⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 036_fs_dcache_c.html

📁 重读linux 2.4.2o所写的笔记
💻 HTML
📖 第 1 页 / 共 3 页
字号:
      void prune_dcache(int count)<BR>
      {<BR>
      &nbsp;&nbsp;&nbsp; spin_lock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; for (;;) {<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; struct dentry *dentry;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; struct list_head *tmp;<BR>
      <BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp =
      dentry_unused.prev;<FONT color=#3333ff> /*遍历unused 链表*/</FONT><BR>
      <BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (tmp == &amp;dentry_unused)<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
      list_del_init(tmp);<FONT color=#3333ff> /*先unshash*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dentry = list_entry(tmp, struct
      dentry, d_lru);<BR>
      <BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* If the dentry was recently
      referenced, don't free it. */<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (dentry-&gt;d_flags &amp;
      DCACHE_REFERENCED) {
      <FONT color=#3333ff>/*如果有lookup命中这个节点就还留用,继续加速查找已经删除的文件*/</FONT><BR>
      &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
      dentry-&gt;d_flags &amp;= ~DCACHE_REFERENCED;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
      list_add(&amp;dentry-&gt;d_lru, &amp;dentry_unused);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count--;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; continue;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dentry_stat.nr_unused--;<BR>
      <BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Unused dentry with a count? */<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
      (atomic_read(&amp;dentry-&gt;d_count)) <FONT color=#3333ff>/*引用计数应当为0,
      印证了猜测.*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BUG();<BR>
      <BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; prune_one_dentry(dentry);
      <FONT color=#3333ff>/*全部的释放... 也有对parent节点的dput,这个函数就不罗列了*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!--count)<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; spin_unlock(&amp;dcache_lock);<BR>
      }<BR>
      <BR>
      prune dcache的过程就是在unused链表中找些东西释放给mm. 剩下的对parent节点的prune和对sb的prune不难理解,
      不再罗列了.倒是select_parent的非递归算法可以看看.(这里就算了)<BR>
      <BR>
      初始化相关的部分,dcache_init,不再分析.<BR>
      到此补充一张dentry的示意图:<BR>
      <DIV id=nuz7 style="PADDING-RIGHT:0pt; PADDING-LEFT:0pt; PADDING-BOTTOM:1em; PADDING-TOP:1em; TEXT-ALIGN:left">
        <IMG src=036_fs_dcache_c_images/dcbsxfpf_20vcx5trcf.gif style="WIDTH:632px; HEIGHT:528px">
      </DIV>
      <BR>
      <BR>
      顺便看看如何加入hash表吧:<BR>
      static __inline__ void <FONT color=#3333ff><B>d_add</B></FONT>(struct
      dentry * entry, struct inode * inode)<BR>
      {<BR>
      &nbsp;&nbsp;&nbsp; d_instantiate(entry, inode);
      <FONT color=#3333ff>/*建立entry-&gt;d_alias,
      inode-&gt;i_dentry关系*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; d_rehash(entry);
      /<FONT color=#3333ff>*加入hash表*/</FONT><BR>
      }<BR>
      简单搜索可知这种 make postive的工作都交给了具体的文件系统去做了,如 ext2_lookup.
      d_delete试图只是将删除的文件的inode和dentry的关系脱离,这里复习?一下.<BR>
      <BR>
      <BR>
      说了这么多看dget_locked就知道为什么了:<BR>
      /* This should be called _only_ with dcache_lock held */<BR>
      <BR>
      static inline struct dentry *
      <FONT color=#009900><B>__dget_locked</B></FONT>(struct dentry *dentry)<BR>
      {<BR>
      &nbsp;&nbsp;&nbsp; atomic_inc(&amp;dentry-&gt;d_count);<BR>
      &nbsp;&nbsp;&nbsp; if (atomic_read(&amp;dentry-&gt;d_count) == 1) {
      <FONT color=#3333ff>/*我们inc后等于1, 代表他在lru队列,即unused队列*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dentry_stat.nr_unused--;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; list_del(&amp;dentry-&gt;d_lru);
      <FONT color=#3333ff>/*暂时吧他从lru搞出来,dpu又会回到这里来*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
      INIT_LIST_HEAD(&amp;dentry-&gt;d_lru);&nbsp;&nbsp;&nbsp;
      &nbsp;&nbsp;&nbsp; /* make "list_empty()" work */<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; return dentry;<BR>
      }<BR>
      struct dentry * dget_locked(struct dentry *dentry)<BR>
      {<BR>
      &nbsp;&nbsp;&nbsp; return __dget_locked(dentry);<BR>
      }<BR>
      最后,反而d_lookup比较清新宜人,没啥令人难懂的操作.<BR>
      struct dentry * <FONT color=#009900><B>d_lookup</B></FONT>(struct dentry *
      parent, struct qstr * name)<BR>
      <BR>
      每次查完dcache,都要检查是不是要做revalidate操作,逻辑是:如果需要做,
      组成了就好,做不成就释放invalidate这个dentry(unhash<BR>
      然后 prune掉所有子目录):<BR>
      if (dentry &amp;&amp; dentry-&gt;d_op &amp;&amp;
      dentry-&gt;d_op-&gt;d_revalidate) {<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if
      (!dentry-&gt;d_op-&gt;d_revalidate(dentry, flags) &amp;&amp;
      !d_invalidate(dentry)) {<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dput(dentry);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dentry = NULL;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      比较典型的例子可能是NFS了,但是过于复杂了些. 看看<B>pid_base_revalidate</B>也就够了.<BR>
      <FONT color=#3366ff>/**<BR>
      &nbsp;* d_invalidate - invalidate a dentry<BR>
      &nbsp;* @dentry: dentry to invalidate<BR>
      &nbsp;*<BR>
      &nbsp;* Try to invalidate the dentry if it turns out to be<BR>
      &nbsp;* possible. If there are other dentries that can be<BR>
      &nbsp;* reached through this one we can't delete it and we<BR>
      &nbsp;* return -EBUSY. On success we return 0.<BR>
      &nbsp;*<BR>
      &nbsp;* no dcache lock.<BR>
      &nbsp;*/<BR>
      &nbsp;</FONT><BR>
      int d_invalidate(struct dentry * dentry) /*invalidate, 使其彻底的失效*/<BR>
      {<BR>
      &nbsp;&nbsp;&nbsp; /*<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* If it's already been dropped, return OK.<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;*/<BR>
      &nbsp;&nbsp;&nbsp; spin_lock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; if (list_empty(&amp;dentry-&gt;d_hash))
      {<FONT color=#3366ff> /*已经无效了*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; spin_unlock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; /*<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* Check whether to do a partial shrink_dcache<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* to get rid of unused child entries.<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;*/<BR>
      &nbsp;&nbsp;&nbsp; if (!list_empty(&amp;dentry-&gt;d_subdirs)) {
      <FONT color=#3333ff>/*清除所有子目录,树*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; spin_unlock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; shrink_dcache_parent(dentry);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; spin_lock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      <BR>
      &nbsp;&nbsp;&nbsp; /*<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* Somebody else still using it?<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;*<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* If it's a directory, we can't drop it<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* for fear of somebody re-populating it<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* with children (even though dropping it<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* would make it unreachable from the root,<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* we might still populate it if it was a<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;* working directory or similar).<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;*/<BR>
      &nbsp;&nbsp;&nbsp; if (atomic_read(&amp;dentry-&gt;d_count) &gt; 1) {<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (dentry-&gt;d_inode &amp;&amp;
      S_ISDIR(dentry-&gt;d_inode-&gt;i_mode)) {<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
      spin_unlock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<BR>
      &nbsp;&nbsp;&nbsp; }<BR>
      <BR>
      &nbsp;&nbsp;&nbsp;
      list_del_init(&amp;dentry-&gt;d_hash);<FONT color=#3333ff>
      /*这个操作就是使其无效的操作,,,,随后的dput会将其放入lru(如果ref==1)*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; spin_unlock(&amp;dcache_lock);<BR>
      &nbsp;&nbsp;&nbsp; return 0;<BR>
      }<BR>
      <BR>
      <BR>
      而 int d_validate(struct dentry *dentry, struct dentry
      *dparent,)并不是d_invalid的对应者, 这个函数左看右看是验证一个没有引用的的指针是否有效....., ncp, smb使用,
      估计做这两个文件系统的人才知道这个鬼东西到底是啥玩意.<BR>
      <BR>
      <BR>
      struct dentry * d_find_alias(struct inode *inode)
      :<FONT color=#ff0000>只有VFAT使用(2.4), 看来VFAT不支持dentry的alias(不能在其一个目录下安装多个设备?
      还是另有隐情..... 待解问题....</FONT><BR>
      void d_prune_aliases(struct inode *inode) 太具体了,这两个函数<BR>
      <BR>
      <BR>
      <BR>
      int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)<BR>
      void <B>d_move</B>(struct dentry * dentry, struct dentry * target)
      :虽然vfs_rename很复杂的,这里倒是尽是些力气活.<BR>
      char * <B>__d_path</B>(struct dentry *dentry, struct vfsmount *vfsmnt,
      <FONT color=#3333ff>/*从一个dentry需找其父节点的时候,要知道<BR>
      mnt才能在这其中做出选择, 从follow_dot_dot我们能学到这个概念, 倒是再细细品味吧*/</FONT><BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; struct dentry *root, struct vfsmount
      *rootmnt,<BR>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char *buffer, int buflen)<BR>
      asmlinkage long <B>sys_getcwd</B>(char *buf, unsigned long size)
      刚好是__d_path的一个应用.<BR>
      void d_genocide(struct dentry *root) : 非递归遍历树,呵呵...<BR>
      int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry) :呵呵<BR>
      ino_t find_inode_number(struct dentry *dir, struct qstr *name)<B><BR>
      </B>int have_submounts(struct dentry *parent) :有任何子目录是安装点就返回真,树的遍历...<BR>
      <BR>
      这里最后给出一个图,表明dentry 和mnt 所组成的一幅全景图,并且还是一个dentry下面安装多个文件系统的例子:体会下<BR>
      上面的这句话:<BR>
      <FONT color=#3333ff>/*从一个dentry需找其父节点的时候,要知道mnt才能在这其中做出选择,
      从follow_dot_dot我们能学到这个。。。*/<BR>
      <DIV id=fcni style="PADDING-RIGHT:0pt; PADDING-LEFT:0pt; PADDING-BOTTOM:1em; PADDING-TOP:1em; TEXT-ALIGN:left">
        <IMG src=036_fs_dcache_c_images/dcbsxfpf_25gzfbcmd9.jpg style="WIDTH:436px; HEIGHT:635px">
      </DIV>
      <BR>
      </FONT><B><BR>
      </B><BR>
    </TD>
  </TR>
  <TR>
    <TD vAlign=top>
      <BR>
    </TD>
  </TR>
  <TR>
    <TD vAlign=top>
      <BR>
    </TD>
  </TR>
  <TR>
    <TD vAlign=top>
      <BR>
    </TD>
  </TR>
  </TBODY>
</TABLE></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -