一. 临时文件系统的挂载过程
系统开始时先挂载了一个临时的文件系统,通过这个临时的文件系统
-
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中
-
}
1.在fs/ramfs/inode.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,
-
};
1.1全局变量file_systems链表中将参数fs添加进来
-
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;
-
}
1.1.1在全局变量文件系统类型的链表中查找有没有名字等于参数name的文件系统类型
-
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;
-
}
2.在fs/namespace.c中
-
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
-
}
2.1在fs/namespace.c中
-
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;
-
}
2.1.1 rootfs的mount过程
在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;
-
}
2.1.2调用具体文件系统的mount
在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;
-
}
2.1.3在fs/ramfs/inode.c中
-
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);
-
}
2.1.4 在fs/super.c中
-
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
-
}
2.1.5 分配一个super_block并做初初化
-
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;
-
}
2.1.6 初始化super_block并初始化root
-
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;
-
}
二. 真正的文件系统的挂载过程
阅读(1650) | 评论(0) | 转发(0) |