diff options
author | David Anderson <dvander@google.com> | 2020-01-29 15:31:14 -0800 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2020-03-20 23:15:01 -0400 |
commit | c2481ace20e3bae25258db30529a446e83f28c89 (patch) | |
tree | 3f37e4541df0d1c84f190fc34acfca11785a32b6 | |
parent | d4197585fac5d469693c32dd88f03d84a5ef62fc (diff) | |
download | e2fsprogs-c2481ace20e3bae25258db30529a446e83f28c89.tar.gz |
AOSP: e2fsdroid: Properly free the dedup block map.
When BaseFS specifies the same block for two files, it gets added to a
separate "dedup" bitmap, and removed from the free block bitmap. If the
new build does not use every block in this bitmap, there will be an
inconsistency: the block bitmap marks blocks as in-use when they are
actually free. Although this doesn't matter for AOSP's read-only file
systems, it does cause e2fsck to complain, which breaks the build.
Fix the inconsistency by properly freeing all unused blocks within the
dedup block set.
Bug: 139201772
Test: build AOSP using BaseFS
Change-Id: I6b6511eb713a56fec932f1d5668f1766d64d9479
From AOSP commit: 346bee6f8b97aefe7714688f738606c116099fbc
-rw-r--r-- | contrib/android/basefs_allocator.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/contrib/android/basefs_allocator.c b/contrib/android/basefs_allocator.c index 658a75147..325aed852 100644 --- a/contrib/android/basefs_allocator.c +++ b/contrib/android/basefs_allocator.c @@ -39,6 +39,28 @@ static void fs_free_blocks_range(ext2_filsys fs, } } +/* + * Free any blocks in the bitmap that were reserved but never used. This is + * needed to free dedup_block_map and ensure the free block bitmap is + * internally consistent. + */ +static void fs_free_blocks_bitmap(ext2_filsys fs, ext2fs_block_bitmap bitmap) +{ + blk64_t block = 0; + blk64_t start = fs->super->s_first_data_block; + blk64_t end = ext2fs_blocks_count(fs->super) - 1; + errcode_t retval; + + for (;;) { + retval = ext2fs_find_first_set_block_bitmap2(bitmap, start, end, + &block); + if (retval) + break; + ext2fs_unmark_block_bitmap2(fs->block_map, block); + start = block + 1; + } +} + static void basefs_allocator_free(ext2_filsys fs, struct base_fs_allocator *allocator) { @@ -53,6 +75,7 @@ static void basefs_allocator_free(ext2_filsys fs, } ext2fs_hashmap_free(entries); } + fs_free_blocks_bitmap(fs, allocator->dedup_block_map); ext2fs_free_block_bitmap(allocator->exclusive_block_map); ext2fs_free_block_bitmap(allocator->dedup_block_map); free(allocator); |