免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2576 | 回复: 4
打印 上一主题 下一主题

请教关于将dentry从dcache中删除的问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-14 21:59 |只看该作者 |倒序浏览
sys_unlink()里有一事不明,盼指点,谢谢了先:
sys_unlink() ==> do_unlinkat(),do_unlinkat()流程大体为:
1) dentry = lookup_hash(&nd); //在lookup_hash()中会将dentry的引用计数递增
2) atomic_inc(&dentry->inode->i_count); //将inode的引用计数递增
3) vfs_unlink(&dentry->inode, dentry); //调用d_delete(),对inode的i_nlink进行处理
4) dput(dentry);
5) iput(inode);

我的问题是,在第3步的vfs_unlink() ==> d_delete()中,为什么在dentry的引用计数等于1的情况下,不对dentry进行额外处理,由第4步dput()将其转换成 negative状态,加到dentry_unused这个LRU链表;而在dentry的引用计数大于1的情况下,却调用__d_drop()把 dentry从dcache中删除,当最后一个file放弃该dentry后(引用计数为1时),在它调用的dput()中,因为dentry已经从 dcache中删除,所以释放这个dentry结构?

或者换个问题,引入negative状态是为了虽然dentry相应的磁盘节点已经被删除,但将dentry仍保持在dcache中,以方便后续对同一文件名的查找能够快速完成,那么为什么在上面dentry的引用计数大于1的情况下,不也将其保存在dcache中,以方便后续对同一文件名的查找呢?

论坛徽章:
0
2 [报告]
发表于 2008-12-14 22:03 |只看该作者
也就是d_delete()函数的注释中:
/*
* When a file is deleted, we have two options:
* - turn this dentry into a negative dentry
* - unhash this dentry and free it.
*
* Usually, we want to just turn this into
* a negative dentry, but if anybody else is
* currently using the dentry or the inode
* we can't do that and we fall back on removing
* it from the hash queues and waiting for
* it to be deleted later when it has no users
*/

这里面的we can't do that,为什么"we can't do that"?

论坛徽章:
0
3 [报告]
发表于 2008-12-15 08:53 |只看该作者

回复 #1 fishswimming 的帖子

注释说明 关注一下

论坛徽章:
0
4 [报告]
发表于 2008-12-15 20:18 |只看该作者
原帖由 kns1024wh 于 2008-12-15 08:53 发表
注释说明 关注一下

注释说明的意思是?

论坛徽章:
0
5 [报告]
发表于 2008-12-15 21:56 |只看该作者
我想我找到原因了,在删除文件所调用的d_delete()这个函数里面,分两种情况:
1. 当dentry的引用计数为1时,将dentry加入到dentry_unused链表,转为negative状态,并调用dentry_iput()。 dentry_iput()负责将dentry和它的inode脱钩,调用iput()处理inode,及将dentry->d_inode设为 NULL。
    虽然dentry仍保留在了dentry_hashtable哈希表中,但这样却能保证别的进程无法访问这个dentry,这是因为在进程打开文件所调用的open() ==> sys_open() ==> do_sys_open() ==> do_filp_open ==> open_namei() ==> path_lookup() ==> do_path_lookup() ==> link_path_walk() ==> __link_path_walk()里,对路径中的每一个部分,都是大体上这样处理:
do_lookup(nd, &this, &next);
if(NULL == next.dentry->d_inode)
{
    err = -ENOENT;
    return err;
}
这样就保证了虽然dentry还在dentry_hashtable哈希表中,但因为dentry->d_inode为NULL,所以无法访问。

2. 再到d_delete()中dentry的引用计数大于1的情况时,因为别的进程仍在使用dentry,所以此时不能对dentry进行处理,更不能将 dentry的->d_inode设为NULL。如果仍然把它留在dentry_hashtable中,那么另外的进程就可以找到这个 dentry,所以要把他从dentry_hashtable中删除。这样当另外的进程要查找dentry时,是无法从dentry_hashtable 中找到,只能调用dir->i_op->lookup,如ext2_lookup()来从磁盘中读出相应信息来新组装一个dentry,但 vfs_unlink()函数在调用d_delete()前,已经调用了dir->i_op->unlink,如ext2_unlink() 来将要删除的节点从其父目录的磁盘信息中删除,所以走这条路也是找不到该节点的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP