| 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; |