文件系统如何回到父目录

通过当前path{cur_dentry,cur_ mnt},如何方向遍历到根路径

 

1,  如果当前的path为进程的根目录

cur_dentry == current->fs->root && cur_mnt == current->fs->rootmnt

此时已不能再向上级目录追踪,遍历完毕。

2,  如果当前的path为文件的根目录

cur_dentry == cur_mnt->mnt_root

此时,如果该文件系统没有挂载在其他文件系统之上(cur_mnt == cur_mnt->mnt_root),不能再向上追踪,遍历完毕。

否则,就需要交换文件系统

cur_dentry = cur_mnt->mnt_mountpoint;

cur_mnt  = cur_mnt->mnt_parent;

继续向上遍历

3,  如果为普通目录项,直接回到其父目录的目录项

cur_dentry  = cur_dentry->d_parent;

 

测试模块:

 


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/namei.h>
#include <linux/dcache.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/sched.h>


#define TEST_PATH "/mnt/ext2/home/ydzhang/proc"
#define MAX_ENTRY_LEN 256
#define MAX_ENTRY_DEPTH 10

static int get_path(struct dentry *dentry, struct vfsmount *mnt,
        char *full_path)
{
    struct dentry *tmp_dentry = dentry;
    struct vfsmount *tmp_mnt = mnt;
    char tmp_path[MAX_ENTRY_LEN];
    tmp_path[MAX_ENTRY_LEN-1] = '\0';
        char *path_ptr = tmp_path + MAX_ENTRY_LEN - 1;

        int is_top = 0;
    int only_root = 1;

    while(1)
    {
        //if tmp_dentry is the root of fs

        if(tmp_dentry == current->fs->root
                && tmp_mnt == current->fs->rootmnt)
             {
            is_top = 1; //can't go up

        }
        //if tmp_dentry is the root of fs

        else if(tmp_dentry == tmp_mnt->mnt_root)
        {
            //if it's mounted by

            if(tmp_mnt != tmp_mnt->mnt_parent)
            {
                              tmp_dentry = mnt->mnt_mountpoint;
             tmp_mnt = mnt->mnt_parent;
             only_root = 0;
            }
            else
            {
                is_top = 1; //can't go up

            }
        }
        else
        {
            path_ptr -= strlen(tmp_dentry->d_name.name);
            strncpy(path_ptr, tmp_dentry->d_name.name,
                    strlen(tmp_dentry->d_name.name));

            //add a "/" separator

            path_ptr -= 1;
                        strncpy(path_ptr, "/", 1);

            tmp_dentry = tmp_dentry->d_parent;

            only_root = 0;
        }

        if(only_root) //only a slash

        {
            path_ptr -= 1;
            strncpy(path_ptr, "/", 1);
        }
        if(is_top) //toppest

        {
            break;
        }
    }
    strcpy(full_path, path_ptr);
    return 0;
}

//return negative value will lead to insmod fail

static int dentry_init(vstoid)
{
    struct nameidata namei;
    int err = path_lookup(TEST_PATH, LOOKUP_FOLLOW, &namei);
    if(err)
    {
     printk("path_lookup error\n");
     return 0;
    }

    /* here nd stores the lookup result */

    char *full_path = (char*)kmalloc(MAX_ENTRY_LEN * MAX_ENTRY_DEPTH, GFP_KERNEL);
    get_path(namei.dentry, namei.mnt, full_path);
    printk(KERN_WARNING"full path = %s\n", full_path);
    kfree(full_path);

    return 0;
}

static void dentry_exit(void)
{
    return ;
}

module_init(dentry_init);
module_exit(dentry_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ydzhang");



posted @ 2013-04-19 14:04  ydzhang  阅读(427)  评论(0编辑  收藏  举报