图解Linux文件系统

2020-06-01 00:00:00 数据 文件 节点 结构 指向

在Linux中,文件是重要的一部分,很多的接口都是通过文件的方式展现出来。


文件有很多种:


常见的是普通文件,例如文本文件,二进制文件等。


文件夹其实也是一种文件,你可以vim一个文件夹的内容,可以看到文件夹下面的。


还有一种Char Dev也是一种文件,例如从/dev/random里面,可以读取随机数。


还有一种Block Dev也是一种文件,例如/dev/vda就代表着一块硬盘。


还有一种称为symbolic link文件,指向其他的文件,例如/etc/systemd/system/multi-user.target.wants中的文件指向/lib/systemd/system/中的相应的文件。


还有一种socket文件,用于两个进程之间通信,例如/var/run/docker.sock,就是docker客户端和daemon通信的文件。


一个普通的文件看起来是连续的,但是是分成很多的Block存放在硬盘上的不同的位置,如何知道一个文件包含哪些文件块呢,需要一种称为inode的数据结构。



mode是对权限的控制

uid和gid是属于哪个用户哪个组

atime是文件后一次被访问的时间

mtime是文件的内容被修改的时间

ctime是inode被修改的时间

dtime是inode被删除的时间


重要的是block数组,保存着这个文件保护哪些数据块,数据块里面才是真正的文件内容。


这个数组是怎么组织的呢?


在ext3中的组织方式是这样的。


这是一个层次的结构,前12项(第0到11项)直接指向的就是数据块,当文件太大的时候,第12项则变成了两层的,先指向一个中间块,然后中间块里面再保存指向真正数据块的指针。第13项则变成了三层的,第14项则变成了四层的。


在ext4中这个结构发生了变化,变成了属性架构,称为extend



组织结构如下



在 extent 树中,节点一共有两类:叶子节点和索引节点。


保存文件数据的磁盘块信息全部记录在叶子节点中;而索引节点中则存储了叶子节点的位置和相对顺序。


不管是叶子节点还是索引节点,开始的 12 个字节总是一个 ext4_extent_header 结构,用来标识该数据块中有效项(ext4_extent 或 ext4_extent_idx 结构)的个数(eh_entries 域的值),其中 eh_depth 域用来表示它在 extent 树中的位置:对于叶子节点来说,该值为 0,之上每层索引节点依次加 1。


extent 树的根节点保存在索引节点结构中的 i_block 域中,我们知道它是一个大小为 60 字节的数组,多可以保存一个 ext4_extent_header 结构以及 4 个 ext4_extent 结构。


上面我们看到的inode都是在内核代码中的,也即是内核的数据结构,在文件系统上,同样有这样的inode。


对于ext3,有以下的文件系统结构。


里面会有一个Inode Table,里面顺序保存着一系列inode,inode指向的数据块在Data Blocks里面,那么Inode Table中随着添加和删除文件,哪个位置有文件,哪个位置是空的,则Inode Bit Map中有flag表示。


在Ext4中有些变化,但是Inode Bitmap和Inode Table的部分不变。


好了,说完了基本的文件,下面说说文件夹。


文件夹也是个文件,也有inode,inode也指向数据块,数据块里面是一个列表,每一项是文件名和文件的Inode号码,如果要访问这个文件,需要在文件系统里面找这个inode,然后通过这个inode找到数据块。


文件夹的数据块是如何组织的呢?



如图所示



后我们解释一下Hard Link和Symbolic Link的区别。


Hard Link是不能跨文件系统的,他们指向的是同一个Inode的号码。

Symbolic Link是可以跨文件系统的,因为是在文件内容里面保存着指向的文件的路径。



相关文章