| 760 | | return FS_ERR_NO_ERROR; |
| 761 | | } |
| 762 | | |
| | 777 | U32 hole_start = 0, next_hole=0, freeblock_size=0, next_origin=0; |
| | 778 | U32 files, used, free_pages, wasted; |
| | 779 | U32 mean_space_per_file = 0; |
| | 780 | U32 size = 0; |
| | 781 | U32 current_location = FS_PAGE_START; |
| | 782 | /* Get the number of files and freepages. */ |
| | 783 | nx_fs_get_occupation(&files, &used, &free_pages, &wasted); |
| | 784 | /* Nothing to do here, move on */ |
| | 785 | if (files==0){ |
| | 786 | return FS_ERR_NO_ERROR; |
| | 787 | } |
| | 788 | |
| | 789 | mean_space_per_file = free_pages / files; |
| | 790 | if (mean_space_per_file < 1) { |
| | 791 | /*Fallback to simple defrag*/ |
| | 792 | nx_fs_defrag_simple(); |
| | 793 | } else { |
| | 794 | while (current_location < FS_PAGE_END) { |
| | 795 | if (nx_fs_page_has_magic(current_location)) { |
| | 796 | /* calculate free space after file */ |
| | 797 | volatile U32 *metadata = &(FLASH_BASE_PTR[current_location*EFC_PAGE_WORDS]); |
| | 798 | hole_start = current_location + nx_fs_get_file_page_count(nx_fs_get_file_size_from_metadata(metadata)); |
| | 799 | nx_fs_find_next_origin(hole_start, &next_origin); |
| | 800 | freeblock_size = next_origin - hole_start; |
| | 801 | |
| | 802 | /* frag operations*/ |
| | 803 | if (freeblock_size > mean_space_per_file) { |
| | 804 | size = nx_fs_get_file_size_from_metadata(metadata); |
| | 805 | nx_fs_move_region(current_location , hole_start + mean_space_per_file, nx_fs_get_file_page_count(size)); |
| | 806 | } else if (freeblock_size < mean_space_per_file) { |
| | 807 | nx_fs_find_next_hole(next_origin, & next_hole); |
| | 808 | /* TODO: fix overlapping on move */ |
| | 809 | nx_fs_move_region(next_origin, hole_start + mean_space_per_file, next_hole -1); |
| | 810 | } |
| | 811 | } |
| | 812 | } |
| | 813 | } |
| | 814 | return FS_ERR_NO_ERROR; |
| | 815 | } |
| | 816 | |