目录项dentry

1540阅读 0评论2015-10-20 bj我心飞翔
分类:LINUX

对于一个通常的文件系统来说,文件和目录一般按树状结构保存。直观来看,目录里保存着文件,而所有目录一层层汇聚,最终到达根目录。从这个树状结构,我们可以想象VFS应该有数据结构反映这种树状的结构。实际上确实如此,目录项(dentry)就是反映了文件系统的这种树状关系。


在VFS里,目录本身也是一个文件,只是有点特殊。每个文件都有一个dentry(可能不止一个),这个dentry链接到上级目录的dentry。根目录有一个dentry结构,而根目录里的文件和目录都链接到这个根dentry,二级目录里的文件和目录,同样通过dentry链接到二级目录。这样一层层链接,就形成了一颗dentry树。从树顶可以遍历整个文件系统的所有目录和文件。


为了加快对dentry的查找,内核使用了hash表来缓存dentry,称为dentry cache。dentry cache在后面的分析中经常用到,因为dentry的查找一般都先在dentry cache里进行查找。


dentry的结构定义同样很庞杂,和超级块类似,我们当前只分析最重要的部分。dentry结构简化后的定义如代码清单所示。

点击(此处)折叠或打开

  1. struct dentry {
  2.     atomic_t d_count;
  3.     unsigned int d_flags;        /* protected by d_lock */
  4.     spinlock_t d_lock;        /* per dentry lock */
  5.     int d_mounted;            /* obsolete, ->d_flags is now used for this */
  6.     struct inode *d_inode;        /* Where the name belongs to - NULL is
  7.                      * negative */
  8.     /*
  9.      * The next three fields are touched by __d_lookup. Place them here
  10.      * so they all fit in a cache line.
  11.      */
  12.     struct hlist_node d_hash;    /* lookup hash list */
  13.     struct dentry *d_parent;    /* parent directory */
  14.     struct qstr d_name;

  15.     struct list_head d_lru;        /* LRU list */
  16.     /*
  17.      * d_child and d_rcu can share memory
  18.      */
  19.     union {
  20.         struct list_head d_child;    /* child of parent list */
  21.          struct rcu_head d_rcu;
  22.     } d_u;
  23.     struct list_head d_subdirs;    /* our children */
  24.     struct list_head d_alias;    /* inode alias list */
  25.     unsigned long d_time;        /* used by d_revalidate */
  26.     const struct dentry_operations *d_op;
  27.     struct super_block *d_sb;    /* The root of the dentry tree */
  28.     void *d_fsdata;            /* fs-specific data */

  29.     unsigned char d_iname[DNAME_INLINE_LEN_MIN];    /* small names */
  30. };
对dentry结构的成员解释如下。


d_inode指向一个inode结构。这个inode和dentry共同描述了一个普通文件或者目录文件。


dentry结构里有d_subdirs成员和d_child成员。d_subdirs是子项(子项可能是目录,也可能是文件)的链表头,所有的子项都要链接到这个链表。d_child是dentry自身的链表头,需要链接到父dentry的d_subdirs成员。当移动文件的时候,需要把一个dentry结构从旧的父dentry的链表上脱离,然后链接到新的父dentry的d_subdirs成员。这样dentry结构之间就构成了一颗目录树


d_parent是指针,指向父dentry结构。


d_hash是链接到dentry cache的hash链表。


d_name成员保存的是文件或者目录的名字。打开一个文件的时候,根据这个成员和用户输入的名字比较来搜寻目标文件。


d_mounted 用来指示dentry是否是一个挂载点。如果是挂载点,该成员不为零。



上一篇:Linux系统用shell命令获取文件或字符串的MD5值
下一篇:linux 内核库函数