在文件系统中提取超级块(即如果我的 sda 存储是 ext2 格式)很容易。我只需要跳过 1024 字节即可获取 sda 存储的超级块
lseek(fd, 1024, SEEK_SET);
read(fd, &super_block, sizeof(super_block));
并且提取组描述符也非常容易(前提是我通过查看代码正确理解了)
lseek(fd, 1024 + [block_size_ext_1024_bytes]=1024, SEEK_SET);
read(fd, &block_group, sizeof(block_group));
or
lseek(fd, 1024 + 1024, SEEK_SET);
read(fd, &block_group, sizeof(block_group));
1024=基础偏移量
但是我感到不放心,因为我发现真正的挑战是拉取索引节点只有我有文件名。我知道文件名存储在目录结构中,因此第一个挑战是从那里提取目录结构,并且在目录结构中我可以获取索引节点号。从索引节点号中我可以提取索引节点结构。如何提取 ext2 格式图像中的目录结构?
是的,拉动超级块只需在 ext2 中跳过 Base_Offset=1024 字节,然后像这样读取它即可
lseek(fd, BASE_OFFSET + block_size, SEEK_SET);
//BASE_OFFSET for EXT2 == 1024
read(fd, &super_block, sizeof(super_block));
block_size = 1024 << super_block.s_log_block_size;
printf("Block size is [%d]\n",super_block.s_log_block_size);
超级块的大小由 s_log_block_size 给出。该值将块的大小表示为2的幂,以1024(特别是ext2)字节为单位。因此,0 表示 1024 字节块,1 表示 2048 字节块,依此类推。要计算块的大小(以字节为单位):
unsigned int block_size = 1024 << super.s_log_block_size; /* block
如果需要硬编码 1024,super.s_log_block_size 始终为 0,并且 super.s_log_block_size 是 2 的倍数,因此如果 1024 块大小 super.s_log_block_size 应该为 0
然后我可以提取组描述符。所以对于我的图像来说只有一个组描述符。我不知道如果我有 1TB 存储空间,我会有多少个描述符,因为我有这个存储空间,并且文件系统是 ext4。也许有人会告诉我这个。
这样进一步向前移动1024字节来提取组描述符
lseek(fd, BASE_OFFSET + block_size, SEEK_SET);
read(fd, &block_group, sizeof(block_group));
我认为这给出了找出 ext2 存储中有多少组描述符的想法
unsigned int group_count = 1 + (super_block.s_blocks_count-1) / super_block.s_blocks_per_group;
例如,在我的设备映像上,它有 128 个块,因此第一个块总是引导信息,第二个块包含超级块,第三个块包含第一个组描述符 - 仍然想知道如果我我的第二个组描述符的偏移量是多少我的存储空间有更多。请有人阐明这一点
继续,要提取特定的索引节点,公式是寻找特定索引节点的偏移量
lseek(fd, BLOCK_OFFSET(block_group->bg_inode_table)+(inode_no-1)*sizeof(struct ext2_inode), SEEK_SET);
bg_inode_table可用于提取inode
组描述符通过 bg_block_bitmap、bg_inode_bitmap 和 bg_inode_table 字段告诉我们块/[inode 位图]和 inode 表(稍后描述)的位置。
现在提取根 inode=(应该是 ino_num=2)例如我只需要做
lseek(fd, BLOCK_OFFSET(block_group->bg_inode_table)+(2-1)*sizeof(struct ext2_inode),
SEEK_SET);
inode 表的第一个块的块号存储在组描述符的 bg_inode_table 字段中。
所以索引节点表可以帮助查找特定的索引节点
要提取目录结构,我只需要使用 inode.i_block[0] 数组。填写最后一步
每个 i_block 元素都是可以这种方式使用的数字。基本上是一个指针指向包含带有 inode 的文件内容的实际块
lseek(...BASE_OFFSET+(i_block[x]-1)*block_size...)
ext2 的 block_size 始终为 1024
这样我就可以读取 ext2 文件系统中包含目录结构的块
阅读
void *block;
read(fd, block, block_size);
上面的行给了我映射到特定 inode 的第一个目录
我可以简单地做一个循环来获取所有条目
http://www.science.smith.edu/~nhowe/teaching/csc262/oldlabs/ext2.html