1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
// dentry tapset
// Copyright (c) 2009 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;
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 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 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)
{
root = & @cast(task_current(), "task_struct")->fs->root
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)
while (1) {
if (dentry == @cast(root, "path")->dentry &&
vfsmnt == @cast(root, "path")->mnt)
break;
if (dentry == @cast(vfsmnt, "vfsmount")->mnt_root ||
__dentry_IS_ROOT(dentry)) {
/* 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);
}
|