硬盘的每一层分多个磁道,每个磁道分多个扇区,每个扇区是512个字节.
inode与块的存储
硬盘分成相同的大小单元,我们称之为块(Block)。一块的大小是扇区大小的整数倍,默认是4K。在格式化的时候,这个值是可以设定的。这样分成一个个小的块,用来存放文件部分。这样一来存储文件就比较灵活。这样会出现一个问题怎么存文件的索引信息、文件的元数据的部分,例如名字、权限,这就需要一个机构来存放inode来存放。
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;
......
};
ls命令行的时候,列出来的权限、用户、大小这些信息,就是从这里面取出来的。
i_atime是最近一次访问文件的时间,只要访问了就会修改
i_ctime是最近一次更改inode的时间,可能只修改了用户和权限
i_mtime,最近一次更改文件的时间,修改了用户和权限,也修改了数据,才会改变
数据是怎么存储的?EXT4_N_BLOCKS有如下定义,计算下了一共15项,i_block[0-11],直接得到保存文件内容的块。如果还是存不下呢?i_bolck[12]会保存一个间接块的地址,以此类推。但也存在一个问题就是大文件的话,需要多次读取硬盘才能找到相应的块,这样的访问速度会比较慢。
ext4引入一个新概念Extents。可以用来存放连续的块,这样对于大文件的读写性能也提升了,文件碎片也减少了。
Extents会保存成一颗树。如果文件不大,inode 里面的 i_block 中,可以放得下一个 ext4_extent_header 和 4 项 ext4_extent。所以这个时候,eh_depth 为 0,也即 inode 里面的就是叶子节点,树高度为 0。
inode位图和块位图
问题:要保存一个数据块,或者要保存一个inode,应该放在硬盘的那个位置?
需要弄一个块,来保存block的位图。
open一个文件很复杂,来看下调用链:do_sys_open->do_filp_open->path_openat->do_last->lookup_open
这个调用链的逻辑是,要打开一个文件,先要根据路径找到文件夹。如果发现文件夹下面没有这个文件,同时又设置了O_CREAT,就说明我们要在这个文件夹下面创建一个文件,那么我们就需要一个新的inode。创建新的inode,就需要调用dir_inode,也就是文件夹inode的create函数。这里面一个重要的逻辑就是,从文件系统里面读取 inode 位图,然后找到下一个为 0 的 inode,就是空闲的 inode。
文件系统的格式
。。。
目录的存储格式
其实目录本身也是个文件,也有 inode。inode 里面也是指向一些块。而目录文件的块里面保存的是目录里面一项一项的文件信息。这些信息我们称为 ext4_dir_entry。每一项都会保存这个目录的下一级的文件的文件名和对应的 inode,通过这个 inode,就能找到真正的文件。如果在 inode 中设置 EXT4_INDEX_FL 标志,则目录文件的块的组织形式将发生变化,变成了下面定义的这个样子。
如果我们要查找一个目录下面的文件名,可以通过名称取哈希。如果哈希能够匹配上,就说明这个文件的信息在相应的块里面。然后打开这个块,如果里面不再是索引,而是索引树的叶子节点的话,那里面还是 ext4_dir_entry_2 的列表,我们只要一项一项找文件名就行。通过索引树,我们可以将一个目录下面的 N 多的文件分散到很多的块里面,可以很快地进行查找。
软链接和硬链接的存储格式
ln -s创建的是软链接,不带-s创建的是硬链接。那么它们有什么区别呢?
所谓的链接,我们可以认为是文件的别名,而链接又分为两种,软链接与硬链接。
硬链接与原始文件共用一个inode,但是inode是不跨文件系统的,每个文件系统都有自己的inode列表,因而硬链接是没有办法跨文件系统的。
软链接不同,相当于重新创建了一个文件,这个文件也有独立的inode,只不过打开这个文件看里面内容的时候,内容指向另外一个文件,这就很灵活了,我们可以跨文件系统,甚至目标文件被删除了,链接文件还是存在的,只不过指向的文件找不到了而已。
总结
在文件系统上的布局就像图的下半部分一样。无论是文件夹还是文件,都有一个 inode。inode 里面会指向数据块,对于文件夹的数据块,里面是一个表,是下一层的文件名和 inode 的对应关系,文件的数据块里面存放的才是真正的数据。