一种根据dentry获取绝对路径名的实现方法
本方法适用于linux 2.6.x内核。
1. 先获取dentry所属文件系统对应的挂载点,基本原理是遍历文件系统vfsmount树,找到与dentry有相同超级块的vfsmount,实现如下
next_mnt函数实现了先根遍历法,遍历以root为根的文件系统挂载点,p为遍历过程中的当前结点,返回p的下一个挂载点;vfsmnt_lock可通过内核函数kallsyms_on_each_symbol或kallsyms_lookup_name查找获得。
2. 再调用内核函数d_path,接口封装如下
1. 先获取dentry所属文件系统对应的挂载点,基本原理是遍历文件系统vfsmount树,找到与dentry有相同超级块的vfsmount,实现如下
1
extern spinlock_t *vfsmnt_lock;
2![]()
3
static struct vfsmount* next_mnt(struct vfsmount *p, struct vfsmount *root)
4
{
5
struct list_head *next = p->mnt_mounts.next;
6
if (next == &p->mnt_mounts) {
7
while (1) {
8
if (p == root)
9
return NULL;
10
next = p->mnt_child.next;
11
if (next != &p->mnt_parent->mnt_mounts)
12
break;
13
p = p->mnt_parent;
14
}
15
}
16
return list_entry(next, struct vfsmount, mnt_child);
17
}
18![]()
19
static struct vfsmount* get_dentry_mnt(struct dentry *dentry)
20
{
21
struct vfsmount *p, *root;
22
struct fs_struct *fs = current->fs;
23![]()
24
read_lock(&fs->lock);
25
root = fs->root.mnt;
26
mntget(root);
27
read_unlock(&fs->lock);
28![]()
29
spin_lock(vfsmnt_lock);
30
for(p = root; p; p = next_mnt(p,root)){
31
if(p->mnt_sb == dentry->d_sb){
32
mntget(p);
33
break;
34
}
35
}
36
spin_unlock(vfsmnt_lock);
37![]()
38
mntput(root);
39
40
return p;
41
}
extern spinlock_t *vfsmnt_lock;2

3
static struct vfsmount* next_mnt(struct vfsmount *p, struct vfsmount *root)4
{5
struct list_head *next = p->mnt_mounts.next;6
if (next == &p->mnt_mounts) {7
while (1) {8
if (p == root)9
return NULL;10
next = p->mnt_child.next;11
if (next != &p->mnt_parent->mnt_mounts)12
break;13
p = p->mnt_parent;14
}15
}16
return list_entry(next, struct vfsmount, mnt_child);17
}18

19
static struct vfsmount* get_dentry_mnt(struct dentry *dentry)20
{21
struct vfsmount *p, *root;22
struct fs_struct *fs = current->fs; 23

24
read_lock(&fs->lock);25
root = fs->root.mnt;26
mntget(root);27
read_unlock(&fs->lock);28

29
spin_lock(vfsmnt_lock);30
for(p = root; p; p = next_mnt(p,root)){31
if(p->mnt_sb == dentry->d_sb){32
mntget(p);33
break; 34
}35
}36
spin_unlock(vfsmnt_lock);37

38
mntput(root);39
40
return p;41
}2. 再调用内核函数d_path,接口封装如下
1
char* get_dentry_path(struct dentry *dentry,char *buf,int len)
2
{
3
char *p = "";
4
struct vfsmount *mnt = get_dentry_mnt(dentry);
5
6
if(mnt){
7
struct path ph = {.dentry = dentry, .mnt = mnt};
8
p = d_path(&ph,buf,len);
9
if(IS_ERR(p))
10
p = "";
11
mntput(mnt);
12
}
13
14
return p;
15
}
char* get_dentry_path(struct dentry *dentry,char *buf,int len)2
{3
char *p = ""; 4
struct vfsmount *mnt = get_dentry_mnt(dentry);5
6
if(mnt){7
struct path ph = {.dentry = dentry, .mnt = mnt};8
p = d_path(&ph,buf,len);9
if(IS_ERR(p))10
p = "";11
mntput(mnt);12
}13
14
return p;15
}




浙公网安备 33010602011771号