前言
学习《深入linux内核架构》的书本阅读。基本是书中知识点的摘抄。
VFS虚拟文件系统
VFS在内核的层次结构图。
应用目的:为支持本机文件系统,同时允许访问其他操作系统的文件,Linux内核在用户层和文件系统间引入了抽象层,虚拟文件系统(Virtual File System)。
文件系统类型
- Disk-based Filesystem
如EXT2 - Virtual Filesystem
如proc - 网络文件系统
如NFS
通用文件模型
VFS的解决方案,提供一种结构模型,包含文件系统所应具备的所有组件。此模型,只存在与虚拟中,必须使用各种对象和函数指针与每种文件系统适配。
处理文件时,内核空间和用户空间使用的主要对象是不同的。
用户程序:一个文件由一个文件描述符标识,描述符是整数,用作所有有关文件的操作中用作标识文件的参数。文件描述符是在打开文件时由内核分配的,只在一个进程内部有效。(这很重点,同桌还说是否有可能功用一个文件描述符,在这里看起来就不是了)。两个不同的进程可以使用同样的文件描述符,但是二者不能指向同一个文件。基于同一个描述符来共享文件是不可能的(为什么呢?)
内核空间: 内核处理文件的关键是inode
。每个文件(和目录)都有且仅有一个对应的inode
,其中包含元数据(访问时间,等),和指向文件数据的指针。但inode
不包含文件名。
inode
先给出inode在内核中的结构体定义。
inode
成员分为两类:
- 描述文件状态的元数据。如,
atime
,ctime
,mtime
- 保存实际文件内容的数据段(或者指向数据的指针)
书中给了一个示例,来阐述利用inodes
来构造文件系统的目录层次结构。
(看起来是结合了inode
, dentry
来完成文件的查找,只是当前还没有介绍dentry
的概念)
查找首先,起始于一个inode
,表示根目录/
。(根目录的inode
,对于系统来说是已知的)。根目录是由一个inode
表示,其数据段并不包含普通的数据,而是根目录下的各个目录项。
目录项由两个成员组成:
- 该目录项的数据所在
inode
的编号 - 文件或者目录的名称
系统中所有的inode
都有一个特定的编号,用于唯一标识各个inode
。文件名和inode
之间的关联就是通过该编号完成的。
以/usr/bin/emacs
为例,查找过程:
第一步,查找子目录usr
的inode
,这一步会扫描根inode
的数据段,直至找到一个名为usr
的目录项。
第二步,重复第一步,直至在bin
的数据段中查找到emacs
的目录项,这时仍旧返回一个inode
编号而非目录。(这很奇怪呀,如果最后一项仍旧是目录呢?)
第三步,最后一个inode
的文件内容,与前三个inode
不同。前三个inode
都表示目录,其文件内容是目录项的列表,包括子目录和文件。与emacs
文件关联的inode
,其数据段存储了文件的内容。
下面,给出一张图片,完整描述上面的故事: