Linux中的inode、block
文件系统、分区槽的概念
分区槽,你可以想象Windows系统中的一个盘符,C盘、D盘各为一个分区槽。
操作系统的一个基本功能就是文件与目录管理,不同的系统进行管理的方式都不一样,所以一个分区槽被划分出来之后,还要按照某种文件系统的格式进行格式化,如Windows中的FAT32和NTFS,Linux中的Ext2/3/4和xfs。所以这也是Linux文件系统和Windows没法直接互通的原因,因为它们并不会按照对方的方式来管理文件。
一般情况下我们都会直接把一个分区槽按照一种文件系统的格式直接分区,在很长一段时间内也只允许这样分区,所以文件系统和分区槽的概念一直很模糊。但是后来LVM和磁盘阵列的出现允许我们将一个分区槽划分成多个文件系统或者将多个分区槽合并为一个文件系统,所以我们要把这两个概念区分开。
文件记录方式
无论是磁盘还是固态硬盘,它们肯定不知道文件的存在,它们只是有一些可以用来存储数据的单元,通过一些协议与操作系统进行交互。文件和文件夹是操作系统对磁盘的抽象,这个抽象允许用户以更加清晰明确简单的方式管理磁盘中的数据。
所以操作系统需要一种手段来和底层存储设备交互,Linux中将文件统统抽象成inode
和block
,block
记录文件实际的数据,inode
记录文件的属性、权限、存储内容的block块等数据。
inode
与文件是一对一关系,它的大小固定为128bytes
,而block
与文件是多对一关系,也就是说一个文件可以被存储在多个block
中,block
的大小一般为1K、2K、4K(在Ext2文件系统中)。每个inode
和block
都有一个唯一的编号。
如下图,有一个文件对应着inode4,inode中记录着该文件的数据被存储在编号为2、7、13、15的block中:
类似FAT这种系统没有inode,它是靠将一个文件的所有block组成一个链表来获得文件数据的。
这样虽然节省了一些空间,但是当block分布的过于离散时,磁盘的性能可能急剧下降。此时需要进行一次碎片整理将磁盘中的数据变得井然有序(这个操作很慢)
除了inode
、block
外,系统中还可能有一个superblock
,它记录系统中的所有inode和block总量以及使用量等信息。
Ext2多区块群组
因为inode信息和block信息都是在格式化之出就不会变动,所以如果文件系统很大,将它们都放在一起是不明智的。Ext2中实际使用了如下的方式:
系统中存在很多个inode/block/supernode
的区域,每个区域称为一个组。然后在该文件系统的最前面,为了支持多重引导,设置了一小块Boot Sector用于安装开机管理程序。
inode
inode中记录的内容:
因为inode
一共只有128bytes,其中一个block记录就要4byte,文件稍大,inode中就存不下了,所以Ext2中使用多级存储的方式:
思路就是用额外的block记录文件占用的block信息。
inodebitmap、blockbitmap
inode和block的对照表,用于记录系统中哪些inode或block是空闲的。
文件夹中的inode和block
文件夹的inode和文件的并无区别,记录文件夹的各种权限以及元信息,但他们一般只有一个block块,其中存放的是文件夹中的文件的文件名和inode信息
所以,无论是文件的inode还是block是都不存储文件的名字的,文件的名字存储在它所在文件夹的block中。
读取文件的实例
假设要读取/etc/passwd
则要经历以下步骤:
- 读取
/
的inode块,确保我们具有该目录的rx
权限 - 读取
/
的block块,获取其下etc/
的inode - 读取
etc/
的inode块,确保具有该目录的rx
权限 - 读取
etc/
的block块,获取其下passwd
文件的inode - 读取
passwd
的inode块,确保具有该目录的r
权限 - 读取
passwd
所有的block块
数据不一致
我们看到这种文件系统结构中创建一个文件需要很多步骤,如果在这些步骤中间发生了断电或什么其它问题导致系统异常关闭,此时inode bitmap和block bitmap中可能存在不一致的数据。
日志式文件系统
使用日志,可以解决上面的问题,这也是数据库系统解决不一致问题的方法:
- 预备:当要写入一个文件时,先写入一条将要写入文件的日志
- 实际写入:开始写入文件的权限与数据;更新bitmap的数据
- 结束:完成数据与bitmap的更新后,在日志中写入已经完成的信息
此后只需要检查日志文件系统即可。
参考
- 鸟哥的Linux私房菜 基础篇 第四版