- 论坛徽章:
- 0
|
看了各位发言,看了wheelz贴的代码,现在想学内核,就也查了一下源码
文件系统类型放super block里面
如wheelz所说,一般是进程继承的,这在
do_fork()->copy_process()->dup_task_struct()
中可以看到应该是直接memcpy过来的.
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
int cpu = smp_processor_id();
tsk = task_cache[cpu];
task_cache[cpu] = NULL;
if (!tsk) {
tsk = __alloc_task_struct();
if (!tsk)
return NULL;
}
memcpy(tsk, orig, sizeof(*tsk));
atomic_set(&tsk->usage,1);
return tsk;
}
而init进程是在init_mount_tree时候赋值(wheelz告诉我们的)
然后看了init_mount_tree(void)里面调用的do_kern_mount,就是这里拿到sb
在fs/super.c下面
struct vfsmount *
do_kern_mount(const char *fstype, int flags, char *name, void *data)
{
struct file_system_type *type = get_fs_type(fstype);
struct super_block *sb = ERR_PTR(-ENOMEM);
struct vfsmount *mnt;
if (!type)
return ERR_PTR(-ENODEV);
mnt = alloc_vfsmnt(name);
if (!mnt)
goto out;
if (type->fs_flags & FS_REQUIRES_DEV)
sb = get_sb_bdev(type, flags, name, data);
else if (type->fs_flags & FS_SINGLE)
sb = get_sb_single(type, flags, name, data);
else
sb = get_sb_nodev(type, flags, name, data);
if (IS_ERR(sb))
goto out_mnt;
if (type->fs_flags & FS_NOMOUNT)
sb->s_flags |= MS_NOUSER;
mnt->mnt_sb = sb;
mnt->mnt_root = dget(sb->s_root);
mnt->mnt_mountpoint = sb->s_root;
mnt->mnt_parent = mnt;
up_write(&sb->s_umount);
put_filesystem(type);
return mnt;
out_mnt:
free_vfsmnt(mnt);
out:
put_filesystem(type);
return (struct vfsmount *)sb;
}
注意到mnt->mnt_mountpoint = sb->s_root,是否因为这个mount point特殊,所以就用了sb的根目录并不增加其的引用记数呢?
如果是通过sys_chroot等系统调用,也是从vfsmount结构取出.
而这个vfsmount的值是在mount一个设备的时候读他的super_block得到的
看了一下 fs/namespace.c
do_mount()->do_add_mount()
发现也是调用
do_kern_mount()的,所以也就根据设备名取得了sb信息.
但之后会调用attach_mnt()来改变mount_point的信息.也增加了mount point 的dentry结构的引用记数.
static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
{
mnt->mnt_parent = mntget(nd->mnt);
mnt->mnt_mountpoint = dget(nd->dentry);
list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
nd->dentry->d_mounted++;
}
把vfsmount也抄出来
struct vfsmount
{
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
atomic_t mnt_count;
int mnt_flags;
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
};
看了attach_mnt的代码,才知道,原来mnt_child是用于将结构本身链入mnt_parent的mnt_mounts.
我看的代码是linux-2.4.20-31.9, rh9带的.
本人新学入门,看到有各位大侠在讨论. 也来插一把嘴. 还有很多问题不懂. 比如altroot究竟是什么,会在什么系统调用的时候遇到呢. 还请各位大侠指教. |
|