内容简介:Linux 的成功有一部分原因在于能够很好的支持不同的文件系统,你能够轻松透明地把 Windows、其他 Unix 系统、甚至是占有极小份额的 Amiga 使用的文件系统VFS 背后的 idea 是在 kernel 中抽象出不同文件系统,针对具体的文件系统,Linux kernel 实现具体的操作方法。当系统调用要执行一个
Linux 的成功有一部分原因在于能够很好的支持不同的文件系统,你能够轻松透明地把 Windows、其他 Unix 系统、甚至是占有极小份额的 Amiga 使用的文件系统 mount
到 Linux 的文件系统中。这是通过 Virtual Filesystem
(以下简称 VFS)实现的。
VFS 背后的 idea 是在 kernel 中抽象出不同文件系统,针对具体的文件系统,Linux kernel 实现具体的操作方法。当系统调用 read
、 write
发生时,kernel 根据操作的具体文件系统,比如 native Linux文件系统、NTFS(Windows NT)等,调用相对应的函数。
实例: cp
要执行一个 cp
指令:
cp /floppy/TEST /tmp/test 复制代码
其中 /floppy
是一个 mount 的MS-DOS文件系统,而 /tmp
是 ext2。 VFS 就是应用程序和底层文件系统实现之间的一个抽象层 , cp
不需要知道 /floppy/TEST
个 /tmp/test
的文件系统类型,它只需要调用标准的系统调用,比如 read
、 write
这些, 把底层文件系统不同带来的复杂度交给 kernel 。
示例的代码如下:
inf = open("/floppy/TEST", O_RDONLY, 0); outf = open("/tmp/test", O_WRONLY|O_CREAT|O_TRUNC, 0600); do { i = read(inf, buf, 4096); write(outf, buf, i); } while (i); close(outf); close(inf); 复制代码
示意图:
代码和截图来源于 《Understanding the Linux Kernel, Third Edition》 P457
VFS 支持的文件系统
VFS 支持嗯文件系统一共分为下面三大类:
- Disk-based FS
本地的 disk。包括:
- ext2, etx3, ext4
- Unix 家族,比如 sysv 文件系统、UFS(BSD,solaris)、MINIX等
- Microsoft 文件系统,比如 MS-DOS、NTFS
- ISO9660 CD-ROM(之前的High Sierra Filesystem)
- 其他冷门
- Network FS
这一类支持访问远程的文件系统,比如 NFS、Coda、AFS 等。
- Special FS
如 /proc
虚拟文件系统。
通常来说,root 目录为 Linux 原生的 ext2
、 ext3
、 ext4
,其他类型的文件系统通过 mount
形式 mount 到某个特定子目录。
Common File Model
VFS 背后的核心idea: 用common file model表示所有现实中的FS。这个模型严格使用原生Unix FS 模型,每个特定的 FS 都需要将自己的硬件结构翻译成 common file model。
比如在 common file model 中,目录也被看做文件,包含其他的文件盒目录。然而,一些非 Unix 的 FS,使用的是 file allocation table(FAT),这种情况下,目录不是文件。但是为了遵循 common file model的规则,Linux 对这种 FAT-based 的 FS,必须能够抽象出一个遵循common file model 的接口。
更加具体点,Linux kernel 在处理 read
、 ioctl
这些系统调用的时候,不能直接硬编码,使用某个特定的底层函数。kernel实际上针对每一个操作,使用的是一个指针,这个指针指向了针对此文件系统专门的处理函数。
让我们来看看kernel 是如何完成上面提到的 cp
操作的。
应用层调用 read()
,kernel 实际上会调用 sys_read()
service routine(其他的系统调用也一样)。MS-DOS FS 的文件被 kernel memory 中的一个数据结构表示,这个数据结构包含一个 f_op
字段,指向的是针对 MS-DOS 的 read 函数。 sys_read()
找到这个函数然后调用它。所以整个过程可以看作是:
read() -> sys_read() -> file data structure -> f_op -> read_for_msdos() 复制代码
调用 write()
也一样,这个系统调用会触发针对 ext2
FS 的写调用。
简要来说, 对于每个 open()创建的 file object,kernel 需要负责正确赋值此 file object的指针,指向针对此文件系统的特定函数,然后调用这些函数。
CFM 包含哪些 object types
- superblock object:包含的是 mounted FS 的数据。
- indoe object:特定文件的数据。对于 disk-based FS,这个 object 一般对应一个 file control block。每个 inode object 都有一个 inode number,唯一指定 FS 中的某一个文件。
- file object:一个open file 和进程之间的交互信息。这个 object 只在进程打开文件的时候在kernel memory 中存在
- dentry object:文件名到inode的映射,不同的 FS 有不同的底层实现。
总结一下
VFS 是应用和特定文件系统之间的一层抽象,有些操作能够直接在 VFS 层完成,不需要涉及到底层的具体文件系统。比如说,当进程close file的时候,disk 上的文件本身是不会改变的,所以 VFS 只要把对应的 file 对象释放掉就行了。再比如说, lseek()
系统调用,改变的也是内存中的 file 对象,而不需要设计底层的文件系统。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Mozilla 20 周年:我们的使命是打造更好的互联网
- Ubuntu 17.10 本月结束使命,用户应升级至 18.04
- Gavin Wood 谈 Polkadot 的「疯狂表亲」Kusama 使命与进展
- Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!
- 人工智能发展需要真正的开源开放,OpenI启智平台肩负使命正式启航
- 万维网之父新使命:把互联网数据控制权归还给网民
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming Python
Mark Lutz / O'Reilly Media / 2006-8-30 / USD 59.99
Already the industry standard for Python users, "Programming Python" from O'Reilly just got even better. This third edition has been updated to reflect current best practices and the abundance of chan......一起来看看 《Programming Python》 这本书的介绍吧!