虚拟文件系统:VFS

http://blog.youkuaiyun.com/kickxxx/article/details/9468761

http://blog.youkuaiyun.com/flagonxia/article/details/4379586


除了linux标准的文件系统Ext2/Ext3/Ext4外,存在很多种文件系统,比如reiserfs, xfs, Windows的vfat NTFS,网络文件系统nfs 以及flash 文件系统jffs2, yaffs/yaffs2 ubifs。linux通过叫做VFS的中间层最这些文件系统提供了完美的支持。

对于用户来说,这些文件系统是几乎透明的,在大部分情况下,用户通过libc和kernel的VFS交互,不需要关心底层文件系统实现,但是有时应用程序也需要考虑底层文件系统限制(比如fat vfat不支持链接,比如各个文件系统支持最大文件限制不同)。

VFS存在的意义

1. 向上对应用层提供一个标准的文件操作接口;

2. 对下向文件系统提供一个灵活的接口,以便其他操作系统的文件系统可以方便的移植到Linux上;

3. VFS内部则通过系列高效的管理机制,比如inode cache, dentry cache 以及文件系统的预读等技术,使得底层文件系统不需沉溺到复杂的内核操作,即可获得高性能;

4. 此外VFS把一些复杂的操作分尽量抽象到VFS内部,使得底层文件系统实现更简单。


虚拟文件系统包括:【/dev/】、【/proc/】和【/sys/】等,它们下面的任何文件都不会占有硬盘的空间,因为虚拟文件系统只是一个抽象的对应方式,并没有任何实体的文件存在硬盘中。 它的作用是什么?虚拟文件系统作为User Space与Kernel Space之间的桥梁,当用户的应用程序(Application)需要任何的硬件设备时,要先通过虚拟文件系统或系统模块,向Kernel请求支持。也就是说User Space中的应用程序无法直接和Kernel Space交互,必须通过中间的虚拟文件系统。


VFS架构图



文件系统分类

文件系统一般可以分为以下几类

1. 磁盘文件系统

这类文件系统数目最多,最常见:ext2/ext3/ext4文件系统;resierfs文件系统 SGI的XFS文件系统;jffs2 yaffs ubifs等flash文件系统;crasmfs squashfs等只读文件系统;fat vfa ntfs等windows文件系统;

这类文件系统大部分都是基于块设备的文件系统,文件系统的数据和元数据都保存在块设备上;flash文件系统略有差别,flash文件系统是位于MTD之上的,

flash文件系统需要处理坏快,垃圾收集,磨损平衡等复杂的功能。f随着SD/MMC卡的普及,以及flash文件系统在可扩展性,启动速度上的先天不足。flash文件系统已经慢慢退出了嵌入式舞台。

cramfs squashfs存在的意义在于简单,高效,稳定(简单的东西自然稳定),在文件系统只读的场景,仍然会被用到。二者的共同特点就是只读,压缩。我们要有这样一个概念,文件系统的复杂来源于写数据,删除,truncate操作,目录添加删除,因此一个只读文件系统远比可读写文件系统简单。最直观的方法就是查看cramfs文件系统实现代码,只有区区两个小文件。

Reiserfs 提出了很多文件系统的新概念,对小文件的读写操作做了很大的优化,当然新概念过多,也是导致可读性可理解性差的原因。此外由于reiserfs的作者Hans reiserfs因为杀妻罪名成立,所以reiserfs的开发也受到了影响。

XFS相当的复杂,后面我会单独开一片分析

2. 特别的文件系统

此类文件系统也很常用,他们不是提供常规文件存储和访问,文件系统建立在内存之上,提供特殊的文件系统功能。如proc文件系统,pipe文件系统,以及tmpfs

3. 网络文件系统

包括NFS CODA AFS等网络文件系统


通用文件模型

VFS为底层文件系统提供了抽象,有两种方式提供这种抽象。

1. 提供一个最小的通用模型,使得这个模型支持的功能是所有文件系统的最小交集

2. 提供一个尽量大的通用模型,使得这个模型包含所有文件系统功能的合集。

Linux采用第二种策略来实现VFS,因此VFS封装了底层文件系统的所有功能和抽象,VFS负责把应用层的请求转发给特定的文件系统。

在处理文件时,应用空间和内核空间使用的对象是不同的。对应用程序来说,文件描述符用来表示一个文件,这个文件描述符是打开文件时内核分配给这个文件的一个整数,注意,这个文件描述符只在本进程内有效;而对于内核来说,则使用一个inode来表示一个文件,这个inode可能对应着应用层多个进程内的多个文件描述符。


inode

内核中的每一个文件或者目录都有一个inode,inode由两个主要部分组成:

1. 描述文件状态的元数据,文件元数据包括文件大小,权限,类型,时间;

2. 文件数据描述,则用来定义文件数据在磁盘上的存放位置。

inode仅仅是文件在内核内存中的表现形式,虽然每个文件都有inode,但是并不是每个文件在磁盘上都有对应磁盘inode,实际上有些文件系统并没有磁盘inode,inode的生成有时要借助文件系统扫描。


链接

链接是unix特有的概念,又分为软链接和硬链接

软链接又称为符号链接,软链接文件内容指向一个文件路径,也就是文件真实位置,软链接指向的文件也可以是软链接

硬链接是两个文件共享同一个inode,

并不是所有的文件系统都支持符号链接和硬链接,比如fat, yaffs等文件系统并不支持符号链接。一般来说,没有磁盘目录结构的文件系统肯定不支持硬链接,而没有磁盘inode的肯定不支持链接。

软硬链接虽然为linux/unix操作管理带来了很多便利,但是在很多软件实现上,往往引入很大的复杂性。


