深入浅出文件系统(二)文件系统对象

文件系统对象

深入浅出文件系统(二)文件系统对象_第1张图片

Linux文件系统对象之间的关系可以概括为文件系统类型、超级块、inode、dentry和vfsmount之间的关系。

文件系统类型规定了某种类型文件系统的行为,它存在的主要目的是为了构造这种类型文件系统的实例,或者被称为超级块实例。

超级块反映了文件系统整体的控制信息,超级块以多种方式存在。对于基于磁盘的文件系统,它以特定格式存在于磁盘的固定区域(取决于文件系统类型),为磁盘上的超级块。在文件系统被装载时,其内容被读入内存,构建内存中的超级块。其中某些信息为各种类型的文件系统所共有,被提炼成VFS的超级块结构。如果某些文件系统不具有磁盘上超级块和内存中超级块形式,则它们必须负责从零构造出VFS的超级块。

inode反映了某个文件系统对象的一般元信息,dentry反映了某个文件系统对象在文件系统树中的位置。同超级块一样,inode和dentry也有磁盘上、内存中以及VFS三种形式,其中VFSinode和VFS dentry是被提炼出来,为各种类型文件系统共有的,而磁盘上、内存中inode和dentry则为具体文件系统特有,根据实际情况,也可能根本不需要。

Linux有一棵全局文件系统树,反映了Linux VFS对象之间的关系。文件系统要被用户空间使用,必须先装载到这棵树上。每一次装载被称为一个装载实例,某些文件系统只在内核中使用,也需要这样一个装载实例。每个文件系统装载实例有四个必备元素:vfsmount、超级块、根inode和根dentry。

深入浅出文件系统(二)文件系统对象_第2张图片

 需要强调一下文件系统类型、超级块实例以及装载实例之间的关系。一个文件系统类型可能有多个超级块实例,而每个超级块实例又可以有多个装载实例。

设想分区/dev/sda1和/dev/sda2都被格式化为Minix文件系统类型。当/dev/sda1和/dev/sda2上的文件系统实例先后被装载到系统中时,假设在/mnt/d10和/mnt/d2下,则会有两个超级块实例,分别对应一个装载实例。透过/mnt/d10和/mnt/d2所作的改动(例如创建文件)分别反映到/dev/sda1和/dev/sda2上的文件系统实例中。

然后,/dev/sda1再次被装载到/mnt/d11下,则依然还是两个超级块实例,但是/dev/sda1对应的超级块实例将对应两个装载实例,一个对应在/mnt/d10上的装载,另一个对应在/mnt/d11上的装载。透过/mnt/d10和/mnt/d11所做的改动(例如创建文件)都会被反映到/dev/sda1上的文件系统实例中。

1 file_system_type:文件系统类型

Linux支持多种文件系统,每种文件系统对应一个文件系统类型(file_system_type)结构。是编译到内核,还是作为模块动态装载,文件系统类型需要调用register_filesystem向VFS核心进行注册。如果该文件系统类型不再使用,应该调用unregister_filesystem从VFS核心中注销。上述两个函数都在文件fs/filesystems.c实现。

 file_system_type结构中的域(来自文件include/linux/fs.h)

struct file_system_type {
    const char *name;
    int fs_flags;
#define FS_REQUIRES_DEV     1 
#define FS_BINARY_MOUNTDATA 2
#define FS_HAS_SUBTYPE      4
#define FS_USERNS_MOUNT     8   /* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
#define FS_RENAME_DOES_D_MOVE   32768   /* FS will handle d_move() during rename() internally. */
    struct dentry *(*mount) (struct file_system_type *, int, 
               const char *, void *);
    void (*kill_sb) (struct super_block *);
    struct module *owner;
    struct file_system_type * next;
    struct hlist_head fs_supers;

    struct lock_class_key s_lock_key;
    struct lock_class_key s_umount_key;
    struct lock_class_key s_vfs_rename_key;
    struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];

    struct lock_class_key i_lock_key;
    struct lock_class_key i_mutex_key;
    struct lock_class_key i_mutex_dir_key;
};

文件系统类型注册的主要目的是向Linux VFS提供mount和kill_sb回调函数,分别在Linux装载或卸载这种类型的文件系统实例时被调用。

根据文件系统类型的不同,在Linux内核中可以有一个或多个这种类型的文件系统超级块实例。比如,对于sysfs,只能有一个超级块实例;

文件系统类型将所有超级块实例组成一个链表,链表的表头为fs_supers。超级块对象通过s_instances链接到所属文件系统类型的超级块实例链表中。

比较重要的域是

    struct dentry *(*mount) (struct file_system_type *, int, 
               const char *, void *);

1.mount系统调用流程

2.sys_mount-->file_system_type.mount

//入参:mount -t kingfs /dev/sda /mnt
//dev_name:/dev/sda  dir_name:/mnt    type:kingfs       
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
        char __user *, type, unsigned long, flags, void __user *, data)
{
    ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags,
        (void *) data_page);
}

-->
static int do_new_mount(struct path *path, const char *fstype, int flags,
            int mnt_flags, const char *name, void *data)

-->
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)

-->
struct dentry * 
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
  root = type->mount(type, flags, name, data);
}

 比如mount命令操作:mount -t proc proc  /mnt/

static struct file_system_type proc_fs_type = {
    .name       = "proc",
    .mount      = proc_mount,
    .kill_sb    = proc_kill_sb,
    .fs_flags   = FS_USERNS_MOUNT,
};  

static struct dentry *proc_mount(struct file_system_type *fs_type,
    int flags, const char *dev_name, void *data)
{
    struct super_block *sb;
  //获取超级块sb
    sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns);
    //填充超级块成员域
    err = proc_fill_super(sb);

}

//umount的时候调用
static void proc_kill_sb(struct super_block *sb)


文件系统如何加入到系统。调用register_filesystem向VFS核心进行注册。

int register_filesystem(struct file_system_type * fs)
{       
    struct file_system_type ** p;
    p = find_filesystem(fs->name, strlen(fs->name));   
}

2 super_block:VFS超级块

3 inode:VFS索引节点

4 dentry:VFS目录项

5 vfsmount:文件系统装载

你可能感兴趣的:(存储原理,文件系统)