Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1184904
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: LINUX

2015-12-24 17:40:53


现在我们的主流价值观是社会和谐、世界和谐。同样,Linux成功的关键因素之一是它具有与其他操作系统和谐共存的能力。你能够透明地安装具有其他操作系统文件格式的磁盘或分区,这些操作系统如Windows、其他版本的Unix,甚至像Amiga那样的市场占有率很低的系统。通过所谓的虚拟文件系统概念,Linux使用与其他Unix变体相同的方式设法支持多种文件系统类型。


虚拟文件系统所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核;其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数,内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统,或者文件所在的任何其他文件系统的实际函数。

1 虚拟文件系统概述


虚拟文件系统(Virtual Filesystem)也可以称之为虚拟文件系统转换(Virtual Filesystem Switch,VFS),是一个内核软件层,用来处理与Unix标准文件系统相关的所有系统调用。其健壮性表现在能为各种文件系统提供一个通用的接口。

例如,假设一个用户输入以下shell命令:
$ cp /floppy/TEST /tmp/test

其中/floppy是MS-DOS磁盘的一个安装点,而/tmp是一个标准的第二扩展文件系统(second Extended Filesystom, Ext2)的目录。正如图(a)所示,VFS是用户的应用程序与文件系统实现之间的抽象层。因此,cp程序并不需要知道/floppy/TEST 和 /tmp/test是什么文件系统类型。相反,cp程序直接与VFS交互,这是通过Unix程序设计人员都熟悉的普通系统调用来进行的。cp的执行代码如图(b)所示:
 

VFS支持的文件系统可以划分为三种主要类型:

磁盘文件系统 

这些文件系统管理在本地磁盘分区中可用的存储空间或者其他可以起到磁盘作用的设备(比如说一个USB闪存)。VFS支持的基于磁盘的某些著名文件系统还有:

- Linux使用的文件系统,如广泛使用的第二扩展文件系统(Ext2),新近的第三扩展文件系统(Third Extended Filesystem,Ext3)及Reiser文件系统(ReiserFS)

- Unix家族的文件系统,如sysv文件系统(System V、Coherent、Xenix)、UFS(BSD、Solaris、NEXTSTEP),MINIX文件系统及VERITAS VxFS(SCO UnixWare)。

- 微软公司的文件系统,如MS-DOS、VFAT(Windows 95及随后的版本)及NTFS(Windows NT以及随后的版本)。

- IS09660 CD-ROM文件系统(以前的High Sierra文件系统)和通用磁盘格式(UDF)的DVD文件系统。

- 其他有专利权的文件系统,如HPFS(IBM公司的OS/2)、HFS(苹果公司的Macintosh)、AFFS(Amiga公司的快速文件系统)以及ADFS(Acorn 公司的磁盘文件归档系统)。

- 起源于非Linux系统的其他日志文件系统,如IBM的JFS和SGI的XFS。

网络文件系统
 

这些文件系统允许轻易地访问属于其他网络计算机的文件系统所包含的文件。虚拟文件系统所支持的一些著名的网络文件系统有:NFS、Coda、AFS(Andrew文件系统)、CIFS(用于Microsoft Windows的通用网络文件系统)以及NCP(Novell公司的NetWare Core Protocol)。

特殊文件系统 

这些文件系统不管理本地或者远程磁盘空间。/proc、/sys、/dev等文件系统是特殊文件系统的一个典型范例。

Unix的目录建立了一棵根目录为“/”的树。根目录包含在根文件系统(root filesystem)中,在Linux中这个根文件系统通常就是Ext2或Ext3类型。其他所有的文件系统都可以被“安装”在根文件系统的子目中。当一个文件系统被安装在某一个目录上时,在父文件系统中的目录内容不再是可访问的了,因为任何路径(包括安装点),都将引用已安装的文件系统。但是,当被安装文件系统卸载时,原目录的内容又可再现。

所以,Unix文件系统的一个重要特点就是可以由系统管理员用来隐藏文件,他们只需把一个文件系统安装在要隐藏文件的目录中即可。

