文件系统
首先我们应该知道一个磁盘可以划分为多个分区,而每个分区就可以包含一个文件系统。UNIX的文件系统是这样的:
而我们主要关心的是i节点和数据块。i节点是固定长度的记录项,它包含有关文件的大部分信息。一个柱面组的i节点和数据块的部分是以下这样的:
从这图我们就可以知道,i节点是存放文件的信息(比如stat结构里描述的那些属性),数据块就是存放文件的内容的。那么目录块是什么呢?从图可知,目录块包含了i节点号和文件名。其实这就是hard link(硬链接)。在图中由两个目录项指向同一i节点。每个i节点都有一个链接计数(link count),保存的是指向该i节点的目录项数。只有当链接计数减少至0时,才可以删除该文件(也就是释放该文件占用的数据块)。这就是为什么“解除一个文件的链接”操作并不总是意味着“释放该文件占用的磁盘块”的原因(因为一个文件可以由多个目录项,也就是多个硬链接)。这也就是为什么删除一个目录项的函数被称为unlink而不是delete的原因(实际上,在Linux中,创建硬链接的命令是ln,而解除的命令是unlink)。在stat结构中,链接计数包含在st_link成员中,其基本数据结构类型是nlink_t。
另外一种链接类型被成为符号连接(symbolic link)。对于这种链接,该文件的实际内容(在数据块中)包含了除该符号链接所指向的文件的名字(简单来说,就相当于windows下的快捷方式)。
i节点包括了大多数与文件有关的信息:文件类型、文件访问权限位、文件长度和指向该文件所占用的数据块的指针等等。stat结构中的大多数信息都取自i节点。只有两项数据存放在目录项中:文件名和i节点编号。(i节点编号的数据类型是ino_t)。
当在不更换文件系统情况下为一个文件更名时,该文件的实际内容并未移动,只需构造一个指向现有i节点的新目录项,并解除与旧目录项的链接。这就是mv(1)命令的通常操作方式(原来是这样!)。
接下来讲下目录的i节点:
我们都知道,.代表目录本身,..代表父目录。从图中可知,1267是2549的父目录,因为2549的.指向本身,而1267的..指向父目录。所以,任何一个字目录(不包含其他目录的目录)的链接计数总是为2。(一个是. ,另一个就是本身的名字testdir)。
而父目录的链接计数则是随着子目录的增加而增加。(本身已有.和..两个,加入再建立子目录testdir,则testdir的..则指向父目录)