文件系统中的目录查找

      Linux中的一个进程在识别一个文件的时候,将文件名传递给VFS层,VFS要根据文件名查找这个文件的索引节点inode,以备后续对该文件的操作。通过文件名查找文件索引节点的过程就叫做路径查找(path lookup)。本文是在阅读目录查找代码时随手记录的笔记,会在不断的学习中不断补充。

      路径查找的起始阶段,内核会从某一个特定的dentry开始查起,如果路径名是以‘/’开始,则起始的dentry是current->fs->root;否则,起始的dentry是current->fs->cwd。root和cwd在struct fs_struct中是一个<dentry, vfsmount>对,dentry表示目录对象,vfsmount表示一个文件系统对象。

      路径查找开始后,内核从第一个dentry开始,找到它对应的索引节点;然后从磁盘读出包含那个索引节点的目录文件,获得索引节点。。。,反复执行上述操作,直到找到最后的文件。在上面的查找过程中,必须要考虑以下几点:

1,对获取到的inode的权限做审计和验证

2,因为查找目录对应的目录项对象是一个非常频繁且消耗IO的操作,内核在内存中维护了一个目录项高速缓存directory-entry cache,也叫dcache来加速查找目录项的过程。需要注意的是,从2.6版本起,dcache的通过RCU来减少锁竞争的开销,具体见这里http://www.linuxjournal.com/article/7124

3,当路径中遇到非本文件系统的挂载点时,需要扩展到该挂载点对应的文件系统来做目录查找

4,当路径中遇到符号链接时,也要做相应的处理

5,如果系统调用时一个create文件的操作,在查找的同时需要逐步创建各级目录

 

下面是具体实现的一些摘要

      路径查找大代码绝大多数实现在fs/dcache.c fs/namei.c中,目录项对象struct dentry定义在include/linux/dcache.h中,其他一些与目录查找相关的结构体定义在include/linux/namei.h中。

路径名查找是由path_lookup函数执行的,它的调用方式如下:
int path_lookup(const char *name, unsigned int flags, struct nameidata *nd);
name是要解析的文件路径名,flags是一些标志,nd查找成功后的返回结果
struct nameidata {
        struct path     path;   // 结构体path中是目录项对象的地址和文件系统对象的地址
        struct qstr     last;     // 路径名的最后一个分量
        struct path     root;
        struct file     *file;
        struct inode    *inode; /* path.dentry.d_inode */
        unsigned int    flags;
        unsigned        seq;
        int             last_type;
        unsigned        depth;    // 符号链接嵌套的当前级别
        char *saved_names[MAX_NESTED_LINKS + 1];  // 与符号链接关联的路径数组
 
        /* Intent data */
        union {
                struct open_intent open;
        } intent;
};
 

参考文献:

1,linux2.6源代码

2,linux document: ./Document/filesystem/path_lookup.txt

posted @ 2015-10-18 01:06  CobbLiu  阅读(2505)  评论(0编辑  收藏  举报