一、介绍
1、支持多种不同类型的文件系统共是Linux操作系统的一大特色。
目前支持的文件系统有ext、ext2、minix、umsdos、ncp、iso9660、hpfs、ntfs、msdos、xia、proc、romfs、nfs、smbfs、sysv、affs、efs、coda、hfs、adfs、qnx4、bfs、udf以及ufs等。以后还会支持更多的文件系统。这个系统的实现带来一定的麻烦。因为每一种文件系统都有自己的组织结构和文件操作桉树,相互之间差别很大。Linux对上述文件系统的支持是通过虚拟文件系统VFS的引入实现的。
2、VFS只存在于内存中。
它在系统启动时产生,在系统关闭时注销。VFS的作用就是屏蔽各类文件系统的差异,给用户、应用程序,甚至Linux其他管理模块提供一个统一的界面。管理VFS数据结构的组成部分主要保护超级快和inode。
3、文件操作面向外存空间。
怎么解决外存与内存在IO速度上的差异,从而提高系统效率,是Linux文件系统管理面临的重点问题。Linux的办法是采用缓冲技术和hash表,主要有inode缓存、directory缓存、buffer缓存和打开文件表first_file。
4、在众多可使用的文件系统类型中,EXT2是linux自行设计并具有较高效率的一种文件系统类型。EXT2建立在超级块、块组、inode、目录项等结构的基础上,并在内存映射及在数据块申请/释放策略上做了考虑。
二、文件管理系统
1、register/unregister操作
一个已安装的Linux操作系统究竟支持几种文件系统类型?这需要文件系统类型的注册链表描述。文件系统类型注册表如下:
file_systems-next ->> file_system_type-next ->> file_system_type-next=0
向系统核心注册文件系统的类型有两种途径。一种是在编译核心系统时确定,并在系统初始化时通过内嵌的函数调用想注册表登记。另一种则利用Linux额模块特征,把某个文件系统当作一个模块。装入该模块时(通过kerneled或用insmod、modprob命令)向注册表登记它的类型,卸载该模块时则从注册表注销。文件系统类型的注册和注销函数为:
int register_filesystem (struct file_system_type * s )
int unregister_filesystem(struct file_system_type * s )
文件系统类型的注册和注销反映在以file_systems(fs/super.c)为链头、file_system_type为节点的单向链表中。注册表的每一个file_system_type节点描述一个已注册的文件系统类型。
1)file_system_type类型{ }
const char * name ;
int fs_flags;
struct super_block * (* read_super ) (struct super_block * , void * ,int) ; // 所指向函数用于该文件系统在外存的超级快
struct module * owner ; // 如果该文件系统的程序段是由module动态载入,则指向该module;如果实现该文件系统的程序段是在内核编译时生成的,则owner = NULL ;
struct vfsmout * kern_mnt ;
struct file_system_type * next ;
- 文件的注册函数在文件系统模块被载入时调用,在模块卸载的时候调用注销函数。如EXT2文件系统:
static int_init init_ext2_fs(void)
{
return register_filesystem(&ext2_fs_type);
}
static void_exit exit_ext2_fs(void)
{
unregister_filesystem(&ext2_fs_type);
}
- register_filesystem函数
int register_filesystem(struct file_system_type * fs )
{
int res = 0 ;
struct file_system_type * * p ;
if( !fs )
return -EINVAL ;
if( fs-> next )
return -EBUSY ;
write_lock( &file_systems_lock );
p = find_filesystem( fs->name );
if( * p )
res = - EBUSY ;
else
* p = fs ;
write_unlock( &file_system_lock );
return res ;
}
static struct file_system_type ** find_file_sysem( const char * name )
{
struct file_system_type ** p ;
for(p=&file_systems ; *p ; p =&(*p) -> next )
if ( strcmp( (*p)->name, name ) == 0 )
break ;
return p ;
}
三、文件系统操作
1、mount操作
与任何一种UNIX系统一样,Linux并不通过设备识别访问某文件系统(如DOS那样),而是将它们“捆绑”在一个树形结构中。文件系统安装时(mount),Linux将它挂到树的某个支点(即目录),文件系统的所有文件就是该目录的文件或子目录。直到文件系统卸载时(unmount),这些文件或子目录才自然脱离。
文件系统不仅包含文件及数据,还包括了文件系统本身的树型结构以及子目录、链表(link)、访问权限等信息,它还须保证数据的安全性和可靠性。
Linux文件系统管理首先是关于“文件系统”层的管理。系统启动时,必须首先装入“根”文件系统(有全局变量ROOT_DEV指示),然后根据/ect/fstab的指定,逐个安装文件系统。此外,用户也可以通过mount、unmount操作,随时安装或卸载文件系统。相关结构和操作见init/main.c、fs/super.c和include/linux/fs.h。
当装入一个文件系统时,应首先向操作系统核心注册该文件系统。当卸载一个文件系统时,应先向操作系统核心申请注销该文件系统。文件系统注册和注销的操作函数如下。
static struct vfsmount * add_vfsmnt( struct nameidata * nd , struct dentry * root , const char * dev_name );
static void move_vfsmnt (struct vfsmout * ,struct dentry * moutpoint , struct vfsmount * parent ,const char * dev_name );
static void remove_vfdmnt(struct vfsmount * mnt );
四、虚拟文件系统
1、VFS介绍
VFS,即虚拟文件系统,是物理文件系统与服务之间的一个接口,它对Linux的每个文件系统的所有细节进行抽象,使得不同的文件系统在linux内核看来,都是相同的。严格的说,VFS并不是一种实际的文件系统。它只存在于内存中,不存在于任何外存空间。VFS在系统启动时建立,在系统关闭时消亡。
VFS使得linux同时安装、支持许多不同类型的文件系统成为了可能。VFS拥有关于各种特殊文件系统的公共界面,如超级块、inode、文件操作函数入口等。实际文件系统的细节,统一由VFS的公共界面来索引,它们对系统核心和用户进程来说都是透明的。
2、VFS功能
1)记录可用的文件系统的类型;
2)将设备同时对应的文件系统联系起来;
3)处理一些面向文件的通用操作;
4)涉及到针对文件系统的操作时,VFS把它们映射到与控制文件、目录以及inode相关的物理文件系统。
3、VFS超级块
VFS描述系统文件使用超级块和inode的方式。在系统初始启动时,所有初始化的文件系统类型(file_system_type)都要向VFS(file_systems)登记。每种文件系统类型的读超级块子程序必须识别该文件系统的结构,并且将其信息映射到一个VFS的超级块数据结构上。类似于,对所有的文件系统形成公共的属性和访问接口。
4、VFS inode
文件系统由子目录和文件构成。每个子目录或文件只能由唯一的inode描述,inode是Linux管理文件系统的最基本的单位,也是文件系统连接任何子目录、任何文件的桥梁。