VFS 对象类型

VFS通用模型包含以下类型对象:

1. super block

存储文件系统相关的信息,对于磁盘文件系统来说,这个对象通常对应磁盘上的一个文件系统控制块(磁盘super block)

2. inode

存储一个文件相关的信息,对于磁盘文件系统,这个对象通常对应磁盘上的一个文件控制块(磁盘inode)。每一个inode都对应一个编号,可以在文件系统内唯一标识这个文件。

3. file

file是和进程相关的,file代表一个打开的文件,file和inode之间是多对一的关系,因为多个进程可以打开同一个文件,系统会为每一次打开都创建一个file结构。

4. dentry

底层文件系统的许多操作严重依赖文件的inode,在进行文件操作前,我们需要根据路径名找到文件对应的inode。我们知道文件系统是树状结构的,因此需要从根目录通过目录树找到要操作的文件或目录,这个遍历过程涉及到磁盘操作,非常耗时。根据局部性原理,很有必要把这个查找过程cache起来,dentry就是为了加快目录遍历操作引入的数据结构。

每一个基于磁盘的文件系统,都有特定的方法用来构建目录树。一般来说有两种方式:

1. 磁盘上保存着目录项

2. 通过磁盘文件的父子关系重建目录项


2.1 基本的设备文件

      在/dev/目录下的每个设备文件都有两个代码,即Major Number和Minor Number,它们才是在系统中唯一标识一个设备的识别代码。

     使用ls -l命令,就能看到设备文件的Major Number和Minor Number。如:

     [root@airhouse dev]# ls -l sd*
     brw-r----- 1 root disk 8,  0 2009-07-26 20:44 sda
     brw-r----- 1 root disk 8,  1 2009-07-26 12:45 sda1
     brw-r----- 1 root disk 8,  2 2009-07-26 20:44 sda2
     brw-r----- 1 root disk 8, 16 2009-07-26 20:44 sdb
     brw-r----- 1 root disk 8, 17 2009-07-26 20:44 sdb1
     brw-r----- 1 root disk 8, 18 2009-07-26 20:44 sdb2
     brw-r----- 1 root disk 8, 19 2009-07-26 12:45 sdb3

2.2 /dev/bus

      在/dev目录中,可以根据不同的总线(bus)将硬件分类,目前使用总线访问的存储器,大概都是USB设备。因此在/dev/bus目录中只有一个子目录usb。 我的系统中USB控制器只有一个,它的设备文件是:

       [root@airhouse 001]# pwd

      /dev/bus/usb/001
      [root@airhouse 001]# ls -l
      total 0
      crw-r--r-- 1 root root 189, 0 2009-07-26 20:44 001

2.3 /dev/disk

      该目录下存放所有连接到这台主机上的硬盘信息,按不同的分类方式供用户查询。

      以by-uuid为例,可以看到目前有两只硬盘。

       [root@airhouse by-path]# cd ../by-uuid

      [root@airhouse by-uuid]# ls -l
      total 0
     lrwxrwxrwx 1 root root 10 2009-07-26 12:44 81c97ca6-1d1e-4a5b-903d-bc76ae32a60a -> ../../sda1
     lrwxrwxrwx 1 root root 10 2009-07-26 12:44 dd86b7da-90bb-4b4a-80b8-35afa41cdfef -> ../../sdb3

2.4 /dev/input

      这是存放输入设备的目录,但一般常用的事键盘和鼠标文件。统一的文件时event,但鼠标通用的文件是/dev/input/mice。

 2.5 /dev/mapper

      每个逻辑卷(LV)都在/dev/mapper有一个文件。它们存放实际LV使用的硬盘信息,然后通过device mapper的支持模块来访问硬盘。

      这个目录下还有一个control文件,它是Device Mapepr的控制文件。

 2.6 /dev/net

      目录中默认只会有一个tun设备文件,它是用来建立VPN的“tunnel”所使用的。

 2.7 /dev/pts

      /dev/pts目录下的文件,都是当用户通过非本机登录时,产生出可使用的Terminal界面。它与文件ptmx有直接关系。

 2.8 /dev/shm

      shm是Linux专门用来分享内存的一种API,通过shm的机制,方便地让内存直接变成一种可让用户读写数据的使用空间。

      启动时系统默认会将/dev/shm的目录以tmpfs的文件系统格式挂载(它也是一个VFS)。所以当你使用mount命令可以看到下面一行信息。

                tmpfs on /dev/shm type tmpfs (rw)

       进入系统后,我们自己也可以mount一个tmpfs目录。如:

       [root@airhouse mnt]# mkdir /mnt/tmpfs

      [root@airhouse mnt]# mount -t tmpfs -o size=50M /dev/tmpfs /mnt/tmpfs

       在需要高速存取的场合可以使用它,但是注意,不要使用超过内存大小的空间。

2.9 /dev/.udev

      存放通过udev建立起来的设备文件。udev的工作原理可见我另一篇博文《udev的介绍》。

 2.10 /dev/VolGroup00

      这个目录是在你使用了逻辑卷时才会有。里面存放的是指向该VG包含的LV的设备文件链接。如我的系统里这个文件夹里的东西看上去是这样的。

[root@airhouse VolGroup00]# ls -l
total 0
lrwxrwxrwx 1 root root 31 2009-07-26 20:44 LogVol00 -> /dev/mapper/VolGroup00-LogVol00
lrwxrwxrwx 1 root root 31 2009-07-26 20:44 LogVol01 -> /dev/mapper/VolGroup00-LogVol01
lrwxrwxrwx 1 root root 31 2009-07-26 20:44 LogVol02 -> /dev/mapper/VolGroup00-LogVol02




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值