<----my github

模拟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);
}
posted @ 2022-01-09 16:23  CinqueOrigin  阅读(431)  评论(0)    收藏  举报