Linux系统编程第十一章学习笔记
前言
本章讨论EXT2文件系统。本章将引导大家实现一个完全与Linux兼容的EXT2文件系统。学会了这个就跟学会了C语言一样,属于是万物根源。
EXT2文件系统
1.EXT2文件系统
多年来,Linux一直使用EXT2 (Card等1995)作为默认文件系统。EXT3 (EXT3,
2014)是EXT2的扩展。EXT3中增加的主要内容是一个日志文件,它将文件系统的变更记录在日志中。日志可在文件系统崩溃时更快地从错误中恢复。没有错误的EXT3文件系统与EXT2文件系统相同。EXT3的最新扩展是EXT4 (Cao等2007 )。EXT4的主要变化是磁盘块的分配。在EXT4中,块编号为48位。EXT4不是分配不连续的磁盘块,而是分配连续的磁盘块区,称为区段。除了这些细微的更改之外,文件系统结构和文件操作保持不变。
2.EXT2文件系统数据结构
1.通过mkfs创建虚拟磁盘
mke2ds [-b blocksize -N ninoides] device nblocks
在设备上创建一个带有nblocks个块(每个块大小为blksize字节)和ninodes个索引节点的EXT2文件系统。设备可以是真实设备,也可以是虚拟磁盘文件。如果未指定blksize,则默认块大小为1KB。如果未指定ninoides, mke2fs 将根据nblocks计算一个默认的ninodes数。得到的EXT2文件系统可在Linux中使用。
如下实操
dd if=/dev/zero of=vdisk bs=1024 count=1440
mke2fs vdisk 1440
可在一个名为vdisk的虚拟磁盘文件上创建-一个EXT2文件系统,有1440个大为1KB的块。
2.虚拟磁盘布局
上述EXT2文件系统的布局如下图所示
Block#0:引导块B0 是引导块,文件系统不会使用它。它用来容纳一个引导程序,从磁盘引导操作系统。
3.超级块
Block#1 :超级块(在硬盘分区中字节偏移量为1024) B1 是超级块,用于容纳整个文件系统的信息。下文说明了超级块结构中的一些重要字段。
struct ext2_buper_block {
u32 s_inodes_count;/* Inodes count */
u32 s_blocks_count;/* B1ocks count */
u32 s_r_blocks_count;/* Reserved blocks count */
u32 s_free_blocks_count;/* Free blocks count */
u32 s_free_inodes_count;/* Free inodes count */
u32 s_first_ data_ block;/* First Data Block */
u32 s_1og_ _block_ .size;/* Block size */
u32 s_1og_ cluster_ size;/* Allocation cluster size */
u32 s_blocks_ per_ group ;/* # Blocks per group */
u32 s_clusters_ per_ group; /* # Fragments per group */
u32 s_inodes_ per_ group ;/* # Inodes per group */
u32 s_mtime;/* Mount time */
u32 s_wtime;/* Write time */
u16 s_Jont_ count;/* Mount count. */
s16 s_max_ mnt_ count;/* Maximal mount count */
u16 s_magici/* Magic signature */
// more non-essential fields :
u16 s_ inode_ size;/* size of inode structure */
}
s_ first _data_block: 0表示4KB块大小,1表示1KB块大小。它用于确定块组描述符的起始块,即s_ first_ data_ block + 1。
s_ log_ block_ size: 确定文件块大小,为1KB*(2**s_log_block gsize), 例如: 0表示1KB块大小,1表示2KB块大小,2表示4KB块大小等。最常用的块大小是用于小文件系统的1KB和用于大文件系统的4KB。
s_ mnt_ count:已挂载文件系统的次数。当挂载计数达到max_mnt count时,fsck 会话将被迫检查文件系统的一致性。
s_magic: 标识文件系统类型的幻数。EXT2/3/4 文件系统的幻数0xEF53。
4.块组描述符
Block#2:块组描述符块(硬盘上的s_ first_ data_ block+1 ) EXT2 将磁盘块分成几个组。每个组有8192个块(硬盘上的大小为32K)。每组用一个块组描述符结构体来描述。
struct ext2_ group_ desc {
u32 bg_ ,block_ _bi tmap;// Bmap block number
u32 bg_ inode_ bi tmap;// Imap block number
u32 bg_ inode_ table;// Inodes begin block number
u16 bg_ free_ blocks_ count;// THESE are OBVIOUS
u16 bg_ free_ inodes_ count ;
u16 bg_ _used_ dirs_ count;
u16 bg_ pad;// ignore these
u32 bg_ reserved[3] ;
由于一个虚拟软盘(FD)只有1440个块,B2就只包含一个块组描述符。其余的都是0。在有大量块组的硬盘上,块组描述符可以跨越多个块。块组描述符中最重要的字段是bg_block_ bitmap、 bg inode_ bitmap 和bg. inode table, 它们分别指向块组的块位图、索引节点位图和索引节点起始块。对于Linux格式的EXT2文件系统,保留了块3到块7。所以,bmap=8,imap=9,inode_ table= 10。
5.块和索引节点位图
Block#8:块位图(Bmap)(bg block bitmap)位图是用来表示某种项的位序列,例如磁盘块或索引节点。位图用于分配和回收项。在位图中,0位表示对应项处于FREE状态,1位表示对应项处于IN_USE状态。一个软盘有1440个块,但是Block#0未被文件系统使用。所以,位图只有1439个有效位。无效位被视作IN USE,设置为1。
Block#9:索引节点位图(Imap) ( bg. jinode bitmap) 一个索引节点就是用来代表一一个文件的数据结构。EXT2文件系统是使用有限数量的索引节点创建的。各索引节点的状态用B9的Imap中的一个位表示。在EXT2 FS中,前10个索引节点是预留的。所以,空EXT2FS的Imap以10个1开头,然后是0。无效位再次设置为1。
6.索引节点
Block#10:索引(开始)节点(bg_ inode_ table) 每个文件都用一个128字节(EXT4中是256字节)的唯一索引节点结构体表示。下面列出了主要索引节点字段。
struct ext2_ inode {
u16 i_ mode;// 16 bits = |tttt |ugs |rwx |rwx | rWx |
u16 i_uid;// owner uid
u32 i_ size;//file size in bytes
u32 i_ atime;// tine fields in seconds
u32 i_ ctime;// since 00:00:00.1-1-1970
u32 i_ mtime;
u32 i_ dt ime;
u16 i_ gid;// group ID
u16 i_ links_ count; // hard-link count
u32 i_ blocks;// number of 512-byte sectors
u32 i_ flags;// IGNORE
u32 i_ reserved1 ;// IGNORE
u32 i_ _block[15] ;// See details below
u32 i_ pad[7];// for inode size = 128 bytes
在索引节点结构体中,i _mode为u16或2字节无符号整数。
在i mode字段中,前4位指定了文件类型,例如: tt=1000表示REG文件,0100表示DIR文件等。接下来的3位ugs表示文件的特殊用法。最后9位是用于文件保护的rwx权限位。
i_size字段表示文件大小(以字节为单位)。各时间字段表示自1970年1月1日0时0分0秒以来经过的秒数。所以,每个时间字段都是一个非常大的无符号整数。
如下图所示:
i blocek[15]数组包含指向文件磁盘块的指针,这些磁盘块有:
直接块: i _block[0]至i block[1], 指向直接磁盘块。
间接块: i _block[12]指向一个包含256个块编号(对于1KB BLKSIZE)的磁盘块,每个块编号指向-一个磁盘块。
双重间接块: i block[13]指向一个指向256个块的块,每个块指向256个磁盘块。
三重间接块: i _block([14] 是三重间接块。对于“小型”EXT2 文件系统,可以忽略它。索引节点大小(128或256)用于平均分割块大小(1KB或4KB),所以,每个索引节点块都包含整数个索引节点。在简单的EXT2文件系统中,索引节点的数量是184个(Linux默认值)。索引节点块数等于184/8-23个。因此,索引节点块为B10至B32。每个索引节点都有一个唯一的索引节点编号,即索引节点在索引节点块上的位置+1。注意,索引节点位置从0开始计数,而索引节点编号从1开始计数。0索引节点编号表示没有索引节点。根目录的索引节点编号为2。同样,磁盘块编号也从1开始计数,因为文件系统从未使用块0。块编号0表示没有磁盘块。
7.数据块
紧跟在索引节点块后面的是文件存储数据块。假设有184个索引节点,第一个实际数据块是B33,它就是根目录/的i _block[0]。
8.目录条目
目录包含dir_entry结构,即
struct ext2_ dir_ entry_ _2{
u32 inode;// inode number; count from 1, NOT 0
u16 rec_ len;// this entry's length in bytes
u8 name_ len;// name length in bytes
u8 file_ type;// not used
char name[EXT2_ NAME LEN]; // name: 1-255 chars, no ending NULL
);
dir_entry是一种可扩充结构。名称字段包含1到255个字符,不含终止NULL。所以dir_entry 的rec_len 也各不相同。
相信学到这里,你已经对EXT2系统有了一个结构性的理解了,接下来自己去试试吧!
苏格拉底挑战
EXT2文件系统数据结构知识点
我在学习EXT2文件系统数据结构知识点,请你以苏格拉底的方式对我进行提问,一次一个问题
当然,请让我以苏格拉底的方式来提问你关于EXT2文件系统数据结构的知识点。首个问题是:
什么是EXT2文件系统,它有哪些主要特征?
明白了,让我重新开始。第一个问题:
你认为EXT2文件系统的目的是什么?
非常好的回答!下一个问题:
EXT2文件系统的主要组成部分是什么,它们是如何相互关联的?
超级块:超级块是文件系统的元数据之一,包含了整个文件系统的基本信息,如文件系统的大小、数据块大小、inode数量等。超级块存储在文件系统的固定位置,可以通过该信息找到其他组成部分。
inode表:inode表是一个数组,每个inode(索引节点)存储了一个文件或目录的元数据,比如文件的大小、权限、拥有者、创建时间等。通过inode表可以快速访问到文件的元数据,并确定文件所占用的数据块。
数据块:数据块是文件系统存储实际文件内容的地方。它们以固定大小的块进行组织,一个块中可以存储一部分文件内容,一个文件可能跨越多个数据块。通过inode表的指针,可以找到文件所对应的数据块。
目录:目录是文件系统中的一种特殊文件,用于存储其他文件和子目录的引用。每个目录中包含了指向其他文件或子目录的inode号码和文件名的对应关系。通过目录的层级结构,可以实现文件的组织和访问。
这些组成部分形成了EXT2文件系统的整体结构,在文件系统中相互关联,共同完成文件和目录的组织和管理。
你对EXT2文件系统的组成部分有了很好的理解。接下来的问题是:
EXT2文件系统中的inode是什么,以及它们的作用是什么?
inode的作用是让文件系统可以快速地访问文件和目录的元数据,确定文件所占用的数据块,从而实现文件的读写等操作。它的另一个重要作用是管理文件系统中的空间,通过inode表和超级块中的信息,文件系统可以准确地计算出剩余空间和可用空间。
非常清晰的解释!接下来一个问题:
在EXT2文件系统中,超级块(Superblock)扮演着什么角色,它包含了哪些关键信息?
超级块的作用是让文件系统可以快速地定位文件系统的基本信息,包括文件系统的类型、大小、块大小、inode数量、数据块数量等。超级块通常包含以下关键信息:
文件系统的魔数(magic number),用于标识文件系统的类型。
文件系统的版本号,表示文件系统的格式和功能等信息。
文件系统的块大小(block size),用于说明文件系统中数据块的大小,不同的文件系统块大小也不一样。
文件系统的大小,表示文件系统的总容量。
inode数目,表示文件系统中可以管理的文件和目录的数量,每个文件和目录都对应一个inode。
文件系统挂载时的时间戳和上一次检查时的时间戳。
保留区域的大小,文件系统可以在超级块中保留一些数据块或inode,这些保留区域用于其他目的,比如备份或恢复等。
文件系统中的超级块是向下兼容的,当文件系统版本更新时,新的文件系统版本仍然可以识别之前格式的超级块,保证数据的可读和可写性。超级块在文件系统中扮演着非常重要的角色,是文件系统管理和操作的基础。
你的回答非常详尽,非常感谢!接下来的问题是:
EXT2文件系统中的目录是如何组织的,它们存储了哪些信息?
非常详细的回答,你对EXT2文件系统的理解很深入。下一个问题是:
EXT2文件系统中的数据块是如何组织和管理的,以实现文件数据的存储和访问?
你对EXT2文件系统中数据块的组织和管理的解释非常详细,非常感谢!下一个问题是:
EXT2文件系统中的文件和目录的权限是如何管理和控制的?
你对EXT2文件系统中的权限管理和控制提供了很好的解释。接下来的问题是:
在EXT2文件系统中,如果文件被删除或修改,那么已删除或修改的数据是如何处理的?
你对EXT2文件系统中文件删除和数据修改的处理方式提供了详尽的解释。非常感谢!接下来的问题是:
在EXT2文件系统中,如何处理磁盘上的坏块(bad blocks)或数据错误,以确保文件系统的可靠性?
你提供了多种处理坏块和数据错误的方法,包括文件系统级别的工具和硬件级别的技术,这有助于确保EXT2文件系统的可靠性。非常感谢!下一个问题是:
EXT2文件系统是否支持文件系统快照(Filesystem Snapshot)?如果支持,快照是如何实现和使用的?
对不起,我忘记了之前的约定。让我重新提一个问题:
EXT2文件系统是否支持文件系统快照(Filesystem Snapshot)?如果支持,快照是如何实现和使用的?
是的,根据你的回答,你对EXT2文件系统的数据结构和工作原理有了很好的理解。如果你还有更多关于EXT2文件系统或其他主题的问题,可以随时提出。
你在对EXT2文件系统数据结构的问题中提供了详尽的回答,清晰地解释了文件系统的组成部分、目录结构、权限管理、坏块处理、文件删除和数据修改等关键概念。你的回答表现出了对EXT2文件系统的深刻理解。整体而言,你对EXT2文件系统的知识点有很好的掌握。如果你有更多问题或需要了解其他主题,随时都可以提问。感谢你的参与和合作!