// vfs tapset // Copyright (C) 2006-2007 IBM Corp. // Copyright (C) 2007 Intel Corporation. // Copyright (C) 2007 Bull S.A.S // Copyright (c) 2008 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. %{ // Needed for struct iovec. #include %} /* generic vfs probes */ /* We don't want to have to do a bdevname() call every time we want a devname, so we'll hash them here. */ /* XXX: Is this hashing really that helpful? The call to bdevname() * isn't very involved... */ global __devnames function __find_bdevname:string(dev:long, bdev:long) { if (dev in __devnames) return __devnames[dev] else return __devnames[dev] = bdevname(bdev) } function ppos_pos:long (ppos:long) %{ /* pure */ loff_t *ppos = (loff_t *)(long)THIS->ppos; THIS->__retvalue = (int64_t) kread(ppos); CATCH_DEREF_FAULT(); %} function __address_inode:long (page:long) { mapping = page? @cast(page, "page", "kernel")->mapping : 0 if (mapping == 0) return -1 else return @cast(mapping, "address_space", "kernel")->host } function __page_ino:long (page:long) { host = __address_inode(page) if (host == -1) return -1 else return @cast(host, "inode", "kernel")->i_ino } function __page_dev:long (page:long) { host = __address_inode(page) if (host == -1) return -1 return @cast(host, "inode", "kernel")->i_sb->s_dev } function __page_bdev:long (page:long) { host = __address_inode(page) if (host == -1) return 0 return @cast(host, "inode", "kernel")->i_sb->s_bdev } function __page_index:long (page:long) { return @cast(page, "page", "kernel")->index } function __file_dev:long (file:long) { d_inode = __file_inode(file) if (d_inode == 0) return 0 return @cast(d_inode, "inode", "kernel")->i_sb->s_dev } function __file_bdev:long (file:long) { d_inode = __file_inode(file) if (d_inode == 0) return 0 return @cast(d_inode, "inode", "kernel")->i_sb->s_bdev } function __file_ino:long (file:long) { d_inode = __file_inode(file) if (d_inode == 0) return 0 return @cast(d_inode, "inode", "kernel")->i_ino } function __file_maxbytes:long (file:long) { d_inode = __file_inode(file) if (d_inode == 0) return 0 return @cast(d_inode, "inode", "kernel")->i_sb->s_maxbytes } function __file_filename:string (file:long) { dentry = file ? (@defined(@cast(file, "file", "kernel")->f_path->dentry) ? @cast(file, "file", "kernel")->f_path->dentry : @cast(file, "file", "kernel")->f_dentry) : 0 name = dentry? @cast(dentry, "dentry", "kernel")->d_name->name : 0 if (name == 0) return "NULL" else return kernel_string(name) } function _get_fopv_size:long (iov:long, nr_segs:long) %{ /* pure */ struct iovec *iovp = (struct iovec *)(long)THIS->iov; if (iovp) { int i; THIS->__retvalue = 0; for (i = 0 ; i < THIS->nr_segs ; i++) THIS->__retvalue += kread(&(iovp[i].iov_len)); } else THIS->__retvalue = -1; CATCH_DEREF_FAULT(); %} function _dev_minor:long (dev:long) %{ /* pure */ THIS->__retvalue = (long)MINOR((dev_t)THIS->dev); %} function _dev_major:long (dev:long) %{ /* pure */ THIS->__retvalue = (long)MAJOR((dev_t)THIS->dev); %} probe generic.fop.llseek = kernel.function ("generic_file_llseek") { dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) file = $file offset = $offset origin = $origin maxbyte = __file_maxbytes($file) name = "generic_file_llseek" argstr = sprintf("%d, %d", offset, origin) } probe generic.fop.llseek.return = kernel.function ("generic_file_llseek").return { name = "generic_file_llseek" name = "generic_file_llseek" retstr = $return file = $file offset = $offset origin = $origin error = $return < 0 ? $return : 0 error_str = error ? errno_str(error) : "" } probe generic.fop.aio_read = kernel.function("__generic_file_aio_read") !, kernel.function("generic_file_aio_read") { file = $iocb->ki_filp dev = __file_dev($iocb->ki_filp) devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp)) ino = __file_ino($iocb->ki_filp) pos = (@defined($pos) ? $pos : ppos_pos($ppos)) buf = $iov->iov_base count = __iov_length($iov,$nr_segs,1,1) /*FIX ME: should be VERIFY_WRITE instead of 1*/ name = "generic_file_aio_read" argstr = sprintf("%d, %d, %p", count, pos,buf) size = count units = "bytes" } probe generic.fop.aio_read.return = kernel.function("__generic_file_aio_read").return !, kernel.function("generic_file_aio_read").return { file = $iocb->ki_filp nr_segs = $nr_segs name = "generic_file_aio_read" retstr = sprintf("%d", $return) bytes_read = $return > 0 ? $return : 0 error = $return < 0 ? $return : 0 error_str = error ? errno_str(error) : "" if ($return > 0) { size = $return units = "bytes" } } probe generic.fop.aio_write = kernel.function ("generic_file_aio_write") { file = $iocb->ki_filp dev = __file_dev($iocb->ki_filp) devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp)) ino = __file_ino($iocb->ki_filp) pos = $pos count = (@defined($iov) ? __iov_length($iov,$nr_segs,1,0) /*FIX ME: should be VERIFY_READ instead of 0*/ : $count) buf = (@defined($iov->iov_base) ? $iov->iov_base : $buf) name = "generic_file_aio_write" argstr = sprintf("%d, %d ,%p", count, pos,buf) size = count units = "bytes" } probe generic.fop.aio_write.return = kernel.function ("generic_file_aio_write").return { file = $iocb->ki_filp name = "generic_file_aio_write" retstr = sprintf("%d", $return) if ($return > 0) { size = $return units = "bytes" } } probe generic.fop.readv = kernel.function ("generic_file_readv") ? { dev = __file_dev($filp) devname = __find_bdevname(dev, __file_bdev($filp)) ino = __file_ino($filp) nr_segs = $nr_segs pos = ppos_pos($ppos) name = "generic_file_readv" argstr = sprintf("%d, %d", nr_segs, pos) size = nr_segs units = "segs" } probe generic.fop.readv.return = kernel.function ("generic_file_readv").return ? { name = "generic_file_readv" retstr = sprintf("%d", $return) if ($return > 0) { size = $return units = "bytes" } } /* calls __generic_file_write_nolock */ probe generic.fop.writev = kernel.function ("generic_file_writev")? { dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) nr_segs = $nr_segs pos = ppos_pos($ppos) name = "generic_file_writev" argstr = sprintf("%d, %d", nr_segs, pos) size = nr_segs units = "segs" } probe generic.fop.writev.return = kernel.function ("generic_file_writev").return ? { file = $file name = "generic_file_writev" retstr = sprintf("%d", $return) bytes_written = $return > 0 ? $return : 0 error = $return < 0 ? $return : 0 error_str = error ? errno_str(error) : "" if ($return > 0) { size = $return units = "bytes" } } /* checks for aops->readpage, if not defined, return -ENOEXEC else assigns generic_file_vm_ops to vma add filemap_nopage, filemap_populate */ probe generic.fop.mmap = kernel.function ("generic_file_mmap") { file = $file dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) vm_start = $vma->vm_start vm_end = $vma->vm_end vm_flags = $vma->vm_flags name = "generic_file_mmap" argstr = sprintf("0x%x, 0x%x, 0x%x", vm_start, vm_end, vm_flags) } probe generic.fop.mmap.return = kernel.function ("generic_file_mmap").return { file = $file name = "generic_file_mmap" retstr = sprintf("%d", $return) error = $return < 0 ? $return : 0 error_str = error ? errno_str(error) : "" } probe generic.fop.open = kernel.function ("generic_file_open") { dev = __file_dev($filp) devname = __find_bdevname(dev, __file_bdev($filp)) ino = $inode->i_ino filename = __file_filename($filp) flag = $filp->f_flags size = $inode->i_size name = "generic_file_open" argstr = sprintf("%d,%d, %s", ino, flag, filename) } probe generic.fop.open.return = kernel.function ("generic_file_open").return { name = "generic_file_open" retstr = sprintf("%d", $return) } probe generic.fop.sendfile = kernel.function ("generic_file_sendfile") ? { dev = __file_dev($in_file) devname = __find_bdevname(dev, __file_bdev($in_file)) ino = __file_ino($in_file) count = $count ppos = $ppos name = "generic_file_sendfile" argstr = sprintf("%d", count) size = count units = "bytes" } probe generic.fop.sendfile.return = kernel.function ("generic_file_sendfile").return ? { name = "generic_file_sendfile" retstr = sprintf("%d", $return) if ($return > 0) { size = $return units = "bytes" } } probe generic.fop.splice_read = kernel.function ("generic_file_splice_read") ? { dev = __file_dev($in) devname = __find_bdevname(dev, __file_bdev($in)) ino = __file_ino($in) file = $in len = $len flags = $flags name = "generic_file_splice_read" argstr = sprintf("%d, %x", len, flags) size = len units = "bytes" } probe generic.fop.splice_read.return = kernel.function ("generic_file_splice_read").return ? { name = "generic_file_splice_read" retstr = sprintf("%d", $return) file = $in ino = __file_ino($in) _dev = __file_dev($in) dev_major = _dev_major(_dev) dev_minor = _dev_minor(_dev) ret = $return error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" if (error) { size = ret units = "bytes" } } probe generic.fop.splice_write = kernel.function ("generic_file_splice_write") ? { dev = __file_dev($out) devname = __find_bdevname(dev, __file_bdev($out)) ino = __file_ino($out) file = $out len = $len flags = $flags name = "generic_file_splice_write" argstr = sprintf("%d, %x", len, flags) size = len units = "bytes" } probe generic.fop.splice_write.return = kernel.function ("generic_file_splice_write").return ? { name = "generic_file_splice_write" retstr = sprintf("%d", $return) file = $out error = $return < 0 ? $return : 0 error_str = error ? errno_str(error) : "" if (error) { size = $return units = "bytes" } } probe generic.fop.read = kernel.function ("generic_file_read") ? { dev = __file_dev($filp) devname = __find_bdevname(dev, __file_bdev($filp)) ino = __file_ino($filp) count = $count name = "generic_file_read" argstr = sprintf("%d", count) size = count units = "bytes" } probe generic.fop.read.return = kernel.function ("generic_file_read").return ? { name = "generic_file_read" retstr = sprintf("%d", $return) if ($return > 0) { size = $return units = "bytes" } } probe generic.fop.write = kernel.function ("generic_file_write") ? { dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) count = $count name = "generic_file_write" argstr = sprintf("%d", count) size = count units = "bytes" } probe generic.fop.write.return = kernel.function ("generic_file_write").return ? { name = "generic_file_write" retstr = sprintf("%d", $return) if ($return > 0) { size = $return units = "bytes" } } /* generic_writepages calls mpage_writepages(mapping, wbc, NULL) */ probe generic.aop.writepages = kernel.function ("mpage_writepages") { dev = $mapping->host->i_sb->s_dev devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev) ino = $mapping->host->i_ino nr_to_write = $wbc->nr_to_write name = "generic_writepages" argstr = sprintf("%d", nr_to_write) size = nr_to_write units = "pages" } probe generic.aop.writepages.return = kernel.function ("mpage_writepages").return { name = "generic_writepages" retstr = sprintf("%d", $return) } probe vfs.do_sync_read = kernel.function ("do_sync_read") { dev = __file_dev($filp) ino = __file_ino($filp) len = $len pos = ppos_pos($ppos) buf = $buf name = "do_sync_read" argstr = sprintf("%d, %d , %p ", len, pos,buf) size = len units = "bytes" bytes_to_read = len } probe vfs.do_sync_read.return = kernel.function ("do_sync_read").return { name = "do_sync_read" retstr = sprintf("%d", $return) bytes_to_read = $len ret = $return bytes_read = ret > 0 ? ret : 0 error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" if ($return > 0) { size = $return units = "bytes" } } probe vfs.do_sync_write = kernel.function ("do_sync_write") { dev = __file_dev($filp) devname = __find_bdevname(dev, __file_bdev($filp)) ino = __file_ino($filp) len = $len pos = ppos_pos($ppos) buf = $buf bytes_to_write = len name = "do_sync_write" argstr = sprintf("%d, %d , %p", len, pos, buf) size = len units = "bytes" } probe vfs.do_sync_write.return = kernel.function ("do_sync_write").return { name = "do_sync_write" retstr = sprintf("%d", $return) bytes_to_write = $len ppos = $ppos ret = $return bytes_written = ret > 0 ? ret : 0 error = $return < 0 ? ret : 0 error_str = error ? errno_str(error) : "" if (error) { size = ret units = "bytes" } } probe vfs.block_sync_page = kernel.function ("block_sync_page") { __page = $page dev = __page_dev(__page) devname = __find_bdevname(dev, __page_bdev(__page)) ino = __page_ino(__page) page_index = __page_index(__page) name = "block_sync_page" argstr = sprintf("%d", page_index) size = 1 units = "pages" } probe vfs.block_sync_page.return = kernel.function ("block_sync_page").return { name = "block_sync_page" retstr = sprintf("N/A") } probe vfs.buffer_migrate_page = kernel.function ("buffer_migrate_page")? { __page = $page dev = __page_dev(__page) ino = __page_ino(__page) devname = __find_bdevname(dev,__page_bdev(__page)) page_index = __page_index(__page) name = "buffer_migrate_page" argstr = sprintf("%d", page_index) size = 1 units = "pages" } probe vfs.buffer_migrate_page.return = kernel.function ("buffer_migrate_page").return? { name = "buffer_migrate_page" retstr = sprintf("%d", $return) if ($return == 0) { size = 1 units = "pages" } } /* default if aop not set, __set_page_dirty_nobuffers usually used if set */ probe vfs.__set_page_dirty_buffers = kernel.function ("__set_page_dirty_buffers") { __page = $page dev = __page_dev(__page) devname = __find_bdevname(dev, __page_bdev(__page)) ino = __page_ino(__page) index = __page_index(__page) name = "__set_page_dirty_buffers" argstr = sprintf("%d", index) size = 1 units = "pages" } probe vfs.__set_page_dirty_buffers.return = kernel.function ("__set_page_dirty_buffers").return { name = "__set_page_dirty_buffers" retstr = sprintf("%d", $return) %( kernel_v >= "2.6.17" %? if ($return == 1) %: if ($return == 0) %) { size = 1 units = "pages" } } probe vfs.do_mpage_readpage = kernel.function ("do_mpage_readpage") { __page = $page dev = __page_dev(__page) devname = __find_bdevname(dev, __page_bdev(__page)) ino = __page_ino(__page) index = __page_index(__page) name = "do_mpage_readpage" argstr = sprintf("%d", index) size = 1 units = "pages" } probe vfs.do_mpage_readpage.return = kernel.function ("do_mpage_readpage").return { name = "do_mpage_readpage" retstr = sprintf("0x%x", $return) size = 1 units = "pages" } probe vfs.add_to_page_cache = kernel.function ("add_to_page_cache_locked") !, kernel.function ("add_to_page_cache") { dev = $mapping->host->i_sb->s_dev devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev) ino = $mapping->host->i_ino index = $offset nrpages = $mapping->nrpages name = "vfs.add_to_page_cache" argstr = sprintf("%d, %d", ino, index) } probe vfs.add_to_page_cache.return = kernel.function ("add_to_page_cache_locked").return !, kernel.function ("add_to_page_cache").return { name = "vfs.add_to_page_cache" retstr = sprintf("%d", $return) if ($return == 0) { size = 1 units = "pages" } } probe vfs.remove_from_page_cache = kernel.function ("__remove_from_page_cache") { __page = $page dev = __page_dev(__page) devname = __find_bdevname(dev, __page_bdev(__page)) ino = __page_ino(__page) index = __page_index(__page) name = "vfs.remove_from_page_cache" argstr = sprintf("%d", ino) } probe vfs.remove_from_page_cache.return = kernel.function ("__remove_from_page_cache").return { name = "vfs.remove_from_page_cache" retstr = sprintf("N/A") } probe vfs.read = kernel.function ("vfs_read") { file = $file pos = $pos buf = $buf bytes_to_read = $count dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) } probe vfs.read.return = kernel.function ("vfs_read").return { file = $file pos = $pos buf = $buf bytes_to_read = $count dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) ret = $return bytes_read = ret > 0 ? ret : 0 error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe vfs.readv = kernel.function ("vfs_readv") { file = $file pos = $pos vec = $vec vlen = $vlen bytes_to_read = _get_fopv_size($vec, $vlen) } probe vfs.readv.return = kernel.function ("vfs_readv").return { file = $file pos = $pos vec = $vec vlen = $vlen bytes_to_read = _get_fopv_size($vec, $vlen) ret = $return bytes_read = ret > 0 ? ret : 0 error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe vfs.write = kernel.function ("vfs_write") { file = $file pos = $pos buf = $buf bytes_to_write = $count dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) } probe vfs.write.return = kernel.function ("vfs_write").return { file = $file pos = $pos buf = $buf bytes_to_write = $count dev = __file_dev($file) devname = __find_bdevname(dev, __file_bdev($file)) ino = __file_ino($file) ret = $return bytes_written = ret > 0 ? ret : 0 error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe vfs.writev = kernel.function("vfs_writev") { file = $file pos = $pos vlen = $vlen vec = $vec bytes_to_write = _get_fopv_size($vec, $vlen) } probe vfs.writev.return = kernel.function ("vfs_writev").return { file = $file pos = $pos vlen = $vlen vec = $vec bytes_to_write = _get_fopv_size($vec, $vlen) ret = $return bytes_written = ret > 0 ? ret : 0 error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe _vfs.generic_file_readonly_mmap = kernel.function("generic_file_readonly_mmap") { file = $file vma = $vma } probe _vfs.generic_file_readonly_mmap.return = kernel.function ("generic_file_readonly_mmap").return { file = $file vma = $vma ret = $return error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe _vfs.generic_block_bmap = kernel.function ("generic_block_bmap") { mapping = $mapping block = $block get_block = $get_block } probe _vfs.generic_commit_write = kernel.function ("generic_commit_write") ? { file = $file page = $page from = $from to = $to } probe _vfs.block_prepare_write = kernel.function ("__block_prepare_write") { _inode = $inode page = $page write_from = $from write_upto = $to } probe _vfs.block_prepare_write.return = kernel.function("__block_prepare_write").return { _inode = $inode page = $page write_from = $from write_upto = $to ret = $return error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe _vfs.block_write_begin = kernel.function ("block_write_begin") ? { file = $file pos = $pos len = $len flags = $flags _inode = __address_inode($mapping) } probe _vfs.block_write_begin.return = kernel.function ("block_write_begin").return ? { file = $file pos = $pos len = $len flags = $flags _inode = __address_inode($mapping) ret = $return error = ret < 0 ? ret : 0 error_str = error ? errno_str(error) : "" } probe _vfs.block_write_end = kernel.function ("block_write_end") ? { file = $file pos = $pos len = $len page = $page _inode = __address_inode($mapping) } probe _vfs.block_write_end.return = kernel.function ("block_write_end").return ? { file = $file pos = $pos len = $len page = $page _inode = __address_inode($mapping) ret = $return }