Content #
inode数据结构
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;
......
};
i_atime 是 access time,是最近一次访问文件的时间; i_ctime 是 change time,是最近一次更改 inode 的时间; i_mtime 是 modify time,是最近一次更改文件的时间。
访问了,不代表修改了,也可能只是打开看看,就会改变 access time。修改 inode,有可能修改的是用户和权限,没有修改数据部分,就会改变 change time。只有数据也修改了,才改变 modify time。
EXT4_N_BLOCKS 有如下的定义,计算下来一共有 15 项。
#define EXT4_NDIR_BLOCKS 12
#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#define EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1)
#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1)
在 ext2 和 ext3 中,其中前 12 项直接保存了块的位置,可以通过 i_block[0-11],直接得到保存文件内容的块。
如果一个文件比较大,12 块放不下,就不能直接放数据块的位置了。可以让 i_block[12]指向一个块,这个块里面不放数据块,而是放数据块的位置,这个块我们称为间接块。
如果文件再大一些,i_block[13]会指向一个块,我们可以用二次间接块。二次间接块里面存放了间接块的位置,间接块里面存放了数据块的位置,数据块里面存放的是真正的数据。如果文件再大一些,i_block[14]会指向三次间接块。原理和上面都是一样的,就像一层套一层的俄罗斯套娃,一层一层打开,才能拿到最中心的数据块。
-
SIB (Single Indirect Block) 是单级间接块。每个 ext3 索引节点有 12 个直接块指针,可以直接指向数据块。如果文件的数据块超过了直接块能够容纳的数量,就需要利用 SIB 来指向更多的数据块。
-
DIB (Double Indirect Block) 是双级间接块。在 SIB 无法容纳所有数据块的情况下,DIB 会被使用。DIB 包含多个指针,每个指针指向一个 SIB,而每个 SIB 可以指向多个数据块。
-
TIB (Triple Indirect Block) 是三级间接块。当 SIB 和 DIB 都无法容纳所有的数据块时,TIB 会被使用。TIB 包含多个指针,每个指针指向一个 DIB,而每个 DIB 可以指向多个 SIB,每个 SIB 可以指向多个数据块。
通过这种嵌套的间接块结构,ext3 文件系统能够处理大型文件,可以指向大量的数据块。