Inode和Block
在Linux系统里“一切皆文件”,文件存储于文件系统。Linux文件系统里包含了两个基本的区块inode和block。这儿搬运一下《鸟哥Linux私房菜》里的图:
简而言之:
- 文件的内容由若干块block组成,每块block的大小可以是1K、2K和4K等;
- inode就是用来索引文件block的区块,此外还记录了文件的一些信息,用
stat
系统调用函数可以查看这些信息。- 对于大文件,则是用block块替代inode作索引,甚至作多级索引。
值得一提的还有,多个不同文件可以指向同一个inode,表面上这些文件的绝对路径是不同,但其本质是一体的,这就是硬链接。不过目录不能做硬链接,我的理解是如果目录可以做硬链接,这样就能构造出一个循环的目录路径,系统在挂载文件系统的时候不能很好的处理,所以就禁止目录做硬链接。
不妨就把inode当作文件的本身,而inode指向的block存放文件的内容。
File Descriptor 和 Open File Description
对文件的基本操作有open(2)
和close(2)
这两个系统调用函数。
open()
函数打开一个文件并返回一个文件描述符(file descriptor),而close()
函数则用来关闭指定的文件描述符。从一个整体的角度去看,文件描述符就表示了被打开的那个文件,指向了文件的inode。
事实上,在man page里对于open()
和close()
函数的描述里除了提到了file descriptor
,还提到了一个叫open file description
的名词。为了方便观看,下面的描述中将file descriptor
简称为FD,而open file description
简称为OFD。
open()
调用成功后,会在一个系统全局的表中创建一个OFD的项,这个数据结构除了有指向打开文件的inode
信息,还有文件打开的状态标识和文件当前偏移量等信息。同时在进程表中会创建一个FD项,其值取为当前进程还未用到的最小非负整数,并指向那个OFD项。- FD项与OFD项是多对一的关系。利用
dup
、dup2
函数以及fork
出来的子进程可以复制FD,这些复制的文件描述符FD所指的OFD项不变。close()
调用成功后,会移除进程内维护的指定的FD项,并且如果其指向的OFD项只剩该FD这最后一个指向,那么这个孤立的OFD项也会被移除。
于是乎,进程调用open()
打开一个文件,在进程内维护的是file descriptor
这一项,其指向系统内核维护的open file description
项,而该项又指向文件系统的inode
。
另外呢,观察进程打开的文件描述符可以用如下命令;
最后
这四者的关系从整体上可以用这张图来表示(参考自APUE):