Linux文件系统之文件类型、属性和目录项

您所在的位置:网站首页 linux系统中文件和目录的权限分类情况 Linux文件系统之文件类型、属性和目录项

Linux文件系统之文件类型、属性和目录项

#Linux文件系统之文件类型、属性和目录项| 来源: 网络整理| 查看: 265

UNIX 类操作系统中的文件通常可分为 6 类:①正规文件;②目录名;③符号链接文件;④命名管道文件;⑤字符设备文件;⑥块设备文件。如果在 shell 命令行提示符下执行"ls -l"命令,我们就可以从列出的文件状态信息中知道文件的类型,见下图:

图中,命令执行后所显示的文件信息的第一个字符即表示所列文件的类型。例如图中的 '-' 表示该文件是一个正规(一般)文件。

正规文件('-')是一类文件系统对其不作解释的文件,可包含有任何长度的字节流。例如源程序文件、二进制执行文件、文档以及脚本文件。

目录('d')在 UNIX 类操作系统中也是以一种文件形式呈现出来,但文件系统管理会对其内容进行解释,以使人们可以看到有那些文件包含在一个目录中,以及它们是如何组织在一起构成一个分层次的文件系统的。

符号链接('s')用于使用一个不同文件名来引用另一个文件。符号链接可以跨越一个文件系统而连接到另一个文件系统中的一个文件上。删除一个符号链接并不影响被连接的文件。另外还有一种连接方式称为“硬链接”。它与这里所说符号链接中被链接文件的地位相同,被作为一般文件对待,但不能跨越文件系统(或设备)进行链接,并且会递增文件的链接计数值。见下面对链接计数的说明。

命名管道('p')文件是系统创建有名管道时建立的文件。可用于无关进程之间的通信。

字符设备('c')文件用于以操作文件的方式访问字符设备,例如 tty 终端、内存设备以及网络设备。

块设备('b')文件用于访问象硬盘、软盘等的设备。在 UNIX 类操作系统中,块设备文件和字符设备文件一般均存放在系统的/dev 目录中。

在 Linux 内核中,文件的类型信息保存在对应 i 节点的 i_mode 字段中,并使用其高 4 比特位来表示。在对文件系统进行操作时,系统使用了一些判断文件类型宏,例如 S_ISBLK、S_ISDIR 等,这些宏在include/sys/stat.h 中定义。

在图中文件类型字符后面是每三个字符一组构成的三组文件权限属性。用于表示文件宿主、同组用户和其他用户对文件的访问权限。

'rwx'分别表示对文件可读、可写和可执行的许可权。对于目录文件,可执行表示可以进入目录。在对文件的权限进行操作时,一般使用八进制来表示它们。例如'755'(0b111,101,101)表示文件宿主对文件可以读/写/执行,同组用户和其他人可以读和执行文件。

在 Linux0.12 源代码中,文件权限信息也保存在对应 i 节点的 i_mode 字段中,使用该字段的低 9 比特位表示三组权限。并常使用变量 mode 来表示。有关文件权限的宏在 include/fcntl.h 中定义。图中的'链接计数'位表示该文件被硬连接引用的次数。当计数减为零时,该文件即被删除。'用户名'表示该文件宿主的名称,'组名'是该用户所属组的名称。

MINIX 文件系统目录项结构

它的目录结构和目录项结构与传统 UNIX 文件系统的目录项结构相同,定义在 include/linux/fs.h 文件中。在文件系统的一个目录中,其中所有文件名的目录项存储在该目录文件的数据块中。例如,目录名 root/下的所有文件名的目录项就保存在 root/目录名文件的数据块中。而文件系统根目录下的所有文件名信息则保存在指定 i 节点(即 1 号 i 节点)的数据块中。文件名目录项结构见如下所示:

struct minix_dir_entry {

__u16 inode; //minix_inode 的 ino 号,用于唯一指定一个 inode

char name[0]; //name[0] 是一个空字符数组,用于存放文件或目录的名字

};

对于ext2 文件系统,其目录项结构如下图:

#define EXT2_NAME_LEN 255

struct ext2_dir_entry {

__u32 inode; /* Inode number */

__u16 rec_len; /* Directory entry length */

__u16 name_len; /* Name length */

char name[EXT2_NAME_LEN]; /* File name */

};

在打开一个文件时,文件系统会根据给定的文件名找到其 i 节点号,从而通过其对应 i 节点信息找到文件所在的磁盘块位置,见下图所示。

