- 论坛徽章:
- 17
|
本帖最后由 asuka2001 于 2012-06-26 11:16 编辑
root@ubuntu:/home# find {a,b,c} -type f
a/a
b/b
c/c
root@ubuntu:/home# mount -B b a
root@ubuntu:/home# mount -B c b
root@ubuntu:/home# find {a,b,c} -type f
a/b
b/c
c/c
root@ubuntu:/home# mount -B a c
root@ubuntu:/home# find {a,b,c} -type f
a/b
b/c
c/b
ps: Ubuntu 9.10系统
查看了下内核里的mount系统调用代码,以mount -B b a为例:
1. 查找到dentry a
2. 查找到dentry b
3. 创建vfsmount,然后把vfsmount->mnt_root指向dentry b
4. 将dentry a的d_flags上加上DCACHE_MOUNTED
这样路径查询时,当查找到dentry a时,由于DCACHE_MOUNTED的存在,将直接跳转到对应的vfsmount->mnt_root上,即dentry b
我现在的疑问是第一个红色部分:即a的dentry和b的dentry现在都已经设置了DCACHE_MOUNTED,为什么在路径查询时,只从dentry a跳转到了dentry b上,而没有继续跳转到dentry c上?
即对应以下的代码中的循环为何第一次从dentry a中跳到了对应的vfsmount->mnt_root,即dentry b;而dentry b同样是被mount了,应该继续跳转到dentry c才对!(仅以rcu-walk部分举例,ref-walk部分与之类似)
walk_component() -> do_lookup() -> __follow_mount_rcu()- static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
- struct inode **inode)
- {
- for (;;) {
- struct vfsmount *mounted;
- /*
- * Don't forget we might have a non-mountpoint managed dentry
- * that wants to block transit.
- */
- if (unlikely(managed_dentry_might_block(path->dentry)))
- return false;
- if (!d_mountpoint(path->dentry))
- break;
- mounted = __lookup_mnt(path->mnt, path->dentry, 1);
- if (!mounted)
- break;
- path->mnt = mounted;
- path->dentry = mounted->mnt_root;
- nd->flags |= LOOKUP_JUMPED;
- nd->seq = read_seqcount_begin(&path->dentry->d_seq);
- /*
- * Update the inode too. We don't need to re-check the
- * dentry sequence number here after this d_inode read,
- * because a mount-point is always pinned.
- */
- *inode = path->dentry->d_inode;
- }
- return true;
- }
复制代码 |
|