KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17
System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64
User : nobody ( 99)
PHP Version : 5.2.17
Disable Function : NONE
Directory :  /proc/21573/root/usr/share/systemtap/tapset/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/21573/root/usr/share/systemtap/tapset/dentry.stp
// dentry tapset
// Copyright (c) 2009-2010, 2012 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.
 

function __dentry_IS_ROOT:long(dentry:long)
{
        return (@cast(dentry, "dentry")->d_parent == dentry)
}


function __dentry_prepend:string(dentry:long,name:string)
{
        dname = d_name(dentry)

        /*
         * In case we are following down a mount point trigger, we can get
         * multiple instances of a root mount.
         */
        c = substr(name, strlen(name)-1, strlen(name)-1)
        if (dname == "/" && c == "/")
                return name;

        if (name == "") {
                return dname;
        } else {
                return sprintf("%s/%s", dname, name);
        }
}



/**
 *   sfunction d_name - get the dirent name
 *
 *   Returns the dirent name (path basename).
 *   @dentry: Pointer to dentry.
 */
function d_name:string(dentry:long)
{
        len = @cast(dentry, "dentry")->d_name->len;
        return kernel_string_n(@cast(dentry, "dentry")->d_name->name, len);
}


/**
 *   sfunction inode_name - get the inode name
 * 
 *   Returns the first path basename associated with the given inode.
 *   @inode: Pointer to inode.
 */
function inode_name:string(inode:long)
{
        i_dentry = & @cast(inode, "struct inode")->i_dentry;
        d_alias = @cast(i_dentry, "struct list_head")->next;
        dentry = d_alias - (& @cast(0, "struct dentry")->d_alias);
        return reverse_path_walk(dentry);
}


/**
 *   sfunction reverse_path_walk - get the full dirent path
 *
 *   Returns the path name (partial path to mount point).
 *   @dentry: Pointer to dentry.
 */
function reverse_path_walk:string(dentry:long)
{
        while(1) {
                name = __dentry_prepend(dentry, name);
                dentry = @cast(dentry, "dentry")->d_parent;
                if (__dentry_IS_ROOT(dentry))
                        return name;
        }
}


/**
 *   sfunction real_mount - get the 'struct mount' pointer
 *
 *   Returns the 'struct mount' pointer value for a 'struct vfsmount'
 *   pointer.
 *   @vfsmnt: Pointer to 'struct vfsmount'
 */
function real_mount:long(vfsmnt:long)
{
	if (@defined(@cast(0, "mount")->mnt_parent)) {
		/*
		 * The following is the script language equivalent of:
		 *
		 *    return container_of(vfsmnt, struct mount, mnt);
		 *
		 * We can't do the above because 'struct mount' is
		 * defined in a private header (in fs/mount.h).  But,
		 * we can do the script language equivalent (because
		 * we've got dwarf info).
		 *
		 * More spelled out in C, the above would look like:
		 *
		 *    return (vfsmnt - offsetof(struct mount, mnt));
		 * 
		 * Notice we're casting 0 here on purpose to find the
		 * offset of the 'mnt' member of 'struct mount.
		 */
		offset = &@cast(0, "mount")->mnt
		if (vfsmnt > offset)
			return (vfsmnt - offset)
	}
	return 0
}

/**
 *   sfunction task_dentry_path - get the full dentry path
 *
 *   Returns the full dirent name (full path to the root), like
 *   the kernel d_path function.
 *   @task: task_struct pointer.
 *   @dentry: direntry pointer.
 *   @vfsmnt: vfsmnt pointer.
 */
function task_dentry_path:string(task:long,dentry:long,vfsmnt:long)
{
        root = & @cast(task, "task_struct")->fs->root

        while (1) {
		# If we've found the right dentry/vfsmnt, we're done.
		#
		# (Why check for 'struct path' and 'struct vfs_path'?
		# Later RHEL5 kernels renamed 'struct path' to 'struct
		# vfs_path'.)
		if (@defined(@cast(0, "path")->dentry)
		    ? (dentry == @cast(root, "path")->dentry
		       && vfsmnt == @cast(root, "path")->mnt)
		    : (dentry == @cast(root, "vfs_path")->dentry
		       && vfsmnt == @cast(root, "vfs_path")->mnt))
                        break;

                if (dentry == @cast(vfsmnt, "vfsmount")->mnt_root ||
                    __dentry_IS_ROOT(dentry)) {
			if (! @defined(@cast(0, "vfsmount")->mnt_parent)) {
				mnt = real_mount(vfsmnt)
				if (mnt == 0)
					return "<unknown>"

				/* Global root? */
				if (@cast(mnt, "mount")->mnt_parent == vfsmnt)
					return sprintf("/%s", name);
				dentry = @cast(mnt, "mount")->mnt_mountpoint
				vfsmnt = @cast(mnt, "mount")->mnt_parent
			}
			else {
				/* Global root? */
				if (@cast(vfsmnt, "vfsmount")->mnt_parent
				    == vfsmnt)
					return sprintf("/%s", name);

				dentry = @cast(vfsmnt, "vfsmount")->mnt_mountpoint
				vfsmnt = @cast(vfsmnt, "vfsmount")->mnt_parent
			}
                        continue;
                }
                name = __dentry_prepend(dentry, name);
                dentry = @cast(dentry, "dentry")->d_parent;
        }

        return sprintf("/%s", name);
}



/**
 *   sfunction d_path - get the full nameidata path
 *
 *   Returns the full dirent name (full path to the root), like
 *   the kernel d_path function.
 *   @nd: Pointer to nameidata.
 */
function d_path:string(nd:long)
{
	dentry = (@defined(@cast(nd,"nameidata")->path->dentry)
	    ? @cast(nd,"nameidata")->path->dentry
	    : @cast(nd,"nameidata")->dentry)
	vfsmnt = (@defined(@cast(nd,"nameidata")->path->mnt)
	    ? @cast(nd,"nameidata")->path->mnt
	    : @cast(nd,"nameidata")->mnt)

	return sprintf("%s/", task_dentry_path(task_current(), dentry, vfsmnt))
}


Anon7 - 2021