zoukankan      html  css  js  c++  java
  • 文件路径查找do_path_lookup

    每个进程都有他自己当前的工作目录和它自己的根目录。这是内核用来标识进程与文件系统相互作用做必须维护的数据;每个进程的fs字段指向进程的fs_struct结构;

    struct path {
        struct vfsmount *mnt;
        struct dentry *dentry;
    };
    /include/linux  line6
    struct
    fs_struct { int users;     // 共享这个表的进程个数 rwlock_t lock; //用于表中字段的读写自旋锁 int umask; //打开文件设置文件权限是所使用的位掩码 int in_exec; struct path root, pwd; };

    struct nameidata用于保存与路径名查找操作有关的数据对象;

    struct qstr {
        unsigned int hash;
        unsigned int len;
        const unsigned char *name;
    };
    struct nameidata {
        struct path    path;//目录项对象的地址和已安装文件系统对象的地址
        struct qstr    last;//路径名的最后一个分量
        unsigned int    flags;//查找标志
        int        last_type;//路径名最后一个分量的类型
        unsigned    depth; //符号链接嵌套的当前级别
        char *saved_names[MAX_NESTED_LINKS + 1];//符号链接嵌套的当前级别
         
        /* Intent data */
        union {
            struct open_intent open;//指点如何访问文件
        } intent;
    };

    查找过程

    static int do_path_lookup(int dfd, const char *name,
                    unsigned int flags, struct nameidata *nd)
    {
        int retval = 0;
        int fput_needed;
        struct file *file;
        struct fs_struct *fs = current->fs;
            /*初始化查找结果*/
        nd->last_type = LAST_ROOT; /* if there are only slashes... */
        nd->flags = flags;
        nd->depth = 0;
    
        if (*name=='/') {              //从根目录开始查找
            read_lock(&fs->lock);
            nd->path = fs->root;
            path_get(&fs->root);//增加目录对象和文件系统对象的引用计数
            read_unlock(&fs->lock);
        } else if (dfd == AT_FDCWD) { //从当前目录开始查找
            read_lock(&fs->lock);
            nd->path = fs->pwd;
            path_get(&fs->pwd);
            read_unlock(&fs->lock);
        } else {                             //从其他目录查找
            struct dentry *dentry;
    
            file = fget_light(dfd, &fput_needed);
            retval = -EBADF;
            if (!file)
                goto out_fail;
    
            dentry = file->f_path.dentry;
    
            retval = -ENOTDIR;
            if (!S_ISDIR(dentry->d_inode->i_mode))
                goto fput_fail;
    
            retval = file_permission(file, MAY_EXEC);
            if (retval)
                goto fput_fail;
    
            nd->path = file->f_path;
            path_get(&file->f_path);
    
            fput_light(file, fput_needed);
        }
    
        retval = path_walk(name, nd);
        if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
                    nd->path.dentry->d_inode))
            audit_inode(name, nd->path.dentry);
    out_fail:
        return retval;
    
    fput_fail:
        fput_light(file, fput_needed);
        goto out_fail;
    }
  • 相关阅读:
    生日小助手源码运行的步骤
    关于生日小助手跨平台兼容性的临时解决方案
    生日小助手V3.0——跨平台的农历生日提醒软件
    生日小助手V3.1——跨平台多语言的农历生日提醒软件
    有关生日小助手的内容,请浏览生日小助手官方网站……
    生日小助手的详细规划——本博文随时更新,持续有效
    生日小助手V2.0发布了——可以正式投入使用!
    前端开发入门的几本推荐书籍
    多想一想,JS中函数声明和函数表达式的区别
    table固定宽度大小
  • 原文地址:https://www.cnblogs.com/linengier/p/2996394.html
Copyright © 2011-2022 走看看