文件系统 FS (未)
文件系统 FS (未)
文件系统 (FS)
特点
- 持久化:文件系统是操作系统中负责管理持久数据的子系统,说简单点,就是负责把用户的文件存到磁盘硬件中,因为即使计算机断电了,磁盘里的数据并不会丢失,所以可以持久化的保存文件。
- 组织方式:文件系统的基本数据单位是文件,它的目的是对磁盘上的文件进行组织管理,那组织的方式不同,就会形成不同的文件系统。
- 一切皆文件:Linux 最经典的一句话是:「一切皆文件」,不仅普通的文件和目录,就连块设备、管道、socket 等,也都是统一交给文件系统管理的。
几个文件相关的概念(等待重新梳理)
文件 / 文件对象
Linux 文件系统会为每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),它们主要用来记录文件的元信息和目录层次结构。
目录 (目录文件)
目录也属于是文件,自然继承了文件的特性,也存在对应的inode和目录项
索引节点 (inode = index node)
内容(文件的元信息)
inode 编号
文件大小
访问权限
创建时间
修改时间
数据在磁盘的位置
……等等
唯一标识:索引节点是文件的唯一标识,它们之间一一对应
存放:存放于磁盘。inode存储在磁盘上的特定区域,这个区域被称为inode表。每个文件系统分区都有自己的inode表。inode的位置和数量在文件系统创建时就已经确定,不会再改变。
目录项 (dentry = directory entry)
- 内容
- 文件的名字
- 索引节点指针
- 与其他目录项的层级关联关系
- 存放:存放于内存(目录结构的一部分。目录结构是内核数据结构,目录项相当于是这个数据结构里的一部分)
- 例如:/home/xxx/yyy.txt 中,/、home、xxx、yyy.txt 都是一个目录项
目录结构 / 目录树 / 目录项集
- 内容
- 多个目录项关联起来,就会形成目录结构 (目录树)
- 存放:存放于内存:但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。
几个文件相关的概念 - 梳理
目录 != 目录项
虽然名字很相近,但是它们不是一个东西:
- 目录:是个文件,持久化存储在磁盘
- 目录项:是内核一个数据结构,缓存在内存
- 如果查询目录频繁从磁盘读,效率会很低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。
注意,目录项这个数据结构不只是表示目录,也是可以表示文件的。
索引节点与目录的关系 (多对一)
每个文件有两个数据结构:
- 索引节点(index node)
- 目录项(directory entry)
由于索引节点唯一标识一个文件,而目录项记录着文件的名字,所以目录项和索引节点的关系是多对一。也就是说,一个文件可以有多个别名。
比如:硬链接的实现就是多个目录项中的索引节点指向同一个文件。
注意,目录也是文件,也是用索引节点唯一标识,和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件
磁盘与文件数据
那文件数据是如何存储在磁盘的呢?
扇区 (512B)
磁盘读写的最小单位是扇区,扇区的大小只有 512B
大小,很明显,如果每次读写都以这么小为单位,那这读写的效率会非常低。
逻辑块 (4KB,8扇区)
所以,文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块),Linux 中的逻辑块大小为 4KB
,也就是一次性读写 8 个扇区,这将大大提高了磁盘的读写的效率。
Linc 补充:
$ df -l 文件系统 1K的块 已用 可用 已用% 挂载点
这里的 “1K的块” 指显示方式是K,方便你看块的大小总和是多少,而不是说每个逻辑块的大小真的是1K
磁盘区域 (超级块、inode区、数据块区)
另外,磁盘进行格式化的时候,会被分成三个存储区域,分别是 超级块、索引节点区和数据块区。
- 超级块:用来存储文件系统的详细信息,比如块个数、块大小、空闲块等等。
- 索引节点区:用来存储索引节点;
- 数据块区:用来存储文件或目录数据;
我们不可能把超级块和索引节点区全部加载到内存,这样内存肯定撑不住,所以只有当需要使用的时候,才将其加载进内存,它们加载进内存的时机是不同的:
- 超级块:当文件系统挂载时进入内存;
- 索引节点区:当文件被访问时进入内存;
关系总结
以上就是索引节点、目录项以及文件数据的关系,下面这个图就很好的展示了它们之间的关系:
索引节点是存储在硬盘上的数据,那么为了加速文件的访问,通常会把索引节点加载到内存中。