1. 程式人生 > >一種根據dentry獲取絕對路徑名的實現方法

一種根據dentry獲取絕對路徑名的實現方法

   本方法適用於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*="";    
 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