例如对于要查找文件名/usr/bin/vi 的 i 节点号,文件系统首先会从具有固定 i 节点号(1)的根目录开始操作,即从 i 节点号 1 的数据块中查找到名称为 usr 的目录项,从而得到文件/usr 的 i 节点号。根据该 i 节点号文件系统可以顺利地取得目录/usr,并在其中可以查找到文件名 bin 的目录项。这样也就知道了/usr/bin 的 i 节点号,因而我们可以知道目录/usr/bin 的目录所在位置,并在该目录中查找到 vi 文件的目录项。最终我们可获得文件路径名/usr/bin/vi 的 i 节点号,从而可以从磁盘上得到该 i 节点号的 i 节点结构信息。

如果从一个文件在磁盘上的分布来看,对于某个文件数据块信息的寻找过程可用下图表示(其中未画出引导块、超级块、i 节点和逻辑块位图)。

通过用户程序指定的文件名,我们可以找到对应目录项。根据目录项中的 i 节点号就可以找到 i 节点表中相应的 i 节点结构。i 节点结构中包含着该文件数据的块号信息,因此最终可以得到文件名对应的数据信息。上图中有两个目录项指向了同一个 i 节点,因此根据这两个文件名都可以得到磁盘上相同的数据。每个 i 节点结构中都有一个链接计数字段 i_nlinks 记录着指向该 i 节点的目录项数,即文件的硬链接计数值。本例中该字段值为 2。在执行删除文件操作时,只有当 i 节点链接计数值等于 0 时内核才会真正删除磁盘上该文件的数据。另外,由于目录项中 i 节点号仅能用于当前文件系统中,因此不能使用一个文件系统的目录项来指向另一个文件系统中的 i 节点,即硬链接不能跨越文件系统。

与硬链接不同,符号链接类型的文件名目录项并不直接指向对应的 i 节点。符号链接目录项会在对应文件的数据块中存放某一文件的路径名字符串。当访问符号链接目录项时,内核就会读取该文件中的内容,然后根据其中的路径名字符串来访问指定的文件。因此符号链接可以不局限在一个文件系统中,我们可以在一个文件系统中建立一个指向另一个文件系统中文件名的符号链接。

在每个目录中还包含两个特殊的文件目录项,它们的名称分别固定是 '.' 和 '..'。'.'目录项中给出了当前目录的 i 节点号,而'..'目录项中给出了当前目录父目录的 i 节点号。因此在给出一个相对路径名时文件系统就可以利用这两个特殊目录项进行查找操作。例如要查找../kernel/Makefile,就可以首先根据当前目录的'..'目录项得到父目录的 i 节点号,然后按照上面描述过程进行查找操作。

对于每个目录文件的目录项,其 i 节点中的链接计数字段值也表明连接到该目录的目录项数。因此每个目录文件的链接计数值起码为 2。其中一个是包含目录文件的目录项链接,另一个是目录中'..'目录项的链接。例如我们在当前目录中建立一个名为 mydir 的子目录,那么在当前目录和该子目录中的链接示意图见下图

图中示出了我们在 i 节点号为 56 的目录中建立了一个 mydir 子目录,该子目录的 i 节点号是 123。在 mydir 子目录中的'.'目录项指向自己的 i 节点 123,而其'..'目录项则指向其父目录的 i 节点 56。可见,由于一个目录的目录项本身总是会有两个链接,若其中再包含子目录,那么父目录的 i 节点链接数就等于 2+子目录数。

比如 在文件夹a下创建一个文件夹 dir,流程如下:

1、首先在 a 的 i_zone[] 所有数据块中遍历,查找有没有存在名字为dir的目录项。若存在,则返回文件已存在,结束。若不存在进行下一步。

2、在i节点位图中查找一个bit为为0的位,在i节点中创建一条i节点记录,也即是下图i节点中dir的i节点记录。

3、为文件夹dir的i节点创建一个数据块,数据块中保存2个目录项, 也即是 . 和 .. 的目录项。所以 . 的目录项中inode节点号指向的是自己的inode,..的目录项中inode节点指向的是a的inode节点号。

4、由于在a的目录下新增了一个文件夹dir,因此在a的目录数据块中新增一条dir的目录项,当然dir的目录项中inode号也即是自己的inode号。

欢迎关注公众号 Linux码农,获取更多干货



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3