Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int remove_inode(int type, int parent_inode, int child_inode)
- {
- dprintf("... remove inode %d\n", child_inode);
- // load the disk sector containing the child inode
- int inode_sector = INODE_TABLE_START_SECTOR+child_inode/INODES_PER_SECTOR;
- char inode_buffer[SECTOR_SIZE];
- if(Disk_Read(inode_sector, inode_buffer) < 0) return -1;
- dprintf("... load inode table for child inode from disk sector %d\n", inode_sector);
- // get the child inode
- int inode_start_entry = (inode_sector-INODE_TABLE_START_SECTOR)*INODES_PER_SECTOR;
- int offset = child_inode-inode_start_entry;
- assert(0 <= offset && offset < INODES_PER_SECTOR);
- inode_t* child = (inode_t*)(inode_buffer+offset*sizeof(inode_t));
- // check for right type
- if(child->type!=type){
- dprintf("... error: the type parameter does not match the actual inode type\n");
- return -3;
- }
- // check if child is non-empty directory
- if(child->type==1 && child->size>0){
- dprintf("... error: inode is non-empty directory\n");
- return -2;
- }
- // reset data blocks of file
- if(type==0){
- /**
- * DEBUGGING PRINT
- */
- dprintf("Inode size: %d, data sector 0: %d\n", child->size, child->data[0]);
- char data_buffer[SECTOR_SIZE];
- for(int i=0; i<child->size; i++){
- if(Disk_Read(child->data[i], data_buffer) < 0) return -1;
- dprintf("... delete contents of file with inode %d from sector %d\n",
- child_inode, child->data[i]);
- bzero(data_buffer, SECTOR_SIZE);
- if(Disk_Write(child->data[i], data_buffer) < 0) return -1;
- if (bitmap_reset(SECTOR_BITMAP_START_SECTOR, SECTOR_BITMAP_SECTORS, child->data[i]) < 0) {
- dprintf("... error: free sector occupied by file in sector bitmap unsuccessful\n");
- return -1;
- }
- }
- }
- // delete the child inode
- memset(child, 0, sizeof(inode_t));
- if(Disk_Write(inode_sector, inode_buffer) < 0) return -1;
- dprintf("... delete inode %d, update disk sector %d\n",
- child_inode, inode_sector);
- // get the disk sector containing the parent inode
- inode_sector = INODE_TABLE_START_SECTOR+parent_inode/INODES_PER_SECTOR;
- if(Disk_Read(inode_sector, inode_buffer) < 0) return -1;
- dprintf("... load inode table for parent inode %d from disk sector %d\n",
- parent_inode, inode_sector);
- // get the parent inode
- inode_start_entry = (inode_sector-INODE_TABLE_START_SECTOR)*INODES_PER_SECTOR;
- offset = parent_inode-inode_start_entry;
- assert(0 <= offset && offset < INODES_PER_SECTOR);
- inode_t* parent = (inode_t*)(inode_buffer+offset*sizeof(inode_t));
- dprintf("... get parent inode %d (size=%d, type=%d)\n",
- parent_inode, parent->size, parent->type);
- // check if parent is directory
- if(parent->type != 1) {
- dprintf("... error: parent inode is not directory\n");
- return -3;
- }
- // check if parent is non-empty
- if(parent->size < 1) {
- dprintf("... error: parent directory has no entries\n");
- return -1;
- }
- // reset bit of child inode in bitmap
- if (bitmap_reset(INODE_BITMAP_START_SECTOR, INODE_BITMAP_SECTORS, child_inode) < 0) {
- dprintf("... error: reset inode in bitmap unsuccessful\n");
- return -1;
- }
- int remainder = parent->size % DIRENTS_PER_SECTOR;
- int group = (parent->size+DIRENTS_PER_SECTOR-1)/DIRENTS_PER_SECTOR;
- char dirent_buffer[SECTOR_SIZE];
- dirent_t* dirent;
- int counter = 0;
- int found = 0;
- // search for the dirent in every group
- for(int i = 0; i<group; i++){
- if(Disk_Read(parent->data[i], dirent_buffer) < 0) return -1;
- dprintf("... search for child in disk sector %d for dirent group %d\n", parent->data[i], i);
- for(int j=0; j<DIRENTS_PER_SECTOR; j++){
- counter ++;
- dirent = (dirent_t*)(dirent_buffer+j*sizeof(dirent_t));
- if(counter < parent->size && (!found)) {
- // Case 1: Child node found and last dirent in the same sector
- if(dirent->inode == child_inode && i == group-1) {
- dirent_t* last_dirent = (dirent_t*)(dirent_buffer+(remainder-1)*sizeof(dirent_t));
- memcpy(dirent, last_dirent, sizeof(dirent_t));
- memset(last_dirent, 0, sizeof(dirent_t));
- if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
- dprintf("... delete dirent (inode=%d) from group %d, update disk sector %d\n",
- child_inode, i, parent->data[i]);
- found=1;
- // Case 2: Child node found, but last dirent in other sector
- } else if(dirent->inode == child_inode) {
- char last_dirent_buffer[SECTOR_SIZE];
- if(Disk_Read(parent->data[group-1], last_dirent_buffer) < 0) return -1;
- dprintf("... load last dirent from parent %d in disk sector %d for dirent group %d\n",
- parent_inode, parent->data[group-1], group-1);
- dirent_t* last_dirent = (dirent_t*)(last_dirent_buffer+(remainder-1)*sizeof(dirent_t));
- memcpy(dirent, last_dirent, sizeof(dirent_t));
- memset(last_dirent, 0, sizeof(dirent_t));
- if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
- dprintf("...delete dirent (inode=%d) from group %d, update disk sector %d\n",
- child_inode, i, parent->data[i]);
- if(Disk_Write(parent->data[group-1], last_dirent_buffer) < 0) return -1;
- dprintf("...copy last dirent with inode %d into group %d, update disk sector %d\n",
- dirent->inode, group-1, parent->data[group-1]);
- found=1;
- }
- } else if(!found) {
- // Case 3: Child found and last dirent from parent
- if(dirent->inode == child_inode) {
- memset(dirent, 0, sizeof(dirent_t));
- if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
- dprintf("... delete dirent (inode=%d) from group %d, update disk sector %d\n",
- child_inode, group-1, parent->data[i]);
- found=1;
- // Case 4: Child node not found, and reached last dirent from parent
- } else if(counter >= parent->size) {
- dprintf("Counter: %d, Parent size: %d\n", counter, parent->size);
- dprintf("... error: child inode could not be found in parent directory\n");
- return -1;
- }
- }
- }
- }
- // check for remaining dirents from parent in that sector (otherwise reset sector bitmap)
- if (remainder == 1) {
- // disk sector has to be freed
- if (bitmap_reset(SECTOR_BITMAP_START_SECTOR, SECTOR_BITMAP_SECTORS, parent->data[group]) < 0) {
- dprintf("... error: free sector in bitmap unsuccessful\n");
- return -1;
- }
- parent->data[group-1] = 0;
- }
- // update parent inode and write to disk
- parent->size--;
- if(Disk_Write(inode_sector, inode_buffer) < 0) return -1;
- dprintf("... update parent inode on disk sector %d\n", inode_sector);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement