【Linux】Linux操作系统对文件系统的管理

在虚拟文件系统的支持下,Linux可以支持迄今为止的大多数文件系统。但是,Linux并不是在初始化时就把所有文件系统全部都装入,而只是安装一个文件系统(通常是Ext2)作为根文件系统。根文件系统在整个系统运行过程中是不能被拆卸的,是系统的基本组成部分。通常,根文件系统上主要安装了保证系统正常工作运行的操作系统代码文件以及若干语言编译程序、命令解释程序和相应的命令处理程序等文件。其他文件系统则都定义成可安装模块,以便用户需要时动态地进行安装。

所谓安装,就是在虚拟文件系统中建立一个超级块super_block,并用被安装文件系统超级块中的相关信息填写super_block,然后用被安装文件系统的根目录代替系统现有目录结构的一个空目录,从而把子系统与原文件系统连接起来。

为使系统在安装之前了解待安装文件子系统的基本信息(例如超级块的位置),必须向系统文件注册表提交一个数据结构进行注册。

把一个文件系统安装到根文件系统的一个节点上的示意图如下所示:

文件系统的注册

由于不同的文件系统具有不同的特点,因此其安装过程也不尽相同。为了正确地安装一个文件系统,被安装的文件系统在安装之前必须向系统进行注册,以便使系统感知和了解待安装文件系统的类型及安装相关的信息。

系统通过调用文件的初始化例程来填写一个叫做file_system_type的数据结构,并调用函数register_filesystem()把该数据结构加入到由系统维护的已注册文件系统的链表中。如下图所示:

数据结构file_system_type的定义如下:

struct file_system_type {
	const char *name;                //文件系统的名称
	int fs_flags;        
	int (*get_sb) (struct file_system_type *, int,
		       const char *, void *, struct vfsmount *);
	void (*kill_sb) (struct super_block *);
	struct module *owner;
	struct file_system_type * next;            //下一个文件系统的指针
	struct list_head fs_supers;

	struct lock_class_key s_lock_key;
	struct lock_class_key s_umount_key;

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

文件系统的安装与卸载

当系统试图安装一个子文件系统时,系统会调用函数mount()首先在文件系统注册链表中查找与用户提供名称相匹配的注册文件系统,如果找到,则在该文件系统的file_system_type中获得与文件系统对应的超级块的指针,并用超级块中的相关信息填写系统分配给该系统的VFS超级块,并把这个超级块加入到VFS超级块链表中。

接下来就要填写一个系统分配给该文件系统的vfsmount数据结构,以保存已被安装的文件系统的基本安装信息,从而把该文件系统的根节点安装到选定的VFS索引节点上。vfsmount结构的定义如下:

struct vfsmount {
	struct list_head mnt_hash;
	struct vfsmount *mnt_parent;	/* 本系统所挂接的父文件系统 */
	struct dentry *mnt_mountpoint;	/* 挂接点的dentry结构 */
	struct dentry *mnt_root;	/* 本系统的根目录 */
	struct super_block *mnt_sb;	/* pointer to superblock */
	struct list_head mnt_mounts;	/* list of children, anchored here */
	struct list_head mnt_child;	/* and going through their mnt_child */
	int mnt_flags;
	/* 4 bytes hole on 64bits arches */
	const char *mnt_devname;	/* 设备名称 e.g. /dev/dsk/hda1 */
	struct list_head mnt_list;
	struct list_head mnt_expire;	/* link in fs-specific expiry list */
	struct list_head mnt_share;	/* circular list of shared mounts */
	struct list_head mnt_slave_list;/* list of slave mounts */
	struct list_head mnt_slave;	/* slave list entry */
	struct vfsmount *mnt_master;	/* slave is on master->mnt_slave_list */
	struct mnt_namespace *mnt_ns;	/* containing namespace */
	int mnt_id;			/* mount identifier */
	int mnt_group_id;		/* peer group identifier */
	/*
	 * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
	 * to let these frequently modified fields in a separate cache line
	 * (so that reads of mnt_flags wont ping-pong on SMP machines)
	 */
	atomic_t mnt_count;
	int mnt_expiry_mark;		/* true if marked for expiry */
	int mnt_pinned;
	int mnt_ghosts;
	/*
	 * This value is not stable unless all of the mnt_writers[] spinlocks
	 * are held, and all mnt_writer[]s on this mount have 0 as their ->count
	 */
	atomic_t __mnt_writers;
};

所有已经被安装的系统都有一个对应的vfsmount数据结构,结构中的指针mnt_mountpoint指向挂接点的目录,而指针mut_root指向被安装系统的根目录,所以结构vfsmount是子系统与父系统之间的桥梁。该数据结构一旦被填写,系统便认为该结构所对应的文件系统已经被安装。

所以,已经被安装的系统的vfsmount数据结构,在系统中也是用一个链表来管理的。

拆卸一个文件子系统的过程基本与安装的过程相反。系统首先验证文件子系统是否为可拆卸的:如果该文件子系统的文件正在被使用,则该系统时不可拆卸的;否则,释放该文件子系统所占用的VFS超级块和安装点,从而卸下该文件子系统。

猜你喜欢

转载自blog.csdn.net/qq_38410730/article/details/81414847