| | 687 | fs_err_t nx_fs_soft_format(void) { |
| | 688 | U32 nulldata[EFC_PAGE_WORDS] = {0}; |
| | 689 | U32 i, j; |
| | 690 | |
| | 691 | for (i=FS_PAGE_START; i<FS_PAGE_END; i++) { |
| | 692 | if (nx_fs_page_has_magic(i)) { |
| | 693 | volatile U32 *metadata = &(FLASH_BASE_PTR[i*EFC_PAGE_WORDS]); |
| | 694 | size_t size, npages; |
| | 695 | |
| | 696 | size = nx_fs_get_file_size_from_metadata(metadata); |
| | 697 | npages = nx_fs_get_file_page_count(size); |
| | 698 | nx_display_string("erasing "); |
| | 699 | nx_display_uint(npages); |
| | 700 | nx_display_end_line(); |
| | 701 | |
| | 702 | for (j=i; j<i+npages; j++) { |
| | 703 | nx_display_string("wiping "); |
| | 704 | nx_display_uint(j); |
| | 705 | nx_display_end_line(); |
| | 706 | |
| | 707 | nx__efc_write_page(nulldata, j); |
| | 708 | } |
| | 709 | |
| | 710 | i += npages - 1; |
| | 711 | } |
| | 712 | } |
| | 713 | |
| | 714 | return FS_ERR_NO_ERROR; |
| | 715 | } |
| | 716 | |
| 922 | | fs_err_t nx_fs_defrag_best_overall(void) { |
| 923 | | U32 hole_start = 0, next_hole = 0, next_origin = 0; |
| 924 | | U32 files, used, free_pages, wasted, mean_space_per_file = 0; |
| 925 | | U32 i; |
| | 952 | static fs_err_t nx_fs_defrag_pull_file_to(U32 origin, U32 dest) { |
| | 953 | volatile U32 *metadata; |
| | 954 | size_t size; |
| | 955 | |
| | 956 | metadata = &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]); |
| | 957 | size = nx_fs_get_file_size_from_metadata(metadata); |
| | 958 | |
| | 959 | return nx_fs_move_region(origin, dest, |
| | 960 | nx_fs_get_file_page_count(size)); |
| | 961 | } |
| | 962 | |
| | 963 | static U32 nx_fs_defrag_get_mean_space(void) { |
| | 964 | U32 files, used, free_pages, wasted; |
| 951 | | if (nx_fs_find_next_hole(next_origin, &hole_start) != FS_ERR_NO_ERROR) { |
| 952 | | hole_start = FS_PAGE_END-1; |
| 953 | | } |
| 954 | | |
| 955 | | nx_fs_move_region(next_origin, i, hole_start - next_origin); |
| 956 | | |
| | 993 | err = nx_fs_defrag_pull_file_to(next_origin, i); |
| | 994 | if (err != FS_ERR_NO_ERROR) { |
| | 995 | return err; |
| | 996 | } |
| | 997 | |
| | 998 | nx_display_uint(mean_space_per_file); |
| | 999 | nx_display_end_line(); |
| | 1000 | |
| | 1001 | /* Then, iterate on all files to set a proper space after them. */ |
| 959 | | size_t hole_size; |
| 960 | | |
| 961 | | /* Calculate the size of the hole directly after this block. */ |
| 962 | | nx_fs_find_next_hole(i, &hole_start); |
| 963 | | nx_fs_find_next_origin(hole_start, &next_origin); |
| 964 | | hole_size = next_origin - hole_start; |
| 965 | | |
| 966 | | /* When the size of the hole following this file is greater than |
| 967 | | * what we want to put after it, move the rest of the current |
| 968 | | * block a bit forward to make room after this file. |
| | 1004 | volatile U32 *metadata; |
| | 1005 | size_t size, npages, hole_size; |
| | 1006 | |
| | 1007 | metadata = &(FLASH_BASE_PTR[i*EFC_PAGE_WORDS]); |
| | 1008 | size = nx_fs_get_file_size_from_metadata(metadata); |
| | 1009 | npages = nx_fs_get_file_page_count(size); |
| | 1010 | |
| | 1011 | /* No file left after this one, job's done. */ |
| | 1012 | if (nx_fs_find_next_origin(i + npages, &next_origin) != FS_ERR_NO_ERROR) { |
| | 1013 | return FS_ERR_NO_ERROR; |
| | 1014 | } |
| | 1015 | |
| | 1016 | hole_size = next_origin - (i + npages); |
| | 1017 | |
| | 1018 | nx_display_uint(i); |
| | 1019 | nx_display_string(" "); |
| | 1020 | nx_display_uint(npages); |
| | 1021 | nx_display_end_line(); |
| | 1022 | |
| | 1023 | i += npages + mean_space_per_file; |
| | 1024 | |
| | 1025 | nx_display_uint(hole_size); |
| | 1026 | nx_display_string(" > "); |
| | 1027 | nx_display_uint(i); |
| | 1028 | nx_display_end_line(); |
| | 1029 | |
| | 1030 | /* First, trivial case: the hole size equals mean_space_per_file. |
| | 1031 | * We then have nothing to do and can proceed to the next file. |
| 970 | | if (hole_size > mean_space_per_file) { |
| 971 | | // TODO |
| 972 | | size_t size = nx_fs_get_file_size_from_metadata(metadata); |
| 973 | | nx_fs_move_region(i + size, mean_space_per_file, |
| 974 | | hole_start - i); |
| 975 | | } |
| 976 | | |
| 977 | | /* Otherwise, if the hole is smaller than what we want, move the |
| 978 | | * following block a bit forward, when possible. |
| | 1033 | if (hole_size == mean_space_per_file) { |
| | 1034 | continue; |
| | 1035 | } |
| | 1036 | |
| | 1037 | /* Second case: the hole size is greater than what we want: pull |
| | 1038 | * the next file at (beginning of the hole + mean_space_per_file). |
| 985 | | |
| 986 | | nx_fs_move_region(next_origin, hole_start + mean_space_per_file, |
| 987 | | next_hole - next_origin); |
| 988 | | } |
| 989 | | } |
| 990 | | } |
| 991 | | |
| 992 | | return FS_ERR_NO_ERROR; |
| 993 | | } |
| 994 | | |
| | 1045 | } |
| | 1046 | |
| | 1047 | /* Last case: the hole is smaller than what we need: try to move |
| | 1048 | * what's after this file a bit forward to make room for |
| | 1049 | * mean_space_per_file pages. |
| | 1050 | */ |
| | 1051 | else { |
| | 1052 | U32 next_hole = 0, hole_end = 0; |
| | 1053 | size_t next_hole_size; |
| | 1054 | |
| | 1055 | nx_display_string("here\n"); |
| | 1056 | |
| | 1057 | if (nx_fs_find_next_hole(next_origin, &next_hole) != |
| | 1058 | FS_ERR_NO_ERROR) { |
| | 1059 | /* The block goes all the way to the end of the flash: we |
| | 1060 | * can't do anything anymore, just leave. |
| | 1061 | */ |
| | 1062 | return FS_ERR_NO_ERROR; |
| | 1063 | } |
| | 1064 | |
| | 1065 | if (nx_fs_find_next_origin(next_hole, &hole_end) != FS_ERR_NO_ERROR) { |
| | 1066 | hole_end = FS_PAGE_END-1; |
| | 1067 | } |
| | 1068 | |
| | 1069 | 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(); |
| | 1075 | |
| | 1076 | /* First sub-case: we have enough space after this block to |
| | 1077 | * extend our hole up to mean_space_per_file pages. |
| | 1078 | */ |
| | 1079 | if (next_hole_size >= mean_space_per_file - hole_size) { |
| | 1080 | /* Move the block [next_origin ; next_hole] |
| | 1081 | * (mean_space_per_file - hole_size) pages to the right. |
| | 1082 | */ |
| | 1083 | err = nx_fs_move_region(next_origin, |
| | 1084 | next_origin + mean_space_per_file, |
| | 1085 | next_hole - next_origin); |
| | 1086 | if (err != FS_ERR_NO_ERROR) { |
| | 1087 | return err; |
| | 1088 | } |
| | 1089 | } |
| | 1090 | |
| | 1091 | else { |
| | 1092 | /* TODO: find a way to accomodate this situation. */ |
| | 1093 | return FS_ERR_NO_SPACE_LEFT_ON_DEVICE; |
| | 1094 | } |
| | 1095 | } |
| | 1096 | } |
| | 1097 | } |
| | 1098 | |
| | 1099 | return FS_ERR_NO_ERROR; |
| | 1100 | } |
| | 1101 | |