Chinaunix

标题: fs_struct结构 [打印本页]

作者: stuman    时间: 2013-12-11 19:31
标题: fs_struct结构
struct fs_struct
{
        atomic_t count;
        rwlock_t lock;
        int umask;
        struct dentry *root,*pwd,*altroot;
        struct vfsmount *rootmnt,*pwdmnt,*altrootmnt;
};
请问此结构体中的指针*root与*rootmnt是否指向整个系统的根节点,还是指向当前进程所在文件系统的根节点?
我的理解觉得是第一种情况,但是有书上说是第2种情况,所以只好请教大家了
作者: humjb_1983    时间: 2013-12-12 12:10
stuman 发表于 2013-12-11 19:31
struct fs_struct
{
        atomic_t count;

应该是第2种,至于该root是否为整个文件系统的根,取决于该文件系统是否为根文件系统。
作者: stuman    时间: 2013-12-12 12:28
如果是第二种情况的话,指针*root与*rootmnt就不能配套了,*rootmnt只能指向整个文件系统的根,否则就会和*pwdmnt重复。
是不是这样呢?
作者: humjb_1983    时间: 2013-12-12 17:17
stuman 发表于 2013-12-12 12:28
如果是第二种情况的话,指针*root与*rootmnt就不能配套了,*rootmnt只能指向整个文件系统的根,否则就会和* ...

仔细看了下,这里的root确实应该是根文件系统,也就是说是第一种情况才对~~,确实有点晕,最好实际调试确认下,如有结果,也请告知下~

作者: asuka2001    时间: 2013-12-12 19:25
回复 3# stuman

/mnt/vfsmount1/new_root/mnt/vfsmount2/pwd

进程chroot()到/mnt/vfsmount1/new_root/后:

fs_struct->rootmnt->mnt_root                  /mnt/vfsmount1/
fs_struct->root                                         /mnt/vfsmount1/new_root

fs_struct->pwdmnt->mnt_root                 /mnt/vfsmount1/new_root/mnt/vfsmount2
fs_struct->pwd                                        /mnt/vfsmount1/new_root/mnt/vfsmount2/pwd
作者: humjb_1983    时间: 2013-12-13 08:43
本帖最后由 humjb_1983 于 2013-12-13 08:46 编辑
asuka2001 发表于 2013-12-12 19:25
回复 3# stuman

/mnt/vfsmount1/new_root/mnt/vfsmount2/pwd

如果不chroot结果是怎样的?另外两种情况下的rootmnt和pwdmnt的mnt_mountpoint是什么?
谢谢!
作者: asuka2001    时间: 2013-12-13 09:09
回复 6# humjb_1983

如果不chroot,那么fs_struct与父进程一致。

fs_struct->rootmnt->mnt_root                  /
fs_struct->root                                         /

fs_struct->pwdmnt->mnt_root                 /mnt/vfsmount1/new_root/mnt/vfsmount2
fs_struct->pwd                                        /mnt/vfsmount1/new_root/mnt/vfsmount2/pwd
作者: asuka2001    时间: 2013-12-13 09:18
回复 6# humjb_1983


mnt_mountpoint按照我的理解,是文件系统挂载点。


/mnt/vfsmount1/new_root/mnt/vfsmount2/pwd中:

假设我们只挂载了根文件系统"/",此时对于

/mnt/vfsmount1这个目录,有一个dentry与之对应。我们不妨将其记为dentry_in_"/"

然后我们开始挂载一个文件系统到/mnt/vfsmount1时。mount调用会在dentry_in_"/"中加上标志,然后创建一个struct mount与之对应。

此时挂载的文件系统本身是一个树,它的根的dentry既为mount->vfsmount->mnt_root。这个和dentry_in_"/"不一样。所以mount->mnt_mountpoint == dentry_in_"/"。

内核的路径搜索到/mnt/vfsmount1时,首先查找到dentry_in_"/",然后发现其标记,此时会找到对应的struct mount。然后从mount->vfsmount->mnt_root继续搜索。
作者: asuka2001    时间: 2013-12-13 09:21
本帖最后由 asuka2001 于 2013-12-13 09:22 编辑

回复 6# humjb_1983

总结一下,那么mount->vfsmount->mnt_root是对于挂载的文件系统树自己的根路径。

而mount->mnt_mountpoint是指的我们挂载的文件系统在原有根文件系统树中所处的路径。
   
作者: humjb_1983    时间: 2013-12-13 09:54
asuka2001 发表于 2013-12-13 09:21
回复 6# humjb_1983

总结一下,那么mount->vfsmount->mnt_root是对于挂载的文件系统树自己的根路径。

明白了,感谢~
另外请再确认下,fs_struct->root跟fs_struct->rootmnt->mnt_mountpoint或mnt_root具体有啥关系?
楼主的问题:fs_struct->root是根文件系统的根,还是当前挂载的文件系统的根?fs_struct->rootmnt和pwdmnt的关系?
作者: asuka2001    时间: 2013-12-13 10:35
回复 10# humjb_1983

在进程中,fs_struct->root 决定了路径的检索起点。但是进程的根文件系统类型是什么,由fs_struct->rootmnt来决定。

fs_struct->root可以是fs_struct->rootmnt这个文件系统树的根节点,也同样可以是该文件系统树中的任意一个目录节点。
所以fs_struct->root与fs_struct->rootmnt->mnt_root没有必然联系。

至于文件系统的mnt_root和mnt_mountpoint的区别我想上面已经解释的很清楚了!LZ的问题只要理解了这几者的区别也就不言而喻了。
   
作者: humjb_1983    时间: 2013-12-13 12:44
asuka2001 发表于 2013-12-13 10:35
回复 10# humjb_1983

在进程中,fs_struct->root 决定了路径的检索起点。但是进程的根文件系统类型是什 ...

是否可以这样理解?
1、当未作chroot的时候,fs_struct->root==fs_struct->rootmnt->mnt_root
2、当chroot后,fs_struct->root==chroot设置的root,而fs_struct->rootmnt->mnt_root保持不变
3、fs_struct->root并不一定是/,仅当fs_struct->rootmnt->mnt_mountpoint==/时,fs_struct->root才==/  ?
4、rootmnt和pwdmnt之间是啥关系?还能明示下?
感谢!
作者: asuka2001    时间: 2013-12-13 14:56
本帖最后由 asuka2001 于 2013-12-13 14:58 编辑

回复 12# humjb_1983

1. 虽然 fs_struct->root与 fs_struct->rootmnt->mnt_root没有必然联系,但是一般而言两者相等是常态。我们挂载文件系统时,一般是从根开始将整个文件系统树挂载到进程的名字空间(namespace,虽然大部分时候我们将其与根文件系统含混使用)中的某个节点。

2. 这个是错误的。因为进程的根文件系统所处的文件系统不一定是父进程的根文件系统。

例如父进程的根文件系统是nfs。我们chroot到/mnt/ext4/child_root时。子进程的fs_struct->rootmnt对应的就应该是ext4文件系统,而不是父进程fs_strcut->rootmnt对应的nfs文件系统。

3. 这个是错误的:fs_struct->root一定是代表进程名字空间中"/"所对应的dentry。

只不过子进程的名字空间中"/"可以与父进程名字空间中"/"对应不同的dentry。

4. 当子进程chroot到了/mnt/ext4/child_root时,fs_struct->rootmnt对应的是ext4文件系统。

假设我们此时再挂载ntfs到子进程名字空间中的"/mnt/ntfs" (从父进程的名字空间来看应该是"/mnt/ext4/child_root/mnt/ntfs/")。

进入该目录,此时:子进程的pwdmnt对应的就是ntfs文件系统了。而rootmnt仍然对应的是ext4文件系统。

作者: humjb_1983    时间: 2013-12-13 16:26
asuka2001 发表于 2013-12-13 14:56
回复 12# humjb_1983

1. 虽然 fs_struct->root与 fs_struct->rootmnt->mnt_root没有必然联系,但是一般 ...

感谢指点~~
namespace通常仅用在基于容器的虚拟化场景吧,当所有进程都处于同一个namespace时,情况应该就比较简单了吧。
这种情况下,能否再总结下这几个字段的关系~,呵呵
作者: asuka2001    时间: 2013-12-13 16:37
回复 14# humjb_1983

A filesystem is a hierarchical storage of data adhering to a specific structure.

In Unix, filesystems are mounted at a specific mount point in a global hierarchy known as a namespace.

严格来说:我们经常混用根文件系统这个名词,有得时候指的是挂载到名字空间中"/"的文件系统。有得时候我们用它代指名字空间。它们实际上是有区别的!


   
作者: asuka2001    时间: 2013-12-13 16:47
本帖最后由 asuka2001 于 2013-12-13 16:48 编辑

回复 14# humjb_1983

我所看的内核3.11.5中,fs_struct是这样定义的:

struct path {
        struct vfsmount *mnt;
        struct dentry *dentry;
};
struct fs_struct {
        int users;
        spinlock_t lock;
        seqcount_t seq;
        int umask;
        int in_exec;
        struct path root, pwd;
};


对于名字空间中的节点,path->vfsmount代表了该节点所处的文件系统。如果没有这个信息,假设paht->dentry对应的是目录,继续检索目录下的其他文件内核就只有抓瞎了!除非所有的目录项都在dcache中。

所以在名字空间中,每当经过一个文件系统的挂载点的时候,path->vfsmount都会改变为它所处的实际文件系统。


   
作者: asuka2001    时间: 2013-12-13 16:56
回复 14# humjb_1983

假设init进程开始时通过"root="传参挂载了/dev/sda1为根文件系统,/dev/sda1上的文件系统是ext4。挂载时其挂载点将由mount系统调用创建,记录为ext4_vfsmnt。

那么对于所有的进程,假设它们不再更改自己的名字空间:

fs_struct->root.dentry ==ext4_vfsmnt->mnt_root
fs_struct->mnt == ext4_vfsmnt

而ext4_vfsmnt->mnt_root,则是挂载/dev/sda1时,由ext4 super block创建出来的。
作者: humjb_1983    时间: 2013-12-16 08:46
asuka2001 发表于 2013-12-13 16:56
回复 14# humjb_1983

假设init进程开始时通过"root="传参挂载了/dev/sda1为根文件系统,/dev/sda1上的文 ...

相当的专业~,明白了,感谢指点,以后相关问题再向你请教!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2