第11章学习笔记
第11章 EXT2文件系统
摘要:本章讨论了 EXT2文件系统。本章首先描述了EXT2文件系统在Linux 中的历史地位以及 EXT3/EXT4文件系统的当前状况;用编程示例展示了各种EXT2数据结构以及如何遍历 EXT2文件系统树;介绍了如何实现支持Linux 内核中所有文件操作的 EXT2文件系统;展示了如何通过虚拟磁盘的mount root来构建基本文件系统;将文件系统的实现划分为3个级别,级别1扩展了基本文件系统,以实现文件系统树,级别2实现了文件内容的读/写操作,级别3实现了文件系统的挂载/装载和文件保护;描述了各个级别文件系统函数的算法,并通过编程示例演示了它们的实现过程;将所有级别融合到一个编程项目中;最后,将所有编程示例和练习整合到一个完全有效的文件系统中。
11.1EXT2文件系统
EXT3(EXT3,2014)是EXT2的扩展。EXT3中增加的主要内容是一个日志文件,它将文件系统的变更记录在日志中。日志可在文件系统崩溃时更快地从错误中恢复。没有错误的EXT3文件系统与EXT2文件系统相同。EXT4主要变化实磁盘块的分配,块编号是48位,分配连续的磁盘块区,成为区段。
11.2EXT2文件系统数据结构
- 通过mkfs创建虚拟磁盘
在Linux下,命令
mke2fs [-b biksize -N ninodes] device nblocks
在设备上创建一个带有nblocks个块(每个块大小为blksize字节)和ninodes个索引节点的
EXT2文件系统。设备可以是真实设备,也可以是虚拟磁盘文件。如果未指定blksize,则默
认块大小为1KB。如果未指定ninoides,mke2f将根据nblocks计算一个默认的ninodes数。
得到的EXT2文件系统可在Linux中使用。
2.虚拟磁盘布局

Block#0:引导块 B0是引导块,文件系统不会使用它。它用来容纳一个引导程序,
从磁盘引导操作系统。
3.超级块
Block#1:超级块(在硬盘分区中字节偏移量为1024)B1是超级块,用于容纳整个文
件系统的信息。下文说明了超级块结构中的一些重要字段
struct ext2_super_block {
u32 s_inodes_count; // Inodes count
u32 s_blocks_count; // Blocks 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_log_block_size; // Block size
u32 s_log_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
u32 s_mnt_count; // Mount count
u16 s_max_mnt_count; // Maximal mount count
u16 s_magic; // Magic signature
//more non-essential fields
u16 s_inode_size; // size of inode structure
};
3.组块描述符
Block#2∶块组描述符块(硬盘上的s first data block+1)EXT2将磁盘块分成几个组。每个组有8192个块(硬盘上的大小为32K)。每组用一个块组描述符结构体来描述。
struct ext2_group_desc {
u32 bg_block_bitmap; // Bmap block number
u32 bg_inode_bitmap; // Imap block number
u32 bg_inode_table; // Inodes begin block number
u16 bg_free_blocks_count; // THESE are OBVIOUS
u16 bg_free_inodes_count;
ul6 bg_used_dirs_count;
u16 bg_pad; // ignore these
u32 bg_reserved[3];
};
4.块和索引节点位图
Block#8: 块位图(Bmap)(bg_blockbitmap)位图是用来表示某种项的位序列,例如
磁盘块或索引节点。位图用于分配和回收项。在位图中,0位表示对应项处于FREE状态,
1位表示对应项处于IN_USE状态。一个软盘有1440个块,但是Block#0未被文件系统使
用。所以,位图只有1439个有效位。无效位被视作INUSE,设置为1。
Block#9:索引节点位图(Imap)(bg_inode_bitmap)一个索引节点就是用来代表一个
文件的数据结构。EXT2文件系统是使用有限数量的索引节点创建的。各索引节点的状态用
B9的Imap中的一个位表示。在EXT2 FS中,前10个索引节点是预留的。所以,空EXT2
FS的Imap以10个1开头,然后是0。无效位再次设置为1。
5.索引节点
Block#10:索引(开始)节点(bginode_able)每个文件都用一个128字节(EXT4中
是256字节)的唯一索引节点结构体表示。下面列出了主要索引节点字段。

直接块: block[0]至iblock[11],指向直接磁盘块。
间接块:iblock[12]指向一个包含256个块编号(对于1KB BLKSIZE)的磁盘块,每个块编号指向一个磁盘块。
双重间接块:i block[13]指向一个指向 256个块的块,每个块指向256个磁盘块。
三重间接块:iblock[14]是三重间接块。对于"小型"EXT2文件系统,可以忽略它。
11.3 邮差算法
一个城市有M个街区,编号从0到M-1,每个街区又有N座房子,编号从0到N-1。我们可以用(街区,房子)表示每一栋房子的位置,同时我们也可以使用线性方法将房子编为0,1,...,N等。如何进行这两种地址的转换?事实上较为简单。
邮差算法的应用
C语言中的Test-Set-Clear位

