文件
Linux中文件的概念并没有那么纯粹,不单单指的是磁盘上的文件。Linux中只要是字节序列构成的载体,都可以是文件,比如I/O设备、socket套接字等。总的来说大致分为以下几类:
- 普通文件。即磁盘上的文件
- 目录文件。即目录
- 链接文件。Windows上称为快捷方式,但是在Linux中链接文件还分为软链接(符号链接)与硬链接
- 设备文件。Linux中将设备看作文件来进行管理,分为块设备与字符设备。
- socket文件。用于网络通信
- 管道文件。用于IPC
文件系统结构
在Linux中,文件系统并不是像Windows中的那样分为一个一个盘,而是以挂载到别的文件系统的形式存在的。这种结构可以简单地看成树型结构,根结点则是根文件系统。
文件系统
Linux可以支持很多文件系统,这些文件系统之间的数据也可以是互通的。Linux使用了VFS
这一结构来管理文件系统。
VFS
即虚拟文件系统,在各种具体的文件系统之上建立一个抽象层,屏蔽了不同文件系统之间的差异。这种抽象层其实也像POSIX
标准一样,为了屏蔽底层的细节而设计的。
VFS
VFS
主要有如下的四个对象类型:
- 超级块(struct super_block)。超级块代表一个已经安装的文件系统,存储着该文件系统的有关信息,比如文件系统的类型、大小、状态等。
- 索引结点(struct inode)。索引结点对象表示存储设备上的一个实际的物理文件,存储该文件的有关信息,比如权限、大小以及创建时间等。
- 目录项(struct dentry)。目录项描述了文件系统的层次结构,不管是目录还是普通的文件,都是一个目录项对象。
- 文件(struct file)。文件对象代表已经被进程打开的文件,主要用于建立进程和文件之间的对应关系。
值得注意的是,目录项并不是存在于磁盘中的信息,而是存在于内存当中,相当于磁盘的缓存。
文件
文件对象描述已经打开的文件,对于进程来说,能够直接进行处理的是文件,而不是超级块之类的。对于每个inode
,可以对应多个文件对象,而一个文件对象只能对应一个inode
。文件对象包含了对文件的相关操作struct file_operations
,包括打开、关闭、读写等等。
与文件系统相关的结构
超级块中包含了一些其他的文件系统有关的结构体,例如struct file_system_type
,表示文件系统类型。对于ext3
文件系统来说定义如下:
1 | static struct file_system_type ext3_fs_type = { |
struct vfsmount
则包含了文件系统挂载的信息,包括挂载点、根结点等。
与进程相关的结构
每个进程都有自己的根目录与当前工作目录,例如在shell
中,可以使用pwd
(print working directory)命令来打印当前工作目录。除此之外,进程还需要记录自己打开的文件,进程打开的文件用struct files_struct
来表示,里面就包括了struct file
数组,记录已经打开的文件信息。
inotify机制
简单来说,inotify
机制是用来监听文件的变化的,类似与设备发送中断来表示设备状态发生了变化,操作系统也会发送信号来表示文件发生了变化,而这一点在Linux是通过inotify
机制来实现的。
每个inode
结点上都有一个inotify_watches
字段,指向了该inode
对象的监控列表,一个watch
实例是一个struct inotify_watch
结构的实例,代表了对该inode
的监控请求,其中就包含了事件处理函数。
inotify
的实现原理是,在各个文件操作函数的hook
通过inode
的成员inotify_watches
找到监控列表,然后再通过监控列表找到事件处理函数,然后再进行处理。