aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Anderson <dvander@google.com>2019-12-05 12:23:12 -0800
committerTheodore Ts'o <tytso@mit.edu>2020-01-01 13:41:34 -0500
commitdcbe79c4fa09f87983df09c82f006a455661c47c (patch)
tree178225d5947d6aecdac765997e9565a144628f77
parent269f4c1bc7ca2ecf1d2926d8153488570f8b266c (diff)
downloade2fsprogs-dcbe79c4fa09f87983df09c82f006a455661c47c.tar.gz
AOSP: e2fsdroid: Refactor basefs allocation.
This refactors base_fs_alloc_load() to address two issues. First, the failure cases have been made simpler by factoring out a common helper for freeing a base_fs_allocator. Second, we no longer return EXIT_FAILURE, since this is not an errcode_t. Bug: 145316683 Change-Id: I8b28c684ecf3423b605b550177d7ead4eb2821a4 From AOSP commit: b461ade872a809ab913d7506e9b8ed597d57dc87
-rw-r--r--contrib/android/basefs_allocator.c82
1 files changed, 53 insertions, 29 deletions
diff --git a/contrib/android/basefs_allocator.c b/contrib/android/basefs_allocator.c
index 474cc03bb..c37df147b 100644
--- a/contrib/android/basefs_allocator.c
+++ b/contrib/android/basefs_allocator.c
@@ -25,6 +25,23 @@ static void fs_free_blocks_range(ext2_filsys fs,
}
}
+static void basefs_allocator_free(ext2_filsys fs,
+ struct base_fs_allocator *allocator)
+{
+ struct basefs_entry *e;
+ struct ext2fs_hashmap_entry *it = NULL;
+ struct ext2fs_hashmap *entries = allocator->entries;
+
+ if (entries) {
+ while ((e = ext2fs_hashmap_iter_in_order(entries, &it))) {
+ fs_free_blocks_range(fs, &e->blocks);
+ delete_block_ranges(&e->blocks);
+ }
+ ext2fs_hashmap_free(entries);
+ }
+ free(allocator);
+}
+
static void fs_reserve_blocks_range(ext2_filsys fs,
struct block_range_list *list)
{
@@ -36,41 +53,58 @@ static void fs_reserve_blocks_range(ext2_filsys fs,
}
}
-errcode_t base_fs_alloc_load(ext2_filsys fs, const char *file,
- const char *mountpoint)
+/*
+ * For each file in the base FS map, ensure that its blocks are reserved in
+ * the actual block map. This prevents libext2fs from allocating them for
+ * general purpose use, and ensures that if the file needs data blocks, they
+ * can be re-acquired exclusively for that file.
+ */
+static void fs_reserve_blocks(ext2_filsys fs,
+ struct base_fs_allocator *allocator)
{
- errcode_t retval;
struct basefs_entry *e;
struct ext2fs_hashmap_entry *it = NULL;
+ struct ext2fs_hashmap *entries = allocator->entries;
+
+ while ((e = ext2fs_hashmap_iter_in_order(entries, &it)))
+ fs_reserve_blocks_range(fs, &e->blocks);
+}
+
+errcode_t base_fs_alloc_load(ext2_filsys fs, const char *file,
+ const char *mountpoint)
+{
+ errcode_t retval = 0;
struct base_fs_allocator *allocator;
- struct ext2fs_hashmap *entries = basefs_parse(file, mountpoint);
- if (!entries)
- return -1;
- allocator = malloc(sizeof(*allocator));
- if (!allocator)
- goto err_alloc;
+ allocator = calloc(1, sizeof(*allocator));
+ if (!allocator) {
+ retval = ENOMEM;
+ goto out;
+ }
retval = ext2fs_read_bitmaps(fs);
if (retval)
- goto err_bitmap;
- while ((e = ext2fs_hashmap_iter_in_order(entries, &it)))
- fs_reserve_blocks_range(fs, &e->blocks);
+ goto err_alloc;
allocator->cur_entry = NULL;
- allocator->entries = entries;
+ allocator->entries = basefs_parse(file, mountpoint);
+ if (!allocator->entries) {
+ retval = EIO;
+ goto err_alloc;
+ }
+
+ fs_reserve_blocks(fs, allocator);
/* Override the default allocator */
fs->get_alloc_block2 = basefs_block_allocator;
fs->priv_data = allocator;
- return 0;
+ goto out;
-err_bitmap:
- free(allocator);
err_alloc:
- ext2fs_hashmap_free(entries);
- return EXIT_FAILURE;
+ basefs_allocator_free(fs, allocator);
+out:
+ return retval;
}
static errcode_t basefs_block_allocator(ext2_filsys fs, blk64_t goal,
@@ -94,19 +128,9 @@ static errcode_t basefs_block_allocator(ext2_filsys fs, blk64_t goal,
void base_fs_alloc_cleanup(ext2_filsys fs)
{
- struct basefs_entry *e;
- struct ext2fs_hashmap_entry *it = NULL;
- struct base_fs_allocator *allocator = fs->priv_data;
-
- while ((e = ext2fs_hashmap_iter_in_order(allocator->entries, &it))) {
- fs_free_blocks_range(fs, &e->blocks);
- delete_block_ranges(&e->blocks);
- }
-
+ basefs_allocator_free(fs, fs->priv_data);
fs->priv_data = NULL;
fs->get_alloc_block2 = NULL;
- ext2fs_hashmap_free(allocator->entries);
- free(allocator);
}
errcode_t base_fs_alloc_set_target(ext2_filsys fs, const char *target_path,