在Linux内核中,一个文件系统包括两部分,一部分是位于磁盘上的管理数据,即文件系统的本体,另一部分是位于内核中的代码,即对VFS中相应接口的实现,没有这部分实现,内核无法识别该文件系统,如此mount、读写等操作也就无从谈起了。
向内核中添加一个文件系统的支持,与其实例无关,即两个分区都是ext4文件系统,但内核对于ext4的支持的代码只需要执行一次,而且,此时也没有从磁盘读取任何数据,这是mount的工作。
本文主要整理内核对各个文件系统的初始化代码
devtmpfs
//devtmpfs __init devtmpfs_init() //drivers/base/devtmpfs.c register_filesystem($dev_fs_type) thread = kthread_run()
sysfs
sysfs_init() //fs/sysfs/mount.c sysfs_root = kernfs_create_root() sysfs_root_kn = sysfs_root->kn; register_filesystem(&sysfs_fs_type);
proc
proc_root_init() //fs/proc/root.c proc_init_inodecache() register_file_system(&proc_fs_type) proc_self_init() proc_thread_self_init() proc_net_init() proc_mkdir("fs) proc_mkdir("driver") proc_mkdir("fs/nfsd") proc_tty_init() proc_mkdir("bus") proc_sys_init()
ext4
__init ext4_init_fs() //fs/ext4/super.c ext4_init_es() ext4_init_pageio() ext4_init_system_zone() kset_create_and_add() proc_mkdir("fs/ext4") init_inodecache() register_filesystem(&ext4_fs_type) //fs/filesystems.c find_filesystem() for (p=&file_systems; *p; p=&(*p)->next)...
bdev
注意到bdev文件系统在初始化时已经挂载
static struct file_system_type bd_type = { .name = "bdev", .mount = bd_mount, .kill_sb = kill_anon_super, }; __init bdev_cache_init() //fs/block_dev.c struct vfsmount * bd_mnt bdev_cachep = kmem_cache_create("bdev_cache") register_filesystem(&bd_type) bd_mnt = kern_mount(&bd_type) kern_mount_data() vfs_kern_mount() mnt = alloc_vfsmnt(name) root = mount_fs(type, flags, name, data); root = type->mount() //bd_mount sb = root->d_sb mnt->mnt = ... list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts); real_mount()->mnt_ns = MNT_NS_INTERNAL blockdev_superblock = bd_mnt->mnt_sb //for writeback