文件系统的初始化过程,两个大的过程
1、register_filesystem(structfile_system_type * fs)
2、struct vfsmount *kern_mount(structfile_system_type *type)
register_filesystem:
先看源代码中的注释:
/**
* register_filesystem-register a new filesystem
* @fs:the file system structure
*
* Adds the file system passed to the list of file systems thekernel
* isaware of for mount and other syscalls. Returns 0 on success,
* ora negative errno code on an error.
*
* The&struct file_system_type that is passed is linked into the kernel
* structuresand must not be freed until the file system has been
* unregistered.
*/
这个函数中,将fs注册到大的表file_systems(全局变量)中,为下一步的fs(文件系统)挂载,或者其他系统调用做铺垫(红字部分的注释)
kern_mount:
struct vfsmount *kern_mount(struct file_system_type *type)
{
return vfs_kern_mount(type, 0, type->name, NULL);
}
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
struct vfsmount *mnt;
char *secdata = NULL;
int error;
if (!type)
return ERR_PTR(-ENODEV);
error = -ENOMEM;
mnt = alloc_vfsmnt(name); //初始化mnt各种链表,有name的话附上name
if (!mnt)
goto out;
if (data) {
secdata = alloc_secdata();
if (!secdata)
goto out_mnt;
error = security_sb_copy_data(type, data, secdata);
if (error)
goto out_free_secdata;
}
error = type->get_sb(type, flags, name, data, mnt); //通过回调函数,得到、初始化mnt->sb
if (error < 0)
goto out_free_secdata;
error = security_sb_kern_mount(mnt->mnt_sb, secdata);
if (error)
goto out_sb;
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
up_write(&mnt->mnt_sb->s_umount);
free_secdata(secdata);
return mnt;
out_sb:
dput(mnt->mnt_root);
up_write(&mnt->mnt_sb->s_umount);
deactivate_super(mnt->mnt_sb);
out_free_secdata:
free_secdata(secdata);
out_mnt:
free_vfsmnt(mnt);
out:
return ERR_PTR(error);
}
从上面的代码中我们清理出一条主线:alloc_vfsmnt------->type->get_sb------------->mnt->mnt_mountpoint(之类的善后)
因为最后需要返回structvfsmount的结构体,这也是这个函数最终目的。所以要为这个结构体分配空间,这就需要了alloc_vfsmnt,alloc_vfsmnt的主要目的是分配空间,并对mnt进行一个比较笼统的初始化,这个初始化各个文件系统都一样。
type->get_sb(type, flags, name, data, mnt)这个过程是为mnt获得超级块(super block(或者简称sb))。各个文件系统的超级块有差异,所以都自带get_sb的方法。
例如sysfs的超级块的方法就是
staticint sysfs_get_sb(struct file_system_type *fs_type,
intflags, const char *dev_name, void *data, struct vfsmount *mnt)
{
returnget_sb_single(fs_type, flags, data, sysfs_fill_super, mnt);
}
关于超级块(sb),任何文件系统中,有且只有一个超级块,文件系统中的目录(dentry),节点(inode),均挂载此超级块下。如果将一个文件系统看做一颗树的话,sb就相当于根节点,在同一文件系统中的dentry,inode所指向的sb均指向此sb。
接下来的后续操作中将mnt进行其他的初始化操作,各个文件系统没多少差异。
综上所分析可得:
1、register_filesystem(structfile_system_type * fs)//这个函数的作用是将新建的文件系统,添加到linux系统的文件系统大表里,这样就跟主系统挂钩了
2、struct vfsmount *kern_mount(structfile_system_type *type)//这个函数的作用是为文件系统,获得mnt空间,且对它进行必要的初始化,特别是获得超级块(sb)的过程,各个文件系统,都有自己特有的方法