《信息安全系统设计与实现》第六周学习笔记
一、课程内容第十一章学习
EXT2文件数据结构
1、通过mkfs创建虚拟磁盘
mke2fs [-b blksize -N ninodes] device nblocks
2、虚拟磁盘布局:
其中Block#0:引导块,B0的引导块,不会被系统使用
3、超级块
·超级块是文件系统的核心数据结构之一,存储了文件系统的整体信息。
·超级块包含文件系统的大小、inode的数量、块的数量等重要信息。
·超级块保存在文件系统的固定位置,以便在文件系统挂载时被读取。
Block#1容纳整个文件系统的信息,是超级块的重要字段:
u32 s_inodes_count://文件系统中节点总数
u32 s_blocks_count://文件系统中块总数
u32 s_r_blocks_count://为超级用户保留的块数
u32 s_free_blocks_count: //文件系统中空闲块总数
u32 s_mtime://文件系统的挂接时间
u32 s_wtime://最后一次对该超级块进行写操作的时间
u32 s_magic ://魔数签名,用于确定文件系统版本的标志
u32 s_inodes_per_group://表示每个组块的inode数目,查找文件inode所在块的位置很重要
u32 s_mnt_count://文件系统挂接计数
u32 s_max_mnt_count://文件系统最大挂接计数
u32 s_state://文件系统的状态
4、块组描述符块
Block#2:块组描述符块(硬盘上的s first data block+1)
EXT2将磁盘块分成几个组每个组有8192个块(硬盘上的大小为32K)。每组用一个块组描述符结构体来描述。
5、其他块和索引节点位图
Block#8:块位图(Bmap)(bg block bitmap) 位图是用来表示某种项的位序列,例如磁盘块或索引节点。位图用于分配和回收项。在位图中,0位表示对应项处于FREE 状态1位表示对应项处于IN USE状态。一个软盘有1440个块但是Block#0未被文件系统使用。所以,位图只有1439 个有效位。无效位被视作IN USE,设置为1。
Block#9:索引节点位图(lmap)(bg_inode bitmap) 一个索引节点就是用来代表一个文件的数据结构。EXT2文件系统是使用有限数量的索引节点创建的。各索引节点的状态用B9的Imap中的一个位表示。在EXT2FS中前10个索引节点是预留的。所以,空EXT2FS的Imap以10个1开头,然后是0。无效位再次设置为1。
Block#10:索引(开始)节点(bg_inode_table)每个文件都用一个128字节(EXT4中是256字节)的唯一索引节点结构体表示。下面列出了主要索引节点字段。
邮差算法
Linear_address LA = N*block + house;
Block_address BA = (LA/N,LA%N);
EXT2文件结构
2级文件系统
实现了文件内容的读/写操作。它由以下函数组成:open、close、lseek、read、write、opendir 和 readdir。
3级文件系统函数
1 挂载算法
mount filesys mount_point
可将某个文件系统挂载到mount_point目录上
2、卸载算法
交叉挂载点
向下遍历
向上遍历
文件保护
9个权限位
3|文件系统项目拓展
多个组-4KB大小块-管道文件-I/O缓冲
三、代码实践
编译项目:编写superblock.c程序显示EXT2文件系统的超级块信息
1、利用命令sudo apt-get install e2fslibs-dev e2fslibs-dev安装开发包
2、检查挂载文件系统
3、编写代码并编译使用
代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ext2fs/ext2_fs.h>
typedef unsigned char u8;
typedef struct ext2_super_block SUPER;
typedef struct ext2_group_desc GD;
#define BLKSIZE 1024
SUPER *sp;
GD *gp;
char buf[BLKSIZE];
int fd;
// get_block() reads a disk block into a buf[]?
int get_block(int fd, int blk, char *buf)
{
lseek(fd, (long)blk*BLKSIZE, SEEK_SET);
return read(fd, buf, BLKSIZE);
}
void print_imap(char *device)
{
int i, ninodes, imapblk;
fd = open(device, O_RDONLY);
if (fd < 0)
{
printf("open %s failed\n", device);
exit(1);
}
get_block(fd, 1, buf); // get superblock
sp = (SUPER *)buf;
// check magic number to ensure it's an EXT2 FS
if (sp->s_magic != EXT2_SUPER_MAGIC)
{
printf("Not an EXT2 FS\n");
close(fd);
exit(1);
}
ninodes = sp->s_inodes_count;
printf("ninodes = %d\n", ninodes);
get_block(fd, 2, buf);
gp = (GD *)buf;
imapblk = gp->bg_inode_bitmap;
printf("imapblk = %d\n", imapblk);
get_block(fd, imapblk, buf);
for (i = 0; i <= ninodes / 8; i++)
{
printf("%02x ", (u8)buf[i]);
}
printf("\n");
close(fd);
}
char *dev = "mydisk";
int main(int argc, char* argv[])
{
if (argc > 1)
{
dev = argv[1];
}
print_imap(dev);
return 0;
}
四、苏格拉底问答
五、其他
代码中遇到的问题
1、文件系统建立
首先,建立一个新的文件系统时
2、文件系统的挂载
代码中使用的知识点
文件描述符和文件操作:通过 open() 函数打开文件并获得一个文件描述符,通过 close() 函数关闭文件。使用 lseek() 函数设置文件偏移量,使用 read() 函数读取文件内容。
EXT2 文件系统结构:代码使用 ext2_fs.h 头文件来解析 EXT2 文件系统的超级块和组描述符
数据块和磁盘块:代码使用 BLKSIZE 定义表示一个数据块的大小。get_block() 函数用于从磁盘读取一个指定块号的数据块。
超级块:通过读取磁盘上的超级块,代码获取了一些关于 EXT2 文件系统的信息,如 inode 总数和魔数。
组描述符:通过读取磁盘上的组描述符块,代码获取了 inode 位图块号。
inode 位图:代码读取了 inode 位图块,并将其内容以十六进制格式打印出来。inode 位图标识了文件系统中每个 inode 的使用情况。