文件系统深层剖析

在 Linux 内核中,一切皆文件

概论

Linux 文件系统为每个文件分配两个数据结构:索引节点(inode)和目录项(dentry)。

  • 索引节点,里面存储了文件的元数据(比如 inode 编号、文件大小、访问权限、修改时间、数据块在磁盘中的位置等),但不包括文件名。索引节点是文件的唯一标识,也被存储在硬盘中
  • 目录项,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系,它的内容是一组“文件名 ↔ inode 编号”的映射关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存

注意:

  • 一个文件在文件系统中真正的内容是由 inode 决定的,而目录项只是给这个 inode 一个名字,方便我们通过路径访问它。多个目录项(即多个不同的路径或文件名)都可以指向同一个 inode,这就是硬链接
  • 目录项和目录不是一个东西:目录是个文件,持久化存储在磁盘,也是用索引节点唯一标识。和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件。而目录项是内核一个数据结构,缓存在内存。因为如果查询目录频繁从磁盘读,效率会很低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。
  • 目录项 dentry 这个数据结构不只是表示目录,也是可以表示文件的。

F1. inode、dentry 和文件数据之间的关系(来自小林 coding)

存储文件数据的磁盘可以被分为三个存储区域

  • 超级块:用来存储文件系统的详细信息,比如块个数、块大小、空闲块等等。
  • 索引节点区:用来存储 inode
  • 数据块区:用来存储文件或目录数据(文件系统的基本操作单位就是数据块)。

虽然 inode 是存储在硬盘上的数据,但为了加速文件的访问,通常会把 inode 加载到内存中。内存空间有限,我们不可能把超级块和索引节点区全部加载到内存,所以只有当需要使用的时候才将其加载进内存,它们加载进内存的时机是不同的:

  • 超级块:当文件系统挂载时进入内存。
  • 索引节点区:当文件被访问时进入内存。

软硬链接

在 Linux 中,硬链接(hard link)是指多个目录项指向同一个 inode,即它们共享同一个文件的数据块。因此,硬链接本质上是“同一个文件的多个名字”。由于 inode 是文件系统内部的结构,不能跨文件系统使用,所以硬链接也只能存在于同一个文件系统中。一个文件的 inode 中包含一个链接计数器,表示有多少个目录项指向它。只有当所有的硬链接(包括原始文件)都被删除后,链接计数归零,系统才会真正释放该文件的磁盘空间。

相比之下,软链接(symbolic link)是一个独立的文件,拥有自己的 inode。它的内容是目标文件的路径,因此更像是一个快捷方式。软链接可以跨文件系统创建,甚至可以指向一个不存在的文件(此时成为悬挂链接或死链接)。访问软链接时,系统会自动解析其路径并跳转到目标文件。如果目标文件被删除了,链接文件还是在的,只不过就找不到指向的文件了。

虚拟文件系统

文件系统种类众多,而操作系统希望为用户提供一个统一的接口,于是在用户层和文件系统层之间引入了一个中间层,即虚拟文件系统。

打开文件表

操作系统为每个进程维护一个打开文件表,用于追踪该进程当前打开的文件。每个条目对应一个文件描述符,文件描述符可以看作是打开文件在进程内的一个“句柄”。在操作系统层面,还存在一个系统级的打开文件表,用于维护每个被打开文件的全局状态信息。操作系统通过这两个层级的文件表,管理文件的访问和资源使用。

每个进程级打开文件表中的条目,指向一个系统级的打开文件表项,而系统级的打开文件表项,再指向VFS 层的 inode 表项,这些表项最终映射到实际文件的磁盘位置。每个系统级打开文件表项通常包含以下信息:

  • 文件位置指针:跟踪文件的当前读写位置。对于同一个文件,不同进程可能拥有独立的文件位置指针(如每个进程单独打开文件),也可能共享(如通过 forkdup 产生的共享文件描述符)。
  • 引用计数:表示有多少个文件描述符引用了该文件。只有当该计数归零时,操作系统才会真正关闭文件、释放对应的打开文件表项,这样可以支持多个进程同时访问同一个文件而不冲突。
  • 文件磁盘位置:用于标识文件在磁盘上的位置,指向文件的 inode,避免每次操作都去磁盘查找文件元信息,从而提高效率。
  • 访问权限:表示打开该文件时指定的权限,如只读、只写、读写、追加等,操作系统根据该信息决定是否允许某些 I/O 操作。

文件的存储

文件的数据在磁盘上的存放方式,主要有连续空间存放和非连续空间存放这两种。其中,非连续空间存放方式又可以分为链表方式索引方式。 👉指路


不准投币喔 👆

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