一種根據dentry獲取絕對路徑名的實現方法
阿新 • • 發佈:2018-12-22
本方法適用於linux 2.6.x核心。
1. 先獲取dentry所屬檔案系統對應的掛載點,基本原理是遍歷檔案系統vfsmount樹,找到與dentry有相同超級塊的vfsmount,實現如下 1extern spinlock_t *vfsmnt_lock;
2
3staticstruct 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
19staticstruct 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} next_mnt函式實現了先根遍歷法,遍歷以root為根的檔案系統掛載點,p為遍歷過程中的當前結點,返回p的下一個掛載點;vfsmnt_lock可通過核心函式kallsyms_on_each_symbol或kallsyms_lookup_name查詢獲得。
2. 再呼叫核心函式d_path,介面封裝如下
1char*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} posted on 2016-08-24 19:22 春秋十二月 閱讀(3342) 評論(0) 編輯 收藏 引用 所屬分類: System
1. 先獲取dentry所屬檔案系統對應的掛載點,基本原理是遍歷檔案系統vfsmount樹,找到與dentry有相同超級塊的vfsmount,實現如下 1extern spinlock_t *vfsmnt_lock;
2
3staticstruct 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,
17}18
19staticstruct 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(
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} next_mnt函式實現了先根遍歷法,遍歷以root為根的檔案系統掛載點,p為遍歷過程中的當前結點,返回p的下一個掛載點;vfsmnt_lock可通過核心函式kallsyms_on_each_symbol或kallsyms_lookup_name查詢獲得。
2. 再呼叫核心函式d_path,介面封裝如下
1char*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} posted on 2016-08-24 19:22 春秋十二月 閱讀(3342) 評論(0) 編輯 收藏 引用 所屬分類: System