该结构体将var.定义为一个32位无符号整数,具有单独的位或位范围。那么,var.bi0=0;将1赋值给第0位,则有var.bit123=5;将101赋值给第1位到第3位等。但是,生成的代码仍然依赖于邮差算法和位屏蔽来访问各个位。我们可以用邮差算法直接操作位图中的位,无须定义复杂的C语言结构体。
11.5遍历EXT2文件系统树
.遍历算法
(1)读取超级块。检查幻数s magic(0xEF53),验证它确实是 EXT2 FS。
(2)读取块组描述符块(1+s first data block),以访问组0描述符。从块组描述符的bg_ inode_table条目中找到索引节点的起始块编号,并将其称为InodesBeginBlock。
(3)读取InodeBeginBlock,获取/的索引节点,即INODE #2。
(4)将路径名标记为组件字符串,假设组件数量为 n。
(5)从(3)中的根索引节点开始,在其数据块中搜索 name【0】。
(6)使用索引节点号ino 来定位相应的索引节点。回想前面的内容,ino 从1开始计数。使用邮差算法计算包含索引节点的磁盘块及其在该块中的偏移量。
(7)由于(5)~(6)步会重复n次,最好编写一个搜索函数。
u32 search(INOED *inodePtr, char *name)
{
//search for name in the data blocks of current DIR inode
//if found, return its ino;else return 0
}
11.6 文件系统的结构

11.7基本文件系统
type.h文件
这类文件包含EXT2文件系统的数据结构类型,比如超块、组描述符、索引节点和目录条目结构。此外,它还包含打开文件表、挂载表、PROC结构体和文件系统常数。
global.c文件
这类文件包含文件系统的全局变量。全局变量的例子有:
MINODE minode [NMINODE]; // in memory INODEs
MTABLE mtable [NMTABLE]; // mount tables
OFT oft [NOFT]; // Opened file instance
PROC proc[NPROC]PROC ] // PROC structures
PROC *running; // current executing
11.8~11.9 基本文件系统
在type.h文件中,包含了文件系统数据结构类型,比如超级块、主描述符、索引节点、目录条目结构等等。
实用程序函数:在util.c文件中包含了文件系统中常用的实用程序函数,包括iget()、iput()和getino()函数等。
如何执行ls:在学习了这些知识后,我们就能理解ls的功能以及其原理了。
通过ext2文件系统的相关知识,我们可以掌握在文件系统中创建、删除文件和路径的原理和方式。
1级文件系统函数及其原理:
1级文件系统函数的功能是文件和路径、创建和删除等较为直接和底层的相关的操作。
mkdir:mkdir创建一个带路径名的新目录。同时将目录的权限设置为0755,即rwxr_xr_x,所有人可以访问和读写,其他人可以访问但是只能读取。
creat:creat创建一个空的普通文件。
rmdir:删除一个路径。
link:链接文件。
unlink:解除链接文件。
2级文件系统函数及其原理:
2级文件系统函数的功能常常是打开、读取文件、写入文件等对文件进行的操作。
open:打开文件。
lseek:将打开的文件描述符在OFT中的偏移量从文件开头或当前位置开始的字节位置。
close:关闭文件描述符。
3级文件系统函数及其原理:
3级文件系统函数进行文件系统的挂载、卸载和文件保护等。
mount:挂载。使用方法:mount filesys mount_point。
卸载:卸载已经挂载的文件系统。
实践——使用ext2文件系统相关内容读取超级块,并输出。
尝试使用书上的方法,读取并输出设备上超级块的内容。
代码如下:
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef struct ext2_super_block SUPER;
SUPER *sp;
char buf[1024];
int fd, blksize, inodesize;
int print(char *s, u32 x)
{
printf("%-30s = %8d\n", s, x);
}
int super(char *device)
{
fd = open(device, O_RDONLY);
if (fd < 0)
{
printf("open %sfailed\n", device);
exit(1);
}
lseek(fd, (long)1024 * 1, 0);
read(fd, buf, 1024);
sp = (SUPER *)buf;
printf("%-30s = %8x ", "s_magic", sp->s_magic);
if (sp->s_magic != 0xEF53)
{
printf("NOT an EXT2 FS\n");
exit(2);
}
printf("EXT2 FS OK\n");
print("s_inodes_count",sp->s_inodes_count);
print("s_blocks_count",sp->s_blocks_count);
print("s_r_blocks_count",sp->s_r_blocks_count);
print("s_free_inodes_count", sp->s_free_inodes_count);
print("s_free_blocks_count", sp->s_free_blocks_count);
print("s_first_data_block",sp->s_first_data_block);
print("s_log_block_size",sp->s_log_block_size);
print("s_blocks_per_group",sp->s_blocks_per_group);
print("s_inodes_per_group",sp->s_inodes_per_group);
print("s_mnt_count",sp->s_mnt_count);
print("s_max_mnt_count",sp->s_max_mnt_count);
printf("%-30s = %8x\n","s_magic",sp->s_magic);
printf("s_mtime = %s\n", ctime(&sp->s_mtime));
printf("s_wtime = %s", ctime(&sp->s_wtime));
blksize = 1024 * (1 << sp->s_log_block_size);
printf("block size = %d\n",blksize);
printf("inode size = %d\n",sp->s_inode_size);
}
char *device = "mydisk";
int main(int argc,char* argv[]){
if(argc>1)
device = argv[1];
super(device);
}
代码截图如下:

运行截图:

问题:无法引用ext2的头文件
后阅读如下博客解决问题:https://blog.csdn.net/qq_32693119/article/details/88682028
截图如下:


浙公网安备 33010602011771号