struct unixfilesystem * unixfilesystem_format(int dfd) { uint16_t bootblock[256]; bootblock[0] = BOOTBLOCK_MAGIC_NUM; diskimg_writesector(dfd, BOOTBLOCK_SECTOR, bootblock); struct unixfilesystem *fs = malloc(sizeof(struct unixfilesystem)); if (fs == NULL) { fprintf(stderr,"Out of memory.\n"); return NULL; } fs->dfd = dfd; // 144 inodes in total, so we have 8 blocks // to store inodes, plus 2 start blocks, // we have 10 blocks in use, and we allocate the entire volume 110 blocks // so the rest 100 blocks is file blocks, and all blocks formats to free. fs->superblock.s_isize = 144; fs->superblock.s_fsize = 110; // 110 blocks of entire volume fs->superblock.s_ninode = fs->superblock.s_isize; // at begining, free inodes number = total inodes number int i; // consider s_inode as bitmap for (i = 0;i < 100;i++) fs->superblock.s_inode[i] = 0; fs->superblock.s_nfree = fs->superblock.s_fsize ; // at begining, free blocks number = total blocks number // consider s_free as bitmap for (i = 0;i < 100;i++) fs->superblock.s_free[i] = 0; diskimg_writesector(dfd, SUPERBLOCK_SECTOR, &fs->superblock); int inumber = filsys_allocInode(fs); if (inumber != ROOT_INUMBER) { fprintf(stderr, "ROOT_INUMBER is not 1, format failed\n"); return -1; } struct inode in; inode_iget(fs, inumber, &in); // format the root dir, and set the i_mode field to DIR inode_format(&in); //in.i_mode &= (0xffff - IFMT); in.i_mode |= IFDIR; inode_iwrite(fs, ROOT_INUMBER, &in); fs->workDirInumber = ROOT_INUMBER; strcpy(fs->workDirName, "/"); return fs; }
int remove_file(struct unixfilesystem *fs, int inumber) { struct inode in; int err = inode_iget(fs, inumber, &in); if (err < 0) return -1; if (!(in.i_mode & IALLOC) || ((in.i_mode & IFMT) == IFDIR)) { /* Not allocated or is a directory */ fprintf(stderr, "The input path is not a file and cannot be removed"); return -1; } if (in.i_nlink == 1) // only one link, so overwrite the file { char zeros[DISKIMG_SECTOR_SIZE] = {0}; int size = inode_getsize(&in); int blockNum = 0; // overwrite the file with zeros for (blockNum = 0; blockNum < size / DISKIMG_SECTOR_SIZE; blockNum++) { char buf[DISKIMG_SECTOR_SIZE]; int blockAddress = inode_indexlookup(fs, &in, blockNum); if (blockAddress == -1) { fprintf(stderr, "Error looking up block number %d in inode %d", blockNum, inumber); return -1; } if (diskimg_writesector(fs->dfd, blockAddress, &zeros) == -1) { fprintf(stderr, "Error overwriting file"); return -1; } } } else // multiple links to file, so only remove this link { in.i_nlink--; } return 0; }