| | 754 | U32 i = FS_PAGE_START; |
| | 755 | U32 next_hole, next_file, first_next_file, hole_length = 0, end_of_block; |
| | 756 | U32 best_block_origin =0, best_block_size=0, block_size = 0; |
| | 757 | fs_err_t err = FS_ERR_NO_ERROR; |
| | 758 | |
| | 759 | while (i < FS_PAGE_END) { |
| | 760 | err = nx_fs_find_next_hole(i, &next_hole); |
| | 761 | if (err != FS_ERR_NO_ERROR) { |
| | 762 | /* No free blocks left on flash : nothing else to do */ |
| | 763 | return FS_ERR_NO_ERROR; |
| | 764 | } |
| | 765 | |
| | 766 | nx_fs_find_next_origin(next_hole, &next_file); |
| | 767 | if (err != FS_ERR_NO_ERROR) { |
| | 768 | /* No files found after : nothing else to do */ |
| | 769 | return FS_ERR_NO_ERROR; |
| | 770 | } |
| | 771 | |
| | 772 | first_next_file = next_file; |
| | 773 | hole_length = next_file - next_hole; |
| | 774 | NX_ASSERT(hole_length <= 0); |
| | 775 | |
| | 776 | /* Search for the best block to move. */ |
| | 777 | do { |
| | 778 | err = nx_fs_find_next_hole(next_file, &end_of_block); |
| | 779 | if (err != FS_ERR_NO_ERROR) { |
| | 780 | /* No free space after */ |
| | 781 | break; |
| | 782 | } |
| | 783 | |
| | 784 | block_size = end_of_block - next_file; |
| | 785 | if (block_size < hole_length && block_size > best_block_size) { |
| | 786 | best_block_size = block_size; |
| | 787 | best_block_origin = next_file; |
| | 788 | } |
| | 789 | next_file = end_of_block; |
| | 790 | } while (next_file < FS_PAGE_END && block_size != hole_length); |
| | 791 | |
| | 792 | /* Move the block to fill the hole and move the search start |
| | 793 | * position after the block. |
| | 794 | */ |
| | 795 | |
| | 796 | /* First case: the block found exactly matches the hole. */ |
| | 797 | if (block_size == hole_length) { |
| | 798 | err = nx_fs_move_region(next_file, next_hole, block_size); |
| | 799 | if (err != FS_ERR_NO_ERROR) { |
| | 800 | return err; |
| | 801 | } |
| | 802 | |
| | 803 | i = next_hole + block_size; |
| | 804 | } |
| | 805 | |
| | 806 | /* Else, if a best match has been found, move it. */ |
| | 807 | else if (best_block_origin != 0) { |
| | 808 | err = nx_fs_move_region(best_block_origin, next_hole, best_block_size); |
| | 809 | if (err != FS_ERR_NO_ERROR) { |
| | 810 | return err; |
| | 811 | } |
| | 812 | |
| | 813 | i = next_hole + best_block_size; |
| | 814 | } |
| | 815 | |
| | 816 | /* Otherwise, if no matching block was found, pull the next block |
| | 817 | * backwards to fill the hole. |
| | 818 | */ |
| | 819 | else { |
| | 820 | err = nx_fs_find_next_hole(first_next_file, &end_of_block); |
| | 821 | if (err != FS_ERR_NO_ERROR) { |
| | 822 | end_of_block = FS_PAGE_END; |
| | 823 | } |
| | 824 | |
| | 825 | err = nx_fs_move_region(first_next_file, next_hole, |
| | 826 | end_of_block - first_next_file); |
| | 827 | if (err != FS_ERR_NO_ERROR) { |
| | 828 | return err; |
| | 829 | } |
| | 830 | |
| | 831 | i = next_hole + end_of_block - first_next_file; |
| | 832 | } |
| | 833 | } |
| | 834 | |