Changeset 608:da4a18f4f414
- Timestamp:
- 06/12/08 13:03:43 (7 months ago)
- Author:
- Maxime Petazzoni <maxime.petazzoni@…>
- Branch:
- default
- Message:
-
Complete the defrag_simple() code.
Comes with fixes to the nx_fs_move_region() helper function and a new
nx_fs_dump() function that displays an index of the filesystem.
- Location:
- nxos/base/lib/fs
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r605
|
r608
|
|
| 219 | 219 | */ |
| 220 | 220 | static fs_err_t nx_fs_move_region(U32 source, U32 dest, U32 len) { |
| 221 | | U32 data; |
| | 221 | U32 data[EFC_PAGE_WORDS]; |
| 222 | 222 | |
| 223 | 223 | NX_ASSERT(source < EFC_PAGES); |
| 224 | 224 | NX_ASSERT(dest < EFC_PAGES); |
| 225 | 225 | NX_ASSERT(len < EFC_PAGES); |
| 226 | | NX_ASSERT(dest - source <= len); |
| | 226 | |
| | 227 | /* TODO: allow forward moves ? */ |
| | 228 | NX_ASSERT(dest < source || (dest > source && dest > source + len)); |
| 227 | 229 | |
| 228 | 230 | while (len--) { |
| 229 | | data = FLASH_BASE_PTR[source*EFC_PAGE_WORDS]; |
| 230 | | if (!nx__efc_write_page(&data, dest)) { |
| | 231 | memcpy((void *) data, |
| | 232 | (void *) &(FLASH_BASE_PTR[source*EFC_PAGE_WORDS]), |
| | 233 | EFC_PAGE_BYTES); |
| | 234 | if (!nx__efc_write_page(data, dest)) { |
| 231 | 235 | return FS_ERR_FLASH_ERROR; |
| 232 | 236 | } |
| 233 | 237 | |
| 234 | | /* TODO: erase the source page ? */ |
| | 238 | if (!nx__efc_erase_page(source, 0)) { |
| | 239 | return FS_ERR_FLASH_ERROR; |
| | 240 | } |
| 235 | 241 | |
| 236 | 242 | source++; |
| … |
… |
|
| 244 | 250 | */ |
| 245 | 251 | static fs_err_t nx_fs_relocate_to_page(fs_file_t *file, U32 origin) { |
| 246 | | U32 page_data[EFC_PAGE_WORDS], null_data[EFC_PAGE_WORDS] = {0}; |
| 247 | | U32 diff, i; |
| 248 | | size_t size; |
| | 252 | fs_err_t err; |
| | 253 | size_t n_pages; |
| | 254 | U32 diff; |
| 249 | 255 | |
| 250 | 256 | diff = origin - file->origin; |
| 251 | 257 | |
| 252 | 258 | /* Move the file's data. */ |
| 253 | | size = nx_fs_get_file_page_count(file->size); |
| 254 | | |
| 255 | | /* TODO: use nx_fs_move_region? */ |
| 256 | | for (i=file->origin; i<size; i++) { |
| 257 | | nx__efc_read_page(i, page_data); |
| 258 | | /* TODO: figure out if we want to erase the source page now or later. */ |
| 259 | | if (!nx__efc_write_page(page_data, i + diff) |
| 260 | | || !nx__efc_write_page(null_data, i)) { |
| 261 | | return FS_ERR_FLASH_ERROR; |
| 262 | | } |
| 263 | | } |
| 264 | | |
| | 259 | n_pages = nx_fs_get_file_page_count(file->size); |
| | 260 | err = nx_fs_move_region(file->origin, origin, n_pages); |
| | 261 | if (err != FS_ERR_NO_ERROR) { |
| | 262 | return err; |
| | 263 | } |
| | 264 | |
| | 265 | /* Set the file pages pointers to their respective new values. */ |
| 265 | 266 | file->origin = origin; |
| 266 | 267 | file->rbuf.page += diff; |
| … |
… |
|
| 638 | 639 | fs_file_t *file; |
| 639 | 640 | U32 page, end; |
| 640 | | U32 erase[EFC_PAGE_WORDS] = {0}; |
| 641 | 641 | |
| 642 | 642 | file = nx_fs_get_file(fd); |
| … |
… |
|
| 649 | 649 | for (page = file->origin; page < end; page++) { |
| 650 | 650 | if (nx_fs_page_has_magic(page)) { |
| 651 | | /* Erase marker. */ |
| 652 | | if (!nx__efc_write_page(erase, page)) { |
| | 651 | if (!nx__efc_erase_page(page, 0)) { |
| 653 | 652 | return FS_ERR_FLASH_ERROR; |
| 654 | 653 | } |
| … |
… |
|
| 746 | 745 | } |
| 747 | 746 | } |
| | 747 | |
| 748 | 748 | return FS_ERR_FILE_NOT_FOUND; |
| 749 | 749 | } |
| 750 | 750 | |
| | 751 | void nx_fs_dump(void) { |
| | 752 | U32 i = FS_PAGE_START, origin = 0; |
| | 753 | union U32tochar nameconv; |
| | 754 | |
| | 755 | while (nx_fs_find_next_origin(i, &origin) == FS_ERR_NO_ERROR) { |
| | 756 | volatile U32 *metadata = &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]); |
| | 757 | |
| | 758 | memcpy(nameconv.integers, |
| | 759 | (void *)(metadata + FS_FILENAME_OFFSET), |
| | 760 | FS_FILENAME_LENGTH); |
| | 761 | |
| | 762 | nx_display_uint(origin); |
| | 763 | nx_display_string(":"); |
| | 764 | nx_display_string(nameconv.chars); |
| | 765 | nx_display_end_line(); |
| | 766 | |
| | 767 | i = origin + nx_fs_get_file_page_count(nx_fs_get_file_size_from_metadata(metadata)); |
| | 768 | } |
| | 769 | |
| | 770 | nx_display_string("--"); |
| | 771 | nx_display_uint(i); |
| | 772 | nx_display_string("--\n"); |
| | 773 | } |
| | 774 | |
| 751 | 775 | /* Defrag functions. */ |
| 752 | 776 | |
| | 777 | /* Simple defragmentation function: tries to concatenate data blocks at |
| | 778 | * the beginning of the flash. |
| | 779 | * |
| | 780 | * To acheive this, we iterate through every "hole" in the flash (empty |
| | 781 | * spage), and try to find a block (contiguous set of files) that best |
| | 782 | * matches the hole. If no block smaller or equal than the hole size is |
| | 783 | * found, pull backwards the next block to fill the hole, if block there |
| | 784 | * is. |
| | 785 | */ |
| 753 | 786 | fs_err_t nx_fs_defrag_simple(void) { |
| 754 | 787 | U32 i = FS_PAGE_START; |
| … |
… |
|
| 758 | 791 | |
| 759 | 792 | while (i < FS_PAGE_END) { |
| | 793 | /* Find the next hole, and its size. */ |
| | 794 | |
| 760 | 795 | err = nx_fs_find_next_hole(i, &next_hole); |
| 761 | 796 | if (err != FS_ERR_NO_ERROR) { |
| … |
… |
|
| 764 | 799 | } |
| 765 | 800 | |
| 766 | | nx_fs_find_next_origin(next_hole, &next_file); |
| | 801 | err = nx_fs_find_next_origin(next_hole, &next_file); |
| 767 | 802 | if (err != FS_ERR_NO_ERROR) { |
| 768 | 803 | /* No files found after : nothing else to do */ |
| … |
… |
|
| 772 | 807 | first_next_file = next_file; |
| 773 | 808 | hole_length = next_file - next_hole; |
| 774 | | NX_ASSERT(hole_length <= 0); |
| | 809 | |
| | 810 | NX_ASSERT(hole_length > 0); |
| 775 | 811 | |
| 776 | 812 | /* Search for the best block to move. */ |
| 777 | 813 | do { |
| 778 | | err = nx_fs_find_next_hole(next_file, &end_of_block); |
| 779 | | if (err != FS_ERR_NO_ERROR) { |
| | 814 | if (nx_fs_find_next_hole(next_file, &end_of_block) != FS_ERR_NO_ERROR) { |
| 780 | 815 | /* No free space after */ |
| 781 | 816 | break; |
| … |
… |
|
| 787 | 822 | best_block_origin = next_file; |
| 788 | 823 | } |
| 789 | | next_file = end_of_block; |
| | 824 | |
| | 825 | if (block_size != hole_length && |
| | 826 | nx_fs_find_next_origin(end_of_block, &next_file) != FS_ERR_NO_ERROR) { |
| | 827 | break; |
| | 828 | } |
| 790 | 829 | } while (next_file < FS_PAGE_END && block_size != hole_length); |
| 791 | 830 | |
-
|
r590
|
r608
|
|
| 202 | 202 | U32 *wasted); |
| 203 | 203 | |
| | 204 | /** Dumps the index of the filesystem as <page>:<filename>. |
| | 205 | */ |
| | 206 | void nx_fs_dump(void); |
| | 207 | |
| 204 | 208 | /** Perform a simple defragmentation of the flash filesystem. |
| 205 | 209 | * |