文件路径查找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;
}
原文地址:https://www.cnblogs.com/linengier/p/2996394.html