📄 lab7-0572201-myfs.c
字号:
#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 + -