Advertisement
Guest User

Untitled

a guest
Nov 19th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.80 KB | None | 0 0
  1. int remove_inode(int type, int parent_inode, int child_inode)
  2. {
  3.  
  4. dprintf("... remove inode %d\n", child_inode);
  5.  
  6. // load the disk sector containing the child inode
  7. int inode_sector = INODE_TABLE_START_SECTOR+child_inode/INODES_PER_SECTOR;
  8. char inode_buffer[SECTOR_SIZE];
  9. if(Disk_Read(inode_sector, inode_buffer) < 0) return -1;
  10. dprintf("... load inode table for child inode from disk sector %d\n", inode_sector);
  11.  
  12. // get the child inode
  13. int inode_start_entry = (inode_sector-INODE_TABLE_START_SECTOR)*INODES_PER_SECTOR;
  14. int offset = child_inode-inode_start_entry;
  15. assert(0 <= offset && offset < INODES_PER_SECTOR);
  16. inode_t* child = (inode_t*)(inode_buffer+offset*sizeof(inode_t));
  17.  
  18. // check for right type
  19. if(child->type!=type){
  20. dprintf("... error: the type parameter does not match the actual inode type\n");
  21. return -3;
  22. }
  23.  
  24. // check if child is non-empty directory
  25. if(child->type==1 && child->size>0){
  26. dprintf("... error: inode is non-empty directory\n");
  27. return -2;
  28. }
  29.  
  30. // reset data blocks of file
  31. if(type==0){
  32.  
  33. /**
  34. * DEBUGGING PRINT
  35. */
  36. dprintf("Inode size: %d, data sector 0: %d\n", child->size, child->data[0]);
  37.  
  38. char data_buffer[SECTOR_SIZE];
  39. for(int i=0; i<child->size; i++){
  40. if(Disk_Read(child->data[i], data_buffer) < 0) return -1;
  41. dprintf("... delete contents of file with inode %d from sector %d\n",
  42. child_inode, child->data[i]);
  43. bzero(data_buffer, SECTOR_SIZE);
  44. if(Disk_Write(child->data[i], data_buffer) < 0) return -1;
  45. if (bitmap_reset(SECTOR_BITMAP_START_SECTOR, SECTOR_BITMAP_SECTORS, child->data[i]) < 0) {
  46. dprintf("... error: free sector occupied by file in sector bitmap unsuccessful\n");
  47. return -1;
  48. }
  49. }
  50.  
  51. }
  52.  
  53. // delete the child inode
  54. memset(child, 0, sizeof(inode_t));
  55. if(Disk_Write(inode_sector, inode_buffer) < 0) return -1;
  56. dprintf("... delete inode %d, update disk sector %d\n",
  57. child_inode, inode_sector);
  58.  
  59. // get the disk sector containing the parent inode
  60. inode_sector = INODE_TABLE_START_SECTOR+parent_inode/INODES_PER_SECTOR;
  61. if(Disk_Read(inode_sector, inode_buffer) < 0) return -1;
  62. dprintf("... load inode table for parent inode %d from disk sector %d\n",
  63. parent_inode, inode_sector);
  64.  
  65. // get the parent inode
  66. inode_start_entry = (inode_sector-INODE_TABLE_START_SECTOR)*INODES_PER_SECTOR;
  67. offset = parent_inode-inode_start_entry;
  68. assert(0 <= offset && offset < INODES_PER_SECTOR);
  69. inode_t* parent = (inode_t*)(inode_buffer+offset*sizeof(inode_t));
  70. dprintf("... get parent inode %d (size=%d, type=%d)\n",
  71. parent_inode, parent->size, parent->type);
  72.  
  73. // check if parent is directory
  74. if(parent->type != 1) {
  75. dprintf("... error: parent inode is not directory\n");
  76. return -3;
  77. }
  78.  
  79. // check if parent is non-empty
  80. if(parent->size < 1) {
  81. dprintf("... error: parent directory has no entries\n");
  82. return -1;
  83. }
  84.  
  85. // reset bit of child inode in bitmap
  86. if (bitmap_reset(INODE_BITMAP_START_SECTOR, INODE_BITMAP_SECTORS, child_inode) < 0) {
  87. dprintf("... error: reset inode in bitmap unsuccessful\n");
  88. return -1;
  89. }
  90.  
  91. int remainder = parent->size % DIRENTS_PER_SECTOR;
  92. int group = (parent->size+DIRENTS_PER_SECTOR-1)/DIRENTS_PER_SECTOR;
  93. char dirent_buffer[SECTOR_SIZE];
  94. dirent_t* dirent;
  95. int counter = 0;
  96. int found = 0;
  97.  
  98. // search for the dirent in every group
  99. for(int i = 0; i<group; i++){
  100.  
  101. if(Disk_Read(parent->data[i], dirent_buffer) < 0) return -1;
  102. dprintf("... search for child in disk sector %d for dirent group %d\n", parent->data[i], i);
  103.  
  104. for(int j=0; j<DIRENTS_PER_SECTOR; j++){
  105. counter ++;
  106. dirent = (dirent_t*)(dirent_buffer+j*sizeof(dirent_t));
  107.  
  108. if(counter < parent->size && (!found)) {
  109.  
  110. // Case 1: Child node found and last dirent in the same sector
  111. if(dirent->inode == child_inode && i == group-1) {
  112. dirent_t* last_dirent = (dirent_t*)(dirent_buffer+(remainder-1)*sizeof(dirent_t));
  113. memcpy(dirent, last_dirent, sizeof(dirent_t));
  114. memset(last_dirent, 0, sizeof(dirent_t));
  115. if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
  116. dprintf("... delete dirent (inode=%d) from group %d, update disk sector %d\n",
  117. child_inode, i, parent->data[i]);
  118. found=1;
  119.  
  120. // Case 2: Child node found, but last dirent in other sector
  121. } else if(dirent->inode == child_inode) {
  122. char last_dirent_buffer[SECTOR_SIZE];
  123. if(Disk_Read(parent->data[group-1], last_dirent_buffer) < 0) return -1;
  124. dprintf("... load last dirent from parent %d in disk sector %d for dirent group %d\n",
  125. parent_inode, parent->data[group-1], group-1);
  126. dirent_t* last_dirent = (dirent_t*)(last_dirent_buffer+(remainder-1)*sizeof(dirent_t));
  127. memcpy(dirent, last_dirent, sizeof(dirent_t));
  128. memset(last_dirent, 0, sizeof(dirent_t));
  129. if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
  130. dprintf("...delete dirent (inode=%d) from group %d, update disk sector %d\n",
  131. child_inode, i, parent->data[i]);
  132. if(Disk_Write(parent->data[group-1], last_dirent_buffer) < 0) return -1;
  133. dprintf("...copy last dirent with inode %d into group %d, update disk sector %d\n",
  134. dirent->inode, group-1, parent->data[group-1]);
  135. found=1;
  136. }
  137.  
  138. } else if(!found) {
  139.  
  140. // Case 3: Child found and last dirent from parent
  141. if(dirent->inode == child_inode) {
  142. memset(dirent, 0, sizeof(dirent_t));
  143. if(Disk_Write(parent->data[i], dirent_buffer) < 0) return -1;
  144. dprintf("... delete dirent (inode=%d) from group %d, update disk sector %d\n",
  145. child_inode, group-1, parent->data[i]);
  146. found=1;
  147.  
  148. // Case 4: Child node not found, and reached last dirent from parent
  149. } else if(counter >= parent->size) {
  150. dprintf("Counter: %d, Parent size: %d\n", counter, parent->size);
  151. dprintf("... error: child inode could not be found in parent directory\n");
  152. return -1;
  153. }
  154. }
  155. }
  156. }
  157.  
  158. // check for remaining dirents from parent in that sector (otherwise reset sector bitmap)
  159. if (remainder == 1) {
  160. // disk sector has to be freed
  161. if (bitmap_reset(SECTOR_BITMAP_START_SECTOR, SECTOR_BITMAP_SECTORS, parent->data[group]) < 0) {
  162. dprintf("... error: free sector in bitmap unsuccessful\n");
  163. return -1;
  164. }
  165. parent->data[group-1] = 0;
  166. }
  167.  
  168. // update parent inode and write to disk
  169. parent->size--;
  170. if(Disk_Write(inode_sector, inode_buffer) < 0) return -1;
  171. dprintf("... update parent inode on disk sector %d\n", inode_sector);
  172.  
  173. return 0;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement