目前文件系统比较成熟,各种学习文档也很多,但这些文档无一另外的上来先灌输一堆概念,什么Block,inode,dentry 等等,很是不友好,本文希望能够以一种更友好的角度来解释这些.
假设我们现在有一个256K的空间,我们要如何去管理这个空间,使其可以存文件嘞,
为了方便管理,我们256K 的空间分为64个4K,,我们把一个4K叫做一个Block,那也就是64个Block, block0 -Block 63
第一步,直接写这些4K,这里我们写了3个文件,
File1:12k, File 2: 4K, File: 32k,这里是直接把数据存好,我们可以有很多方式来记录这个信息
这里我们可以记录一个结构体,记录这个文件的名字,以及这些文件存在的位置,这里我们把这个结构体叫做inode
inode0:「File1: 0,1,2,创建时间,长度,权限等信息」
inode1:「File2: 3,创建时间,长度,权限等信息」
inode2:「File 3: 4,5,6,7,创建时间,长度,权限等信息」
当file 2 被删除了,那我们的Block 3 就是空闲了,同时这个inode1也被释放了.所以我们需要一个bitmap 来表示哪些Block 是有效的,哪些inode 是有效的,
那此时我们就有了一个block bit map(来记录每个Block 的状态),和inode bit map(记录inode 的状态)
block bit map 的大小是比较好确定的,跟存储设备的大小成正比,我们这里是256K,每一个BIt 表示一个4K的大小,那我们只需要一个64个bit 就够了
那inode bit map 的大小怎么确定了,一个文件会对应一个inode 结构体,我们不知道会有多少文件,动态的?那太麻烦了,那我们就随便定一个吧,1000个.
到这里我们就有了block,block bit map,inode inode bit map了,
在实际应用中,存储设备的容量很大的好几个TB,那对应的Bitmap 就很大了,我们不可能把这个的数据放在OS 的内存里,所以只能把它写到存储设备里,需要时候再把他读出来,因此此时我们的64个Block 的分布就成了这个样子了.
当我们要读file 1时,我们只需要把inode 0 这个结构体拿到,然后inode 里会记录block 的地址,那就可以读了...
[总结]
这里主要介绍inode 的概念,从ext4 inode 的结构体可以看出,inode 里面有文件的读写权限 i_mode,属于哪个用户 i_uid,哪个组 i_gid,大小是多少 i_size_io,占用多少个块 i_blocks_io。咱们讲 ls 命令行的时候,列出来的权限、用户、大小这些信息,就是从这里面取出来的。
struct ext4_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size_lo; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Inode Change time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks_lo; /* Blocks count */
__le32 i_flags; /* File flags */
......
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl_lo; /* File ACL */
__le32 i_size_high;
......
};