by cszhao1980
前面所讲的各项内容,进程管理也好,中断处理也罢,都静静的工作在幕后,普通用户
甚至根本感觉不到他们的存在。但文件系统不同,它工作在前台,用户或多或少都有一
定的感性及理性认识——这给我们的读码带来了巨大的好处。在这里我假设大家对unix
文件管理有一定的认识,比如,知道文件系统的树状层次结构,知道文件的访问控制,
知道绝对路径与相对路径,知道如何将一个磁盘mount进系统去。
一个能够被mount进系统的设备也被称为“文件系统卷”,它必须满足unix的一些要求,如:
(1) 它是一个块设备;
(2) #1块必须被设置为“超级块”,其中记录整个文件系统有关的信息;
(3) #2~#n块记录“inode”(索引节点)列表。
Inode是文件系统中最重要的概念之一,毫不夸张的说,它是unix文件系统设计的核心。inode与
文件紧密相关,但可惜的是,它们之间不一定是一一对应的关系,比如与某文件进行“硬链接”
的另一个文件就与前者共享inode。为理解这一点,我们不妨先考虑一下“文件位置”这个概念。
文件的位置有多个层面的含义,比如:
(1) 该文件必然保存在某实际设备上,并占据其中若干个(可以为0)块;
(2) 在文件系统层面上,必然存在一个以它所在的文件系统卷的“根”为起始目录的Path,
通过该Path可以“找到”该文件;
(3) 在unix层面,当该文件所在文件系统被mount进来之后,必然存在一个以根目录为起点的Path,
通过该Path可以‘找到”该文件。
在这三个层面中,仅有层面1属于物理层面,而inode与物理层面的文件时一一对应的。一个inode
表项记录一个文件的“某些”信息,而整个inode列表就记录了整个文件系统上所有文件的信息。一
个磁盘inode entry共有32个字节,磁盘使用专用的块来存放inode entries,1个块可以保存16个inode entry。
Inode的结构如下所示:
5605: struct inode
5606: {
5607: int i_mode; //文件的模式,由一系列bit flag组成,如写标志,可执行标志等等;
5608: char i_nlink; //该文件的“硬链接”数
5609: char i_uid; //文件owner的user id
5610: char i_gid; //文件owner的group id
5611: char i_size0; //文件size首字
5612: char *i_size1; //文件size第二字
5613: int i_addr[8];
5614: int i_atime[2]; //access time
5615: int i_mtime[2];
5616: };
其中,inode使用i_size0和i_size1两个word来模拟1个32位数据,用来存放文件长度,单位为byte。
i_size1为低第16bit,而i_size0为高16 bit。Unix v6支持的文件最大长度2**24字节(占用2**15个块),
因此,i_size0仅有8个 bit为有效值。
当inode被读入内存时,会多出4个成员:
5659: struct inode
5660: {
5661: char i_flag;
5662: char i_count; /* reference count */
5663: int i_dev; /* device where inode resides */
5664: int i_number; /* i number, 1-to-1 with device address */
5665:
……. //以下与磁盘inode定义相同
5675: } inode[NINODE];
(1) i_flag:多于对此inode项进行的内存操作有关,共有以下几种flag:
5679: #define ILOCK 01 /* inode is locked */
5680: #define IUPD 02 /* inode has been modified */
5681: #define IACC 04 /* inode access time to be updated */
5682: #define IMOUNT 010 /* inode is mounted on */
5683: #define IWANT 020 /* some process waiting on lock */
5684: #define ITEXT 040 /* inode is pure text prototype */
(2) i_count:记录系统中进程对该inode项的reference count
(3) i_dev:inode所在设备的设备号;
(4) i_number:该inode在其文件系统内的id。Inode的id是根据其磁盘inode项所处的磁盘
顺序来决定的,即磁盘上第一个inode即为#1号inode,依次类推。对整个系统而言,i_number与
i_dev一起能唯一确定一个inode。
我们还可以看到,在5675行还定义了inode数组,每一个被读入内存的inode项都会占据数组的一个
entry。Inode数组共有NINODE个entry,也就是说最多只能读入NINODE个文件的inode项——这有
助于我们理解那条古训:“打开的文件要及时关闭”。现在,我们大致能够猜出open一个file时,
发生了什么——对了,就是把该文件的磁盘inode读入内存。
【注】:unix虽然定义了磁盘inode的struct,但在实际上任何程序都没有include该.h文件。Unix程序
仅操作一种inode struct,即内存inode struct。
博客地址:http://blog.csdn.net/cszhao1980
博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html