模拟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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)