Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3550194
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类: LINUX

2013-10-22 13:57:16

原文地址:对dentry的理解 作者:Mars007

1.dentry与inode是多对一的(硬链接的情况),可以通过inode->i_dentry找到指向inode的所有dentry.

2.sys_open() 打开一个文件,如果文件不存在,dentry仍然会被创建且被加入到dcache中,但是dentry指向的inode为空(此时dentry为负状 态),path_walk()完毕后,dentry被加入到super_block的LRU链表中,等待销毁.

3.dentry有自己所属的文件系统,因此dentry建立的树状层次结构只在dentry所属的文件系统中生效.

4. 引用计数为0的dentry仍然会保留在dcache中,但是同时也会被加入到super_block的LRU未使用链表中,当需要释放内存时,压缩 dentry的slab回调函数shrink_dcache_memory()被调用,将LRU链表中最久未被使用的dentry从dentry缓存中删 除后,释放给slab分配器.

5.dentry被创建时其父dentry必然存在,且会增加父dentry的引用计数,dentry被销毁 时会减少其父dentry的引用计数,如果其父dentry的引用计数被递减后变为0,那么其父dentry会被销毁,依次向上,直到文件系统的root dentry.

Q:文件系统中有一个文件foo,假设文件系统同时挂载到/mnt1/和/mnt2/,那么/mnt1/foo和/mnt2/foo对应的dentry是同一个dentry吗?
A:是的,一个块设备可以被挂载到多处,每次挂载都会创建vfsmount,但是VFS的super_block只有一个,dentry是属于文件系统的 而不是属于某个挂载点,唯一代表文件系统的是VFS的super_block,因此,dentry结构体中有到super_block的指针,但是没有到 vfsmount的指针,/mnt1/foo和/mnt2/foo是同一个文件系统下的同一个文件,他们对应的dentry也必然是相同的,理解了 dentry是属于文件系统的,就很容易理解为什么struct path的成员只有vfsmount和dentry了.

Q:得到dentry后,可以沿着dentry->d_parent往上一直到系统的根目录吗?
A:如果dentry是属于根文件系统的,则可以.否则,如果dentry属于新挂载的文件系统,则不能,因为通过dentry是无法得知文件系统的挂载 点的(如果文件系统只挂载了一次,通过dentry拿到文件系统的根dentry,找到vfsmount,获得挂载点也是一种办法).

Q:引用计数为0的dentry会同时存在于super_block的未使用链表和dcache中,当通过do_lookup()函数从dcache中找到dentry时只是增加dentry的引用计数,为什么不把它从super_block的链表中删除?
A:dentry的LRU实现使用了lazy LRU,因为dentry的使用时间可能非常短(如stat一个文件),如果从dcahce中找到后,立即将dentry从LRU中移除,使用完毕后,马 上又要插入到LRU链表中,增加了链表操作的开销,由于LRU链表是受全局dcache_lock保护的,加剧对dcache_lock的争用.但是,这 样一来又有一个问题,dentry的引用计数从0->1,到1->0的过程中,dentry在LRU链表中的位置没有变化,且dput() 时,dentry已经在LRU链表中,DCACHE_REFERENCED标志不会置位,shrink_dcache_memory()被调用时,可能被 当作最久未使用dentry给释放掉,但是实际情况是,dentry刚刚才被使用,super_block的LRU链表明显没有达到效果?哥们的这个疑问 还真是一个问题,这个问题已由Nick Piggin在这个中解决.
Q: 调用unlink()删除文件时,经过sys_unlink()->do_unlinkat()->vfs_unlink()进入到 d_delete(),如果dentry还被其他进程使用(dentry->d_count>1),为什么d_delete()需要将 dentry从dcache中移除?
A:如果dentry被其他进程引用,在d_delete()中还不能将dentry转化为负状态,但是必须 将dentry(记为dentry1,dentry1对应的inode记为inode1)从dcache中移除,否则,后续在同一个目录下创建相同文件名 的文件时会从dcache中找到dentry1,导致引用inode1,出现新创建的文件就有数据的情况.


阅读(730) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~