Linux硬盘文件系统

硬盘的每一层分多个磁道,每个磁道分多个扇区,每个扇区是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 的对应关系,文件的数据块里面存放的才是真正的数据。

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107483620
今日推荐