一个文件系统获得了内核的支持,仅仅是功能上的可能性,如果要使用,还需要将其mount到rootfs下,才能可见并进而被使用,本文主要讨论mount的实现过程。
SYSCALL_DEFINE5(mount...) //namespace.c do_mount() user_path() do_remount() do_loopback() do_change_type() do_move_mount() do_new_mount() struct file_system_type *type struct vfs_mount *mnt mnt = vfs_kern_mount() struct mount * mnt mnt = alloc_vfsmnt() root = mount_fs() struct super_block *sb root = type->mount() //回调file_system_type的mount方法 sb = root ->d_sb security_sb_kern_mount() up_write() init mnt list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts) do_add_mount(real_mount(mnt),path,mnt_flags) ext4_mnt() //ext4 mount_bdev(...ext4_fill_super) struct block_device *bdev struct super_block *s bdev = blkdev_get_by_path() s = sget(...test_bdev_super,set_bdev_super...) //find or create a superblock alloc_super() kzalloc() init_waitqueue_head() s->s_bdi = &noop_backing_dev_info ...other initialization of s set() //set_bdev_super() s->s_bdev = data; s->s_dev = s->s_bdev->bd_dev; s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info; bdev->bd_disk->queue; list_add_tail(...&super_blocks) hlist_add_head() get_filesystem() __module_get() sb_set_blocksize() fill_super() //ext4_fill_super() struct ext4_sb_info *sbi sbi = kzalloc() ... init sbi... ext4_msg() setup_timer() sb->s_op = &ext4_sops sb->s_export_op = &ext4_export_ops sb->s_xattr = ext4_xattr_handlers sb->s_root = d_make_root() ext4_setup_super() ext4_ext_init() ext4_mb_init() sbi->s_kobj.kset = ext4_kset init_completion() kobject_init_and_add(&sbi->s_kobj, &ext4_ktype...) s->s_flags|=MS_ACTIVE bdev->bd_super = s dget()
bdev文件系统在其初始化时就已经挂载到内核。
bdev_mount() //bdev mount_pseudo(...&bdev_sops...) sysfs_mount() //sysfs struct dentry* root void * ns ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET); root = kernfs_mount_ns