Ext2文件系统—路径名查找—2--do_lookup简述

        首先我想先承接上一篇博文赘述一下dentry和vfsmount是如何联系起来的。从 __lookup_mnt 中可以看到,可以通过vfsmount中相关dentry结构域找到dentry。而从一个dentry如何找到对应它的vfsmount结构呢?其实这是在最开始的初始化函数 do_path_lookup 中就通过把fs_struct 结构的 root 或 pwd 赋值给nd中的path(nd->path = fs->root;nd->path = fs->pwd),来把最开始的vfsmount 和 dentry联系好的。而在后面的过程中dentry或vfsmount的改变都会通过vfsmount中的dentry域紧密联系。


        接下来讲这章主题。

        之所以称之为简述,是因为这里只讲 do_lookup 的VFS过程,而这个过程比较简单。它包含两个函数:__d_lookup 和 real_lookup 。而所谓的VFS过程其实就是从 dentry 的缓存 dcache 中找到目标dentry。从do_lookup开始就不是沿着路径往上跑,而是“正常”的顺着路径名往下层走。


        __d_lookup 从dcache找dentry的操作很简单,就是通过d_hash哈希函数找到头结点,然后遍历hlisi_head链表,找到父dentry等于parent(传给do_lookup的nd中包含的dentry是当前要找的路径分量父目录的dentry),而且目录名name相同的dentry(主要就是比对目录名字符串)。


        这里所要重点讲的是对于dentry的扩充说明。


        在内核中有个哈希表 dentry_hashtable,是一个list_head指针数组。一旦在内存中建立起一个目录节点的dentry结构,就会根据其节点名的哈希值,通过结构中的d_hash挂入到哈希表的某个队列。所以需要找dentry缓存(dcache)中已建立的dentry,就是根据哈希值从这个哈希表入手。(正因为是哈希表,所以它是个数组)。


        内核中还有一个队列 dentry_unused,注意仅仅是一个队列(上面的哈希表,每一个指针元素后面链的都是一个队列)。凡事已经没有用户,count数为0的dentry结构就通过结构中另一个list_headd_lru挂入这个队列。这是个LRU队列,当需要回收已经不在使用中的dentry结构的空间时,就会从这个队列中找到闲置最久的dentry结构,哈希表的相应那一个队列中脱链并释放。所以,dentry_unused是为缓冲存储而设置的辅助性队列。


       不过在一些特殊的情况下,可能会把一个还在使用中的dentry结构从哈希表中脱链,迫使以后要访问这个节点的进程重新根据磁盘上的内容另行构筑一个dentry结构,而已经脱链的那个结构则由最后调用dput使其共享计数变成0的进程负责将其释放。


        dentry_hashtable哈希表和dentry_unused的结构可参考下图。

Ext2文件系统—路径名查找—2--do_lookup简述_第1张图片


        这里主要就是为了讲dentry_hashtable哈希表和dentry_unused队列的作用和一些特殊情况。另外注意区分d_subdirs、d_child以及d_alias三个队列的意义。具体关于dentrycache的学习可以参考《Linux dentry cache学习

       

你可能感兴趣的:(FS)