Linux编程入门(9)-文件系统的工作过程

上一篇文章简单介绍了文件系统的基础知识,这篇继续学习文件系统的内容。

Linux编程入门(8)-文件系统初步

创建文件的过程

文件有内容和属性,内核将文件内容存放在数据区,文件属性存放在 i 节点,文件名存放在目录中。

创建一个新文件的主要操作步骤如下:

1、存储属性

先找到一个空的 i 节点,然后内核把文件的信息记录在这个 i 节点中。

2、存储数据

根据文件内容的大小,申请能够存储这个文件的磁盘块(假如需要 n 个磁盘块)。内核从空闲磁盘块列表中找出 n 个自由块。将文件内容存放在这些自由磁盘块中。

3、记录磁盘块分配情况

文件内容按顺序存放在内核分配的磁盘块中。内核在 i 节点的磁盘分区记录块序列。

4、添加文件名到目录

内核将文件 i 节点和文件名添加到目录文件。文件名和 i 节点之间的对应关系,将文件名和文件的内容及属性连接了起来。

目录的工作过程

目录是一种包含了文件名字列表的特殊文件,是一个包含 i 节点和文件名的表。例如:

i-节点号文件名
4567.
237654
14327hello.c
634521demo.c

1、目录内部

可以通过命令 ls -1ia 来查看某个目录的内容:

$ ls -1ia demodir/

4889618 .
4751672 ..
9342328 a
9716876 c

显示目录下所有文件及其对应的 i 节点。例如,当前目录 “.” 的 i 节点号是 4889618。这意味着,有关大小、文件所有者、组等各项关于当前目录的信息,存放在 i 节点表中的编号为 4889618 的结构中。

ls 的选项 -1(数字 1)要求每行列出一个文件;选项 -i 告诉 ls 显示 i 节点号;选项 -a 要求显示所有文件。

2、指向同一文件的多重链接

可以使用命令 ls -i 查看系统上任何一个文件的 i 节点号。例如查看系统上根目录中各个文件的 i 节点号:

$ ls -ia /

       2 .                3670017 lib          3145729 sbin
       2 ..               3276801 lib32        5242881 snap
 9437185 bin              3014657 lib64       11796481 srv
 2883585 boot                  11 lost+found        12 swapfile
 2490369 cdrom            2359297 media              1 sys
       2 dev              4718593 mnt         11010049 tmp
11272193 etc             10747905 opt          7208961 usr
 4194305 home                   1 proc         2228225 var
      14 initrd.img       7077889 root              16 vmlinuz
      15 initrd.img.old         2 run               13 vmlinuz.old
  457654 test.log          457654 hello.log
  • 文件具有相同的 i 节点号

左下角的两个文件 test.log 和 hello.log 拥有相同的 i 节点号 457654。两个文件都指向了同一个 i 节点。i 节点实际上代表了一个文件,包含了文件的属性和数据块的列表。因此,test.log 和 hello.log 是同一个文件的两个不同名字。

  • 目录具有相同的 i 节点号

左上角的 “.” 和 “…”,这两项 i 节点号都为 2。所以,“.” 和 “…” 都指向同一个目录。根目录比较特殊,当用命令 mkfs 创建一个文件系统时,mkfs 将根目录的父目录指向自己。

读取文件的过程

读取一个文件时会发生什么呢?如下指令:

$ cat hello.c

1、在目录中寻找文件名

文件名存储在目录文件中。内核在目录文件中搜索包含字符串 “hello.c” 的记录。假设其所在的记录包含编号为 23567 的 i 节点号。

2、定位 i 节点并读取其内容

内核在文件系统中的 i 节点区域找到 i 节点 23567。定位 i 节点可能需要一些简单的计算,所有 i 节点大小相同,每个磁盘块都包含相同数量的 i 节点。为了提高访问效率,内核可能会将 i 节点置于缓冲区中。i 节点包含数据块编号的列表。

3、访问存储文件内容的数据块

通过以上两步,内核已经可以知道文件内容存放在哪些磁盘块上,以及它们的顺序。由于 cat 指令不断地调用 read() 函数,使得内核不断将字节从磁盘块复制到内核缓冲区中,进而到达用户空间。

多个文件系统的组合

