Changeset 614:9844c7961414

Show
Ignore:
Timestamp:
06/13/08 19:01:37 (7 months ago)
Author:
Maxime Petazzoni <maxime.petazzoni@…>
Branch:
default
Message:

Best overall defrag working.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • nxos/base/lib/fs/fs.c

    r612 r614  
    700700      nx_display_end_line(); 
    701701 
    702       for (j=i; j<i+npages; j++) { 
     702      for (j=i; j<i+npages && j<FS_PAGE_END; j++) { 
    703703        nx_display_string("wiping "); 
    704704        nx_display_uint(j); 
     
    10191019      nx_display_string(" "); 
    10201020      nx_display_uint(npages); 
    1021       nx_display_end_line(); 
     1021      nx_display_string(" "); 
     1022      nx_display_uint(hole_size); 
     1023      nx_display_string(">"); 
    10221024 
    10231025      i += npages + mean_space_per_file; 
    1024  
    1025       nx_display_uint(hole_size); 
    1026       nx_display_string(" > "); 
    10271026      nx_display_uint(i); 
    10281027      nx_display_end_line(); 
     
    10531052        size_t next_hole_size; 
    10541053 
    1055         nx_display_string("here\n"); 
    1056  
    10571054        if (nx_fs_find_next_hole(next_origin, &next_hole) != 
    10581055          FS_ERR_NO_ERROR) { 
     
    10681065 
    10691066        next_hole_size = hole_end - next_hole; 
    1070  
    1071         nx_display_uint(next_origin); 
    1072         nx_display_string("-"); 
    1073         nx_display_uint(next_hole); 
    1074         nx_display_end_line(); 
    10751067 
    10761068        /* First sub-case: we have enough space after this block to 
     
    10821074           */ 
    10831075          err = nx_fs_move_region(next_origin, 
    1084             next_origin + mean_space_per_file, 
     1076            next_origin + (mean_space_per_file - hole_size), 
    10851077            next_hole - next_origin); 
    10861078          if (err != FS_ERR_NO_ERROR) { 
     
    10891081        } 
    10901082 
     1083        /* Otherwise, we need to make room for mean_space_per_file - 
     1084         * hole_size pages in one way or another. 
     1085         */ 
    10911086        else { 
    1092           /* TODO: find a way to accomodate this situation. */ 
    1093           return FS_ERR_NO_SPACE_LEFT_ON_DEVICE; 
     1087          /* First, we'll try to move the first file of the obstructing 
     1088           * block somewhere else on the right end side of the flash. 
     1089           */ 
     1090          U32 file_origin = next_origin; 
     1091          size_t file_size = next_hole - next_origin; 
     1092          fs_err_t search_err; 
     1093 
     1094          while ((search_err = nx_fs_find_next_hole(next_origin, &next_hole)) == 
     1095            FS_ERR_NO_ERROR) { 
     1096 
     1097            if (nx_fs_find_next_origin(next_hole, &next_origin) != FS_ERR_NO_ERROR) { 
     1098              next_origin = FS_PAGE_END - 1; 
     1099            } 
     1100 
     1101            if (next_origin - next_hole >= file_size) { 
     1102              /* We found a big enough hole, move our file and stop 
     1103               * searching. 
     1104               */ 
     1105              fs_err_t move_err = nx_fs_move_region(file_origin, next_hole, file_size); 
     1106              if (move_err != FS_ERR_NO_ERROR) { 
     1107                return err; 
     1108              } 
     1109 
     1110              break; 
     1111            } 
     1112 
     1113            /* Avoid looping on the last page. */ 
     1114            if (next_origin == FS_PAGE_END - 1) { 
     1115              next_origin++; 
     1116            } 
     1117          } 
     1118 
     1119          /* If the file was not moved, try to move the whole block 
     1120           * (including holes smaller than what we need, i.e. 
     1121           * mean_space_per_file - hole_size). 
     1122           */ 
     1123          if (search_err == FS_ERR_FILE_NOT_FOUND) { 
     1124            next_origin = file_origin; 
     1125 
     1126            while ((search_err = nx_fs_find_next_hole(next_origin, &next_hole)) 
     1127              == FS_ERR_NO_ERROR) { 
     1128 
     1129              if (nx_fs_find_next_origin(next_hole, &next_origin) != FS_ERR_NO_ERROR) { 
     1130                next_origin = FS_PAGE_END - 1; 
     1131              } 
     1132 
     1133              if (next_origin - next_hole >= mean_space_per_file - hole_size) { 
     1134                /* With this hole, we'll be able to move this block far 
     1135                 * enough to the right to complete the hole we want to 
     1136                 * enl4rg3 up to mean_space_per_file. 
     1137                 */ 
     1138                break; 
     1139              } 
     1140 
     1141              if (next_origin == FS_PAGE_END - 1) { 
     1142                next_origin++; 
     1143              } 
     1144            } 
     1145 
     1146            /* In the case we were not able to find enough room to move 
     1147             * this block away, we can end the defragmentation process 
     1148             * as this case is becoming too expensive. 
     1149             */ 
     1150            if (search_err != FS_ERR_NO_ERROR) { 
     1151              return FS_ERR_NO_SPACE_LEFT_ON_DEVICE; 
     1152            } 
     1153 
     1154            /* Move this whole block [file_origin ; next_hole] of 
     1155             * (mean_space_per_file - hole_size) pages to the right. 
     1156             */ 
     1157            err = nx_fs_move_region(file_origin, 
     1158              file_origin + (mean_space_per_file - hole_size), 
     1159              next_hole - file_origin); 
     1160            if (err != FS_ERR_NO_ERROR) { 
     1161              return err; 
     1162            } 
     1163          } 
     1164 
     1165          /* End of the 2nd sub-case of the last case (meh.). */ 
     1166          i -= mean_space_per_file + npages; 
    10941167        } 
    10951168      }