基于磁盘的文件系统通常存放在块设备中,如硬盘、软盘或者CD-ROM。Linux VFS的一个有用特点是能够处理如/dev/loop0这样的虚拟块设备,这种设备可以用来安装普通文件所在的文件系统。作为一种可能的应用,用户可以保护自己的私有文件系统,因为可以通过把自己文件系统的加密版本存放在一个普通文件中来实现。

第一个虚拟文件系统包含在1986年由Sun公司发布的SunOS操作系统中。从那时起,多数UNIX文件系统都包含VFS。然而,Linux的VFS支持最广泛的文件系统。

2 通用文件模型


VFS所隐含的主要思想在于引入了一个通用的文件模型(common file model),这个模型能够表示所有支持的文件系统。该模型严格反映传统Unix文件系统提供的文件模型。这并不奇怪,因为Linux希望以最小的额外开销运行它的本地文件系统。不过,要实现每个具体的文件系统,必须将其物理组织结构转换为虚拟文件系统的通用文件模型。

例如在通用文件模型中,每个目录被看作一个文件,可以包含若干文件和其他的子目录。但是,存在几个非Unix的基于磁盘的文件系统,它们利用文件分配表(File Allocation Table,FAT)存放每个文件在目录树中的位置,在这些文件系统中,存放的是目录而不是文件。为了符合VFS的通用文件模型,对上述基于FAT的文件系统的实现,Linux必须在必要时能够快速建立对应于目录的文件。这样的文件只作为内核内存的对象而存在。

从本质上说,Linux内核不能对一个特定的函数进行硬编码来执行诸如read()或ioctl()这样的操作,而是对每个操作都必须使用一个指针,指向要访问的具体文件系统的适当函数。

为了进一步说明这一概念,参见前面的那个图,其中显示了内核如何把read()转换为专对MS-DOS文件系统的一个调用。应用程序对read()的调用引起内核调用相应的sys_read()服务例程,这与其他系统调用完全类似。我们在本章后面会看到,文件在内核内存中是由一个file数据结构来表示的。这种数据结构中包含一个称为f_op的字段,该字段中包含一个指向专对MS-DOS文件的函数指针,当然还包括读文件的函数。

sys_read()查找到指向该函数的指针,并调用它。这样一来,应用程序的read()就被转化为相对间接的调用:
file->f_op->read(…);

与之类似,write()操作也会引发一个与输出文件相关的Ext2写函数的执行。简而言之,内核负责把一组合适的指针分配给与每个打开文件相关的file变量,然后负责调用针对每个具体文件系统的函数(由f_op字段指向)。

你可以把通用文件模型看作是面向对象的,在这里,对象是一个软件结构,其中既定义了数据结构也定义了其上的操作方法。出于效率的考虑,Linux的编码并未采用面向对像的程序设计语言(比如C++)。因此对象作为普通的C数据结构来实现,数据结构中指向函数的字段就对应于对象的方法。

通用文件模型由下列对象类型组成:

超级块对象(superblock object):存放已安装文件系统的有关信息。对基于磁盘的文件系统,这类对象通常对应于存放在磁盘上的文件系统控制块(filesystem control block)。

索引节点对象(inode object):存放关于具体文件的一般信息。对基于磁盘的文件系统,这类对象通常对应于在磁盘上的文件控制块(file control block)。每个索引节点对象都有一个索引节点号,这个节点号唯一地标识文件系统中的文件。

文件对象(file object):存放打开文件与进程之间进行交互的有关信息。这类信息仅当进程访问文件期间在于内核内存中。

目录项对象(dentry object):存放目录项(也就是文件的特定名称)与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。

下图所示是一个简单的示例,说明进程怎样与文件进行交互。
 

三个不同进程已经打开同一个文件,其中两个进程使用同一个硬链接。在这种情况下,其中的每个进程都使用自己的文件对象,但只需要两个目录项对象,每个硬链接对应一个目录项对象。这两个目录项对象指向同一个索引节点对象,该索引节点对象标识超级块对象,以及随后的普通磁盘文件。

VFS除了能为所有文件系统的实现提供一个通用接口外,还具有另一个与系统性能相关的重要作用,那就是一些文件相关数据结构的磁盘高速缓存。例如最近最常使用的目录项对象被放在所谓目录项高速缓存(dentry cache)的磁盘高速缓存中,从而加速从文件路径名到最后一个路径分量的索引节点的转换过程。

一般说来,磁盘高速缓存(disk cache)属于软件机制,它允许内核将原本存在磁盘上的某些信息保存在RAM中,以便对这些数据的进一步访问能快速进行,而不必慢速访问磁盘本身。

注意,磁盘高速缓存不同于硬件高速缓存或内存高速缓存,后两者都与磁盘或其他设备无关。硬件高速缓存是一个快速静态RAM,它加快了直接对内存,这样的慢速动态RAM的请求。内存高速缓存是一种软件机制,引入它是为了绕过内核内存分配器(slab分配器)。

除了目录项高速缓存和索引结点高速缓存之外,Linux还使用其他磁盘高速缓存。其中最重要的一种就是所谓的页高速缓存,我们将在本专题中中进行详细介绍。

3 VFS所处理的系统调用


下表列出了VFS的系统调用,这些系统调用涉及文件系统、普通文件、目录文件以及符号链接文件:

系统调用名

说明

mount( ) umount( ) umount2( )

安装/卸载文件系统

sysfs( )

获取文件系统信息

statfs( ) fstatfs( ) statfs64( ) fstatfs64( )

ustat( )

获取文件系统统计信息

chroot( ) pivot_root( )

更改根目录

chdir( ) fchdir( ) getcwd( )

对当前目录进行操作

mkdir( ) rmdir( )

创建/删除目录

getdents( ) getdents64( ) readdir( ) link( )

unlink( ) rename( ) lookup_dcookie( )

对目录项进行操作

readlink( ) symlink( )

对软链接进行操作

chown( ) fchown( ) lchown( ) chown16( )

fchown16( ) lchown16( )

更改文件所有者性

chmod( ) fchmod( ) utime( )

更改文件属性

stat( ) fstat( ) lstat( ) access( ) oldstat( ) oldfstat( ) oldlstat( ) stat64( ) lstat64( )

fstat64( )

读取文件状态

open( ) close( ) creat( ) umask( )

打开/关闭/创建文件

dup( ) dup2( ) fcntl( ) fcntl64( )

对文件描述符进行操作

select( ) poll( )

等待一组文件描述符上发生的事件

truncate( ) ftruncate( ) truncate64( )

ftruncate64( )

更改文件长度

lseek( ) _llseek( )

更改文件指针

read( ) write( ) readv( ) writev( ) sendfile( ) sendfile64( ) readahead( )

进行文件I/O 操作

io_setup( ) io_submit( ) io_getevents( ) io_cancel( ) io_destroy( )

异步I/O (允许多个读和写请求)

pread64( ) pwrite64( )

搜索并访问文件

mmap( ) mmap2( ) munmap( ) madvise( ) mincore( )

remap_file_pages( )

处理文件内存映射

fdatasync( ) fsync( ) sync( ) msync( )

同步文件数据

flock( )

处理文件锁

setxattr( ) lsetxattr( ) fsetxattr( ) getxattr( ) lgetxattr( )fgetxattr( ) listxattr( ) llistxattr( ) flistxattr( ) removexattr( ) lremovexattr( ) fremovexattr( )

处理文件扩展属性



另外还有少数几个由VFS处理的其他系统调用,诸如ioperm()、ioctl()、pipe()和mknod(),涉及设备文件和管道文件,这些将在后续博文中讨论。最后一组由VFS处理的系统调用,诸如socket()、connect()和bind()属于套接字系统调用,并用于实现网络功能。与表中列出的系统调用还对应的一些内核服务例程,我们会在后面的博文中陆续进行讨论。

前面我们已经提到,VFS是应用程序和具体文件系统之间的一层。不过,在某些情况下,一个文件操作可能由VFS本身去执行,无需调用低层函数。例如,当某个进程关闭一个打开的文件时,并不需要涉及磁盘上的相应文件,因此VFS只需释放对应的文件对象。类似地,当系统调用lseek()修改一个文件指针,而这个文件指针是打开文件与进程交互所涉及的一个属性时,VFS就只需修改对应的文件对象,而不必访问磁盘上的文件,因此,无需调用具体文件系统的函数。从某种意义上说,可以把VFS看成“通用”文件系统,它在必要时依赖某种具体文件系统。

 

阅读(716) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~