【linux学习指南】Ext系列文件系统(二)引⼊⽂件系统“块“分区inode概念
文章目录
- 📝引⼊"块"概念
- 🌠引⼊"分区"概念
- 🌉 引⼊"inode"概念
- 🚩总结
📝引⼊"块"概念
其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个”块”(block)。
硬盘的每个分区是被划分为⼀个个的”块”。⼀个”块”的⼤⼩是由格式化的时候确定的,并且不可以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个”块”。”块”是⽂件存取的最⼩单位。
注意:
- 磁盘就是一个三维数组,我们把它看待成为一个"一维数组",数组下标就是LBA,每个元素都是扇区
- 每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也能算出来。
- 知道LBA:块号=LBA/8
- 知道块号:LAB=块号*8+n.(n是块内第几个扇区)
🌠引⼊"分区"概念
其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有⼀块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的⼀种格式化。但是Linux的设备都是以⽂件形式存在,那是怎么分区的呢?
柱⾯是分区的最⼩单位,我们可以利⽤参考柱⾯号码的⽅式来进⾏分区,其本质就是设置每个区的起始柱⾯和结束柱⾯号码。此时我们可以将硬盘上的柱⾯(分区)进⾏平铺,将其想象成⼀个⼤的平⾯,如下图所⽰:
注意:
- 柱⾯⼤⼩⼀致,扇区个位⼀致,那么其实只要知道每个分区的起始和结束柱⾯号,知道每⼀个柱⾯多少个扇区,那么该分区多⼤,其实和解释LBA是多少也就清楚了.
🌉 引⼊"inode"概念
之前我们说过文件=数据+属性,我们使用ls -l的时候看到的除了看到文件名,还能看到文件元数据(属性)。
[root@localhost linux]# ls -l
总用量12
-rwxr-xr-x. 1 root root 7438 "12月31 14:56" a.out
-rw-r--r--. 1 root root 654 "12月31 14:56" test.c
每⾏包含7列:
- 模式
- 硬链接数
- 文件所有者
- 组
- 大小
- 最后修改时间
- 文件名
ls-l读取存储在磁盘上的⽂件信息,然后显⽰出来
其实这个信息除了通过这种⽅式来读取,还有⼀个stat命令能够看到更多信息
wks@hcss-ecs-ab43:~/code/signal23$ stat sig.c
File: sig.c
Size: 914 Blocks: 8 IO Block: 4096 regular file
Device: fc01h/64513d Inode: 408125 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ wks) Gid: ( 1000/ wks)
Access: 2024-12-30 23:00:52.279144447 +0800
Modify: 2024-12-30 23:00:17.386385482 +0800
Change: 2024-12-30 23:00:17.386385482 +0800
Birth: 2024-12-29 17:34:47.804387835 +0800
到这我们要思考⼀个问题,⽂件数据都储存在”块”中,那么很显然,我们还必须找到⼀个地⽅储存⽂件的元信息(属性信息),⽐如⽂件的创建者、⽂件的创建⽇期、⽂件的⼤⼩等等。这种储存⽂件元信息的区域就叫做inode,中⽂译名为”索引节点”。
每⼀个⽂件都有对应的inode,⾥⾯包含了与该⽂件有关的⼀些信息。为了能解释清楚inode,我们需
要是深⼊了解⼀下⽂件系统。
注意:
- Linux下⽂件的存储是属性和内容分离存储的
- Linux下,保存⽂件属性的集合叫做inode,⼀个⽂件,⼀个inode,inode内有⼀个唯⼀的标识符,叫做inode号
所以⼀个⽂件的属性inode⻓什么样⼦呢?
/*
* Structure of an inode on the disk
*/
struct ext2_inode
{
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Creation 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; /* Blocks count */
__le32 i_flags; /* File flags */
union
{
struct
{
__le32 l_i_reserved1;
} linux1;
struct
{
__le32 h_i_translator;
} hurd1;
struct
{
__le32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__le32 i_block[EXT2_N_BLOCKS]; /* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl; /* File ACL */
__le32 i_dir_acl; /* Directory ACL */
__le32 i_faddr; /* Fragment address */
union
{
struct
{
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct
{
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__le16 h_i_mode_high;
__le16 h_i_uid_high;
__le16 h_i_gid_high;
__le32 h_i_author;
} hurd2;
struct
{
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
备注:
EXT2_N_BLOCKS = 15
再次注意:
- ⽂件名属性并未纳⼊到inode数据结构内部
- inode的⼤⼩⼀般是128字节或者256,我们后⾯统⼀128字节
- 任何⽂件的内容⼤⼩可以不同,但是属性⼤⼩⼀定是相同的
到⽬前为⽌,相信⼤家还有两个问题:
- 我们已经知道硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,读取的基本单位是”块”。“块”⼜是硬盘的每个分区下的结构,难道“块”是随意的在分区上排布的吗?那要怎么找到“块”呢?
- 还有就是上⾯提到的存储⽂件属性的inode,⼜是如何放置的呢?
⽂件系统就是为了组织管理这些的!
在Ext系列文件系统中块的组织和查找
- 块的组织
- 在Ext文件系统中,块不是随意排布的。分区被划分为多个块组(Block Group)。每个块组都有自己的结构,包括超级块(Superblock)副本、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)和数据块(Data Blocks)等部分。
- 数据块用于存储文件的数据内容。块的大小是在文件系统创建时确定的,常见的块大小有1KB、2KB、4KB等。
- 块的查找
- 当需要查找一个文件的数据块时,首先要通过文件的inode来获取相关信息。inode中存储了文件的数据块指针。
- 对于小文件,可能直接使用inode中的直接指针来定位数据块。这些直接指针可以直接指向文件的数据块。
- 对于较大的文件,当直接指针用完后,会使用间接指针。例如,一级间接指针会指向一个块,这个块中存储的是其他数据块的地址;如果文件更大,还可能会用到二级间接指针,即一级间接块中存储的部分地址指向的块中存储的还是数据块的地址,以此类推。
- 块位图用于记录每个块的使用状态。如果块位图中的某一位为1,表示对应的块已经被使用;为0则表示块未被使用。通过查询块位图,可以找到空闲的块来存储新的数据。
- Ext系列文件系统中inode的放置
- 在Ext文件系统中,inode存储在inode表中。每个块组都有自己的inode表。
- inode表的大小(即包含的inode数量)在文件系统创建时根据分区大小和其他参数确定。
- 每个inode都有一个唯一的编号(inode number)。当文件系统需要访问一个文件的属性(通过inode来访问)时,首先会根据文件所在的目录信息(目录项中包含文件名和对应的inode编号)找到文件的inode编号。
- 然后通过inode编号在inode表中定位对应的inode。inode中存储了文件的各种属性信息,如文件的类型(普通文件、目录、符号链接等)、文件的访问权限、文件的大小、文件的创建时间、修改时间、访问时间以及最重要的文件数据块指针。
- inode位图用于记录inode的使用状态。与块位图类似,inode位图中的某一位为1表示对应的inode已经被使用,为0表示未被使用。在创建新文件时,文件系统会查找inode位图中为0的位,找到空闲的inode来存储文件的属性信息。