用一些简单的抽象能够将一个单一的分区组织成一个目录树。但是,如果有两个分区,该怎样处理呢?

有些操作系统将盘符或卷标分配给每个磁盘或分区,并将字母或名字作为一个文件全路径的一部分。还有一种做法是,有些系统统一给所有的磁盘块分配编号,以创建一个虚拟的单一磁盘。

Linux 使用第三种方法:每个分区有自己的文件系统树。当计算机上有多于一个的文件系统时,Linux 提供了一种方法将这些树整合成一棵更大的树。

假设两个磁盘上分别有一个目录树,每棵树都有一个根目录。其中一个文件系统被命名为根文件系统,这棵树的顶端是整棵大树的真正的根;另一个文件系统则被附加到根文件系统的某个子目录上。

在内部,内核将根文件系统中的一个目录作为指针,指向另一个文件系统的根,这样两个文件系统就联系起来了。

  • 装载点

在 Linux 系统中,装载文件系统是指,将它嵌入到已有的系统中,以获得某些支持。子树的根目录被嵌入到文件系统的一个目录中,子树所在的目录被称为第二个系统的装载点

命令 mount 列出当前装载的文件系统以及它们的装载点:

$ mount

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=1995672k,nr_inodes=498918,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=403936k,mode=755)
/dev/sda1 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)

/dev/sda1 on / 表明 /dev/hda 上的分区 1 被装载在树的根目录上,这个分区是跟文件系统。

Linux 允许不同类型的文件系统被装载在根文件系统上。

  • 多重 i 节点号和设备交叉链接

Linux 每个文件都有一个 i 节点号。两个不同的磁盘可能都含有 i 节点号为 23567 的文件。若干个目录可能都含有 i 节点号为 23567 的文件,内核是如何知道应该使用哪个 23567 的 i 节点呢?

在两个磁盘上的文件系统中,各有一个文件,且它们的 i 节点号相同。实际上,这两个链接根本不指向同一个文件。而是分别指向各自磁盘系统上的文件(虽然看起来像指向同一个文件)。

不同的文件系统不能生成指向同一个文件的链接,文件以数据块的集合和一个 i 节点的形式存储在磁盘上,目录中的链接会指向文件的 i 节点。

  • 符号链接

硬链接是将目录连接到树的指针,也是将文件名和文件本身链接起来的指针。

符号链接通过名字引用文件,而不是 i 节点号。符号链接可以跨越文件系统,因为它们并不存储原始文件的 i 节点。符号链接也可以指向目录,因为它们与将文件系统联系在一起的真正的链接不同。

硬链接与符号链接之间的区别举例,通过 ln 创建硬链接和符号链接:

$ ln test hard_lnk      /* 创建一个硬链接 hard_link,指向文件 test */
$ ln -s test sym_lnk    /* 创建一个符号链接 sym_lnk,指向文件 test */

$ ls -li  /* 显示文件 i 节点和文件信息 */
8914203 -rw-rw-r-- 2 user user 517 12月  7 13:00 hard_lnk
8914210 lrwxrwxrwx 1 user user   4 12月  7 13:16 sym_lnk -> test
8914203 -rw-rw-r-- 2 user user 517 12月  7 13:00 test

创建一个硬链接文件 hard_lnk,文件 test 和 hard_lnk 实际上指向同一个文件,具有相同的 i 节点号 8914203,也具有同样的文件大小、修改时间和链接数。

指令 ln -s 创建文件 test 的一个符号链接 sym_lnk。这个符号链接的 i 节点为 8914210。其链接数、修改时间和文件大小都不同于原始文件。但当对文件 sym_lnk 进行读写时,实际上操作的是原始文件。

如果原始文件被删除,或者原始文件修改了文件名,符号链接将指向空。

小结

  • 文件属性存储在 i 节点,文件内容存储在磁盘的数据块。i 节点号是文件的唯一标识。
  • 相同的 i 节点可能以不同的名字在若干个目录中出现。每个入口被称为指向文件的硬链接。
  • 符号链接是通过文件名引用文件,而不是 i 节点号。
  • 若干个文件系统的目录树可以被整合成一棵树。内核将一个文件系统的目录,链接到另一个文件系统的根目录的操作,称为装载

关注公众号【一起学嵌入式】,获取更多精彩内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zsky_01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值