一. 临时文件系统的挂载过程
系统开始时先挂载了一个临时的文件系统,通过这个临时的文件系统
1.在fs/ramfs/inode.c中
1.1全局变量file_systems链表中将参数fs添加进来
1.1.1在全局变量文件系统类型的链表中查找有没有名字等于参数name的文件系统类型
2.在fs/namespace.c中
2.1
在fs/namespace.c中
2.1.1 rootfs的mount过程
在fs/namespace.c中
2.1.2调用具体文件系统的mount
在fs/super.c中
2.1.3在fs/ramfs/inode.c中
2.1.4 在fs/super.c中
2.1.5 分配一个super_block并做初初化
2.1.6 初始化super_block并初始化root
二. 真正的文件系统的挂载过程
系统开始时先挂载了一个临时的文件系统,通过这个临时的文件系统
- init/main.c
- start_kernel
- {
- vfs_caches_init(totalram_pages); ;在fs/dcache.c:创建一个虚拟的文件系统
- --> mnt_init ;在fs/namespace.c中
- --> init_rootfs ;1.在fs/ramfs/inode.c中
- --> init_mount_tree(); ;2.在fs/namespace.c中
- }
- int __init init_rootfs(void)
- {
- bdi_init(&ramfs_backing_dev_info); //初始化ramfs_backing_dev_info结构体
- register_filesystem(&rootfs_fs_type); //1.1注册rootfs_fs_type,
- } 即把rootfs_fs_type添加到全局变量中
-
- static struct backing_dev_info ramfs_backing_dev_info = {
- .name = "ramfs",
- .ra_pages = 0, /* No readahead */
- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK |
- BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
- BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
- };
-
- static struct file_system_type rootfs_fs_type = {
- .name = "rootfs",
- .mount = rootfs_mount,
- .kill_sb = kill_litter_super,
- };
- int register_filesystem(struct file_system_type * fs)
- {
-
- struct file_system_type ** p;
- INIT_LIST_HEAD(&fs->fs_supers);
- write_lock(&file_systems_lock);
- p = find_filesystem(fs->name, strlen(fs->name)); //1.1.1在全局变量file_system中查找
- if (*p) //如果在全局变量中能够找到,*p!=NULL说明这个文件系统己经注册过了
- res = -EBUSY;
- else //如果在全局变量中不能找到,*p==NULL,说明这个文件系统没有注册可以使用
- *p = fs; //使得file_systems.next=fs,链表中增加一项
- write_unlock(&file_systems_lock);
- return res;
- }
- static struct file_system_type **find_filesystem(const char *name, unsigned len)
- {
- struct file_system_type **p;
- for (p=&file_systems; *p; p=&(*p)->next)
- if (strlen((*p)->name) == len && //符合的条件是:名字与长度都相同
- strncmp((*p)->name, name, len) == 0)
- break;
- return p;
- }
- static void __init init_mount_tree(void)
- {
- struct vfsmount *mnt;
- struct mnt_namespace *ns;
- struct path root;
-
- mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); //2.1
- ns = create_mnt_ns(mnt); //为新的文件系统创建namespace
- init_task.nsproxy->mnt_ns = ns;
- get_mnt_ns(ns);
- root.mnt = ns->root;
- root.dentry = ns->root->mnt_root;
- set_fs_pwd(current->fs, &root); //将进程0的当前路径设为rootfs的root
- set_fs_root(current->fs, &root); //将进程0的fs设为rootfs的root
- }
- struct vfsmount * do_kern_mount(const char *fstype, int flags, const char *name, void *data)
- {
- //从全局变量file_systems中找出刚刚注册的"rootfs"的地址
- struct file_system_type *type = get_fs_type(fstype);
- struct vfsmount *mnt;
- if (!type)
- return ERR_PTR(-ENODEV);
- mnt = vfs_kern_mount(type, flags, name, data); //2.1.1
- put_filesystem(type); //空函数
- return mnt;
- }
在fs/namespace.c中
- struct vfsmount * vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
- {
- struct vfsmount *mnt;
- struct dentry *root;
-
- if (!type)
- return ERR_PTR(-ENODEV);
- mnt = alloc_vfsmnt(name); //申请并初始化vfsmount结构体
- //这儿flags==0
- if (flags & MS_KERNMOUNT)
- mnt->mnt_flags = MNT_INTERNAL;
- root = mount_fs(type, flags, name, data); //2.1.2
- mnt->mnt_root = root;
- mnt->mnt_sb = root->d_sb;
- mnt->mnt_mountpoint = mnt->mnt_root;
- mnt->mnt_parent = mnt;
- return mnt;
- }
在fs/super.c中
- struct dentry * mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
- {
- struct dentry *root;
- struct super_block *sb;
- //file_system_type rootfs_fs_type 中定义.mount = rootfs_mount,
- root = type->mount(type, flags, name, data); //调用具体文件系统的mount
- sb = root->d_sb;
- sb->s_flags |= MS_BORN;
- up_write(&sb->s_umount);
- return root;
- }
- static struct dentry *rootfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
- {
- return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
- }
- struct dentry *mount_nodev(struct file_system_type *fs_type, int flags, void *data,
- int (*fill_super)(struct super_block *, void *, int))
- {
- struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); //2.1.5
- s->s_flags = flags;
- error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); //2.1.6调用ramfs_fill_super,初始化super_block和root
- s->s_flags |= MS_ACTIVE;
- return dget(s->s_root); //获取在fill_super中初始化好的root
- }
- struct super_block *sget(struct file_system_type *type,
- int (*test)(struct super_block *,void *),
- int (*set)(struct super_block *,void *),
- void *data)
- {
- struct super_block *s = NULL;
- struct super_block *old;
- int err;
- retry:
- if (!s) {
- s = alloc_super(type); //s是空的就需要分配一个super_block结构体
- if (!s)
- return ERR_PTR(-ENOMEM);
- goto retry;
- }
-
- err = set(s, data);
- s->s_type = type;
- strlcpy(s->s_id, type->name, sizeof(s->s_id));
- list_add_tail(&s->s_list, &super_blocks);
- list_add(&s->s_instances, &type->fs_supers);
- spin_unlock(&sb_lock);
- get_filesystem(type);
- return s;
- }
- int ramfs_fill_super(struct super_block *sb, void *data, int silent)
- {
- struct ramfs_fs_info *fsi;
- struct inode *inode = NULL;
- struct dentry *root;
- int err;
-
- save_mount_options(sb, data);
-
- fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
- sb->s_fs_info = fsi;
-
- err = ramfs_parse_options(data, &fsi->mount_opts);
-
- sb->s_maxbytes = MAX_LFS_FILESIZE;
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
- sb->s_magic = RAMFS_MAGIC;
- sb->s_op = &ramfs_ops;
- sb->s_time_gran = 1;
- //分配inode结构体并初始化inode->i_ino=1
- inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
- //初始化root的dentry结构体
- root = d_alloc_root(inode);
- sb->s_root = root;
- return 0;
- }
二. 真正的文件系统的挂载过程