模拟linux的文件系统
linux模拟文件系统还是比较复杂的,这里是参考了许多资料写出来基于ext2的文件系统,大概说一下实现流程,想看更多细节请访问我的github查看。
1.文件系统的数据结构
主要是要设计好超级块、组描述符、inode节点、文件的数据结构,并要计算好大小,填充好空余。
以超级块为例:(其他代码请查看github)
//超级块的数据结构
struct SuperBlock {
char fs_name[10]; //文件系统的名称 10B
unsigned short fs_id; //文件系统标识号 2B
unsigned short first_block; //第一个数据块的位置为0/1,取决于数据块的大小是不是1K 2B
unsigned int datablock_size; //一个数据块的大小,为2的幂次方 4B
unsigned int inode_size; //inode节点的大小 4B
unsigned int groupblock_size; //块组大小,即每个块组有多少个块 4B
unsigned int block_count; //文件系统总块的数量 4B
unsigned int inode_count; //文件系统inode的数量 4B
unsigned int free_block_count; //文件系统空闲块的数量 4B
unsigned int free_inode_count; //文件系统中空闲inode的数量 4B
char padding[982]; //填充项,将超级块填满为1个块的大小 982B
};
2.准备好文件系统需要的基本函数,和一些全局变量
全局变量比较重要的有:
static struct SuperBlock super_block[1]; //超级块
static struct GroupDesc gdt[1]; //组描述符
static struct Inode inode[1]; //inode
static unsigned char blockbitmap_buffer[BLOCK_SIZE] = { 0 };//块位图
static unsigned char inodebitmap_buffer[BLOCK_SIZE] = { 0 }; //inode位图
static struct File dir[32]; // 文件/目录缓冲区
static char buffer[BLOCK_SIZE]; //数据块缓冲区
static FILE* fp; // 模拟磁盘指针
static char current_dir_name[64];
我这里需要的基本函数比较重要的有:
static void write_SuperBlock(); //将超级块信息写回模拟磁盘
static void read_SuperBlock(); //从模拟磁盘中读入超级块
static void write_gdt(void); //将gdt写回模拟磁盘
static void read_gdt(void); //加载gdt到缓存
static void write_inode(unsigned short i); //写回inode表到模拟磁盘
static void read_inode(unsigned short i); //从模拟磁盘加载inode表
static void write_blockbitmap(void); //写回inode表到模拟磁盘
static void read_blockbitmap(void); //从模拟磁盘加载块位图
static void write_inodebitmap(void); //写回inodebitmap表到模拟磁盘
static void read_inodebitmap(void); //从模拟磁盘加载inodebitmap
static void write_dir(unsigned short i);//写回dir到模拟磁盘
static void read_dir(unsigned short i);//从模拟磁盘加载目录
static void write_block(unsigned short i);//写回数据块到模拟磁盘
static void read_block(unsigned short i);//从模拟磁盘加载数据块
static unsigned int get_free_block(); //分配得到一个空闲的数据块
static unsigned int get_free_inode(); //分配得到一个空闲的inode
3.准备好需要实现的高级函数
因为我们只要求读出超级块,所以只写了一些写超级块的函数,如果有别的需要的话请自行实现。
void ShowSuperBlock() {
read_SuperBlock();
printf("element\t\t\t\t\tvalue\n");
printf("filename:\t\t\t%s\n", super_block[0].fs_name);
printf("filesystem id\t\t\t\t%d\n", super_block[0].fs_id);
printf("block size:\t\t\t\t%d\n", super_block[0].datablock_size);
printf("inode size:\t\t\t\t%d\n", super_block[0].inode_size);
printf("group size:\t\t\t\t%d\n", super_block[0].groupblock_size);
printf("all blocks count:\t\t\t%d\n", super_block[0].block_count);
printf("all inodes count:\t\t\t%d\n", super_block[0].inode_count);
printf("free block count:\t\t\t%d\n", super_block[0].free_block_count);
printf("free inode count:\t\t\t%d\n", super_block[0].free_inode_count);
}
本文来自博客园,作者:CinqueOrigin,转载请注明原文链接:https://www.cnblogs.com/CinqueOrigin/p/15754765.html

浙公网安备 33010602011771号