⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lab7-0572201-myfs.c

📁 linux下用文件模拟文件系统的各种操作
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <string.h>	#include <stdlib.h>#define SECTOR_SIZE 512#define TOTAL_SECTOR 10240#define MYFS_N_BLOCKS 15#define MYFS_NAME_LEN 128#define MAX_BUF_LEN 256/* FILE SYSTEM STRUCTURE  *//* | super block (1) | group_desc (1)| block bitmap (1) | inode bitmap (1) | inode table (m) | data blocks (n) |  */struct super_block{	unsigned int s_inodes_count; /*inode count */	unsigned int s_blocks_count; /* block count */	unsigned int s_r_blocks_count;   /*Number of reserved blocks i.e., blocks not for data*/	unsigned int  s_first_data_block;  /* first data block */	unsigned int  s_block_size;    /* Here we simply assume block size=s_block_size Bytes, but in real linux, block size=1024*2^s_log_block_size Bytes*/	unsigned short s_inode_size;        /* size of inode structure */};struct group_desc{	unsigned int bg_block_bitmap;      /* block pointer to block bitmap */	unsigned int bg_inode_bitmap;      /* block pointer to inode bitmap */	unsigned int  bg_inode_table;       /* block pointer to the inodes table, i.e. the first inode block*/	unsigned int  bg_free_blocks_count;  /* free block count */	unsigned int  bg_free_inodes_count;  /* free inodes count */};struct inode{		unsigned int i_size;   /* file size in bytes */	unsigned int i_blocks;               /* data block count */	unsigned int i_block[MYFS_N_BLOCKS];  /* block pointer, =15*/	char name[MYFS_NAME_LEN]; /* File Name  LEN=128*/};/*global control structure*/struct super_block sb;struct group_desc gd;/* both mount_disk and unmount_disk have been well implemented */FILE* disk = NULL;/*allocate a new block or inode, return value:	>= 0 if ok	-1 otherwise*/int newblock();	int newinode();/*deallcate a block or inode*/void releaseblock(int iblock);void releaseinode(int inode);/*read from a block, stored it in buff*/void readblock(int iblock, char *buff);/*write buff's content to block, note that the length of buff is blocksize*/void writeblock(int iblock, char *buff);/*write super_block and so on to disk*/void updata();/*judge if the file with name filename exists, if so, return the inode offsetotherwise, return -1*/int exists(char *filename);/*create a file index node structure*/struct inode *createfile(char *filename);/*allocate a block for a file, note that is may change the index structure*/int createblock(struct inode *pinode);/*append the content of buff to a file*/int appendfile(struct inode *pinode, char *buff);/*close a file*/void closefile(struct inode *pinode);/*recursively copy the index tree rooted by root to file fout,it can deal with any depth indirect index	root:		the root of the index block(may be a leaf block)	h:			the high of the index tree	count:	the bytes to be copied	fout:		destination file*/void copyblocks(int root, int h, int count, FILE *fout);/*opposed to copyblocks*/void removeblocks(int root, int h, int blockcount);int power(int x, int n) {	int half;	if (n <= 0) {		return 1;	}	if (n % 2 == 0) {		half = power(x, n / 2);		return half * half;	}	else {		return x * power(x, n - 1);	}}/* init the disk */int mount_disk(void){	char dump[SECTOR_SIZE] = {0}; 	int count=0;	while (disk == NULL && count < 4)	{		disk = fopen("metafiledisk.dat", "r+b");		count++;		if (disk == NULL)  /* not existing, create one */		{			int i;			disk = fopen("metafiledisk.dat", "wb");			if (disk == NULL)				return 0;			for (i=0; i<TOTAL_SECTOR; i++)				fwrite(dump, SECTOR_SIZE, sizeof(char), disk);			fclose(disk);			disk = NULL;		}		else {			fseek(disk, 0, 0);			fread(&sb, sizeof(sb), 1, disk);			fseek(disk, sb.s_block_size, 0);			fread(&gd, sizeof(gd), 1, disk);		}	}	return (int)disk;}/*write super_block and so on to disk*/void update(void) {	fseek(disk, 0, 0);	fwrite(&sb, sizeof(sb), 1, disk);	fseek(disk, sb.s_block_size, 0);	fwrite(&gd, sizeof(gd), 1, disk);}void unmount_disk(void){	fclose(disk);}/*------------Revise the following code-----------------*/int myinitfs(unsigned int block_size, unsigned int maxfilecount){	char dump[SECTOR_SIZE] = {0}; 	int i;	if (block_size * 8 < maxfilecount) {		printf("maxfilecount shoulde be less than block_size*8!\n");		return 0;	}	printf("\ninit file system will destroy all files on disk!\n");	/*	NOTE: maxfilecount shoulde be less than block_size*8	*/	/*initialize the disk to 0*/	fseek(disk, 0, 0);	for (i = 0; i < TOTAL_SECTOR; i++) {		fwrite(dump, 1, SECTOR_SIZE, disk);	}	/*	disk structure:	super block (1) 	group_desc(1)	block bitmap (1) 	 inode bitmap (1) 	 inode table (m) 	 data blocks (n) 	*/	sb.s_block_size = block_size;	sb.s_blocks_count = SECTOR_SIZE *	TOTAL_SECTOR / block_size;	sb.s_first_data_block = 4 + (sizeof(struct inode) + block_size - 1)/ block_size;	sb.s_inode_size = sizeof(struct inode);	sb.s_inodes_count = maxfilecount;	sb.s_r_blocks_count = 4 + (sizeof(struct inode) + block_size - 1)/ block_size;	gd.bg_block_bitmap = 2;	gd.bg_free_blocks_count = sb.s_blocks_count - sb.s_first_data_block;	gd.bg_free_inodes_count = maxfilecount;	gd.bg_inode_bitmap = 3;	gd.bg_inode_table = 4;	update();	for (i = 0; i < sb.s_first_data_block; i++) {		newblock();	}	return 1;};/* you may implement a write_disk() function for both mycpin() and mytouch()and read_disk() function for mydisplay() and mycpout() */void readblock(int iblock, char *buff) {	fseek(disk, sb.s_block_size * iblock, 0);	fread(buff, 1, sb.s_block_size, disk);}void writeblock(int iblock, char *buff) {	fseek(disk, sb.s_block_size * iblock, 0);	fwrite(buff, 1, sb.s_block_size, disk);}void readinode(int inode, struct inode *pinode) {	fseek(disk, sb.s_block_size * gd.bg_inode_table + sb.s_inode_size * inode, 0);	fread(pinode, 1, sb.s_inode_size, disk);}void writeinode(int inode, struct inode *pinode) {	fseek(disk, sb.s_block_size * gd.bg_inode_table + sb.s_inode_size * inode, 0);	fwrite(pinode, sb.s_inode_size, 1, disk);}int exists(char *filename) {	int ibyte;	int ibit;	int iinode;	int cur;	struct inode in;	char ch;	fseek(disk, gd.bg_inode_bitmap * sb.s_block_size, 0);	for (ibyte = 0; ibyte < sb.s_block_size; ibyte++) {		ch = fgetc(disk);		for (ibit = 0; ibit < 8; ibit++) {			if ( (ch >> ibit) & 1) {				iinode = ibyte * 8 + ibit;				cur = ftell(disk);				fseek(disk, gd.bg_inode_table * sb.s_block_size + iinode * sb.s_inode_size, 0);				fread(&in, sb.s_inode_size, 1, disk);				if (strcmp(in.name, filename) == 0) return ibyte * 8 + ibit;				fseek(disk, cur, 0);			}		}	}	return -1;}struct inode *createfile(char *filename) {	 int iinode;	int i;	struct inode * pinode;	if (exists(filename) >= 0) {		return 0;	}	iinode = newinode();	if (iinode < 0) return 0;	pinode = (struct inode*)malloc(sizeof(struct inode));	if (pinode == 0) {		return 0;	}	strncpy(pinode->name, filename, sizeof(pinode->name));	pinode->i_size = 0;	pinode->i_blocks = 0;	for (i = 0; i < MYFS_N_BLOCKS; i++) {		pinode->i_block[i] = -1;	}	writeinode(iinode, pinode);	return pinode;}int newinode() {	char ch;	int ibyte = 0;	int ibit = 0;	if (sb.s_blocks_count <= 0) return -1;	if (sb.s_inodes_count <= 0) return -1;	fseek(disk, sb.s_block_size * gd.bg_inode_bitmap, 0);	while ( (ch = fgetc(disk)) == -1) ibyte++;	if (ibyte > sb.s_block_size * 8) return -1;	while (ch == (ch | (1 << ibit))) ibit++;	ch |= 1 << ibit;	fseek(disk, -1, 1);	fputc(ch, disk);	sb.s_inodes_count--;	update();	return ibyte * 8 + ibit;}void releaseinode(int inode) {	int ibyte = inode / 8;	int ibit = inode % 8;	char ch;	fseek(disk, sb.s_block_size * gd.bg_inode_bitmap + ibyte, 0);	ch = fgetc(disk);	ch &= ~(1 << ibit);	fseek(disk, -1, 1);	fputc(ch, disk);	sb.s_inodes_count++;	update();}int newblock() {	char ch;	int ibyte = 0;	int ibit = 0;	if (sb.s_blocks_count <= 0) return -1;	fseek(disk, sb.s_block_size * gd.bg_block_bitmap, 0);	while ( (ch = fgetc(disk)) == -1) ibyte++;	if (ibyte > sb.s_block_size * 8) return -1;	while (ch == (ch | (1 << ibit))) ibit++;	ch |= 1 << ibit;	fseek(disk, -1, 1);	fputc(ch, disk);	sb.s_blocks_count--;	update();	return ibyte * 8 + ibit;}void releaseblock(int iblock) {	int ibyte = iblock / 8;	int ibit = iblock % 8;	char ch;	fseek(disk, sb.s_block_size * gd.bg_block_bitmap + ibyte, 0);	ch = fgetc(disk);	ch &= ~(1 << ibit);	fseek(disk, -1, 0);	fputc(ch, disk);	sb.s_blocks_count++;	update();}int createblock(struct inode *pinode) {	int blocks = pinode->i_blocks;	int b = sb.s_block_size / 4;	int index = 11;	int offset = 0;	int h = 0;	int i = 0;	int parent;	int powerb = b;	int in = 0;	int newstart = h - 1;	int *intbuff = (int*)malloc(sb.s_block_size);	int nblock;	if (blocks < 12) {		nblock = newblock();		free(intbuff);		if (nblock < 0) return -1;		pinode->i_block[pinode->i_blocks++] = nblock;		return nblock;	}	blocks -= 12;	powerb = b;	while (blocks >= 0) {		offset = blocks;		blocks -= powerb;		powerb *= b;		index++;		h++;	}	parent = pinode->i_block[index];	if (parent < 0) {		parent = newblock();		if (parent < 0) {			free(intbuff);			return -1;		}		pinode->i_block[index] = parent;	}	powerb = b;	newstart = h - 1;	while (newstart > 0 && offset / powerb * b == offset / (powerb / b)) {		newstart--;		powerb *= b;	}	powerb = power(b, h - 1);	for (i = 0; i < newstart; i++) {		in = (offset / powerb) % b;		readblock(parent, (char*)intbuff);		parent = intbuff[in];		powerb /= b;	}	for (; i <= h - 1; i++) {		in = (offset / powerb) % b;		readblock(parent, (char*)intbuff);		intbuff[in] = newblock();		if (intbuff[in] < 0) {			free(intbuff);			return 0;		}		writeblock(parent, (char*)intbuff);		parent = intbuff[in];		powerb /= b;	}	free(intbuff);	pinode->i_blocks++;	return parent;}int appendfile(struct inode *pinode, char *buff) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -