3 #include "basefs_allocator.h"
4 #include "block_range.h"
8 struct base_fs_allocator {
9 struct ext2fs_hashmap *entries;
10 struct basefs_entry *cur_entry;
13 static errcode_t basefs_block_allocator(ext2_filsys, blk64_t, blk64_t *,
14 struct blk_alloc_ctx *ctx);
16 static void fs_free_blocks_range(ext2_filsys fs, struct block_range *blocks)
19 ext2fs_unmark_block_bitmap_range2(fs->block_map, blocks->start,
20 blocks->end - blocks->start + 1);
21 blocks = blocks->next;
25 static void fs_reserve_blocks_range(ext2_filsys fs, struct block_range *blocks)
28 ext2fs_mark_block_bitmap_range2(fs->block_map,
29 blocks->start, blocks->end - blocks->start + 1);
30 blocks = blocks->next;
34 errcode_t base_fs_alloc_load(ext2_filsys fs, const char *file,
35 const char *mountpoint)
38 struct basefs_entry *e;
39 struct ext2fs_hashmap_entry *it = NULL;
40 struct base_fs_allocator *allocator;
41 struct ext2fs_hashmap *entries = basefs_parse(file, mountpoint);
45 allocator = malloc(sizeof(*allocator));
49 retval = ext2fs_read_bitmaps(fs);
52 while ((e = ext2fs_hashmap_iter_in_order(entries, &it)))
53 fs_reserve_blocks_range(fs, e->head);
55 allocator->cur_entry = NULL;
56 allocator->entries = entries;
58 /* Override the default allocator */
59 fs->get_alloc_block2 = basefs_block_allocator;
60 fs->priv_data = allocator;
67 ext2fs_hashmap_free(entries);
71 static errcode_t basefs_block_allocator(ext2_filsys fs, blk64_t goal,
72 blk64_t *ret, struct blk_alloc_ctx *ctx)
75 struct block_range *next_range;
76 struct base_fs_allocator *allocator = fs->priv_data;
77 struct basefs_entry *e = allocator->cur_entry;
79 /* Try to get a block from the base_fs */
80 if (e && e->head && ctx && (ctx->flags & BLOCK_ALLOC_DATA)) {
81 *ret = e->head->start;
83 if (e->head->start > e->head->end) {
84 next_range = e->head->next;
88 } else { /* Allocate a new block */
89 retval = ext2fs_new_block2(fs, goal, fs->block_map, ret);
92 ext2fs_mark_block_bitmap2(fs->block_map, *ret);
97 void base_fs_alloc_cleanup(ext2_filsys fs)
99 struct basefs_entry *e;
100 struct ext2fs_hashmap_entry *it = NULL;
101 struct base_fs_allocator *allocator = fs->priv_data;
103 while ((e = ext2fs_hashmap_iter_in_order(allocator->entries, &it))) {
104 fs_free_blocks_range(fs, e->head);
105 delete_block_ranges(e->head);
106 e->head = e->tail = NULL;
109 fs->priv_data = NULL;
110 fs->get_alloc_block2 = NULL;
111 ext2fs_hashmap_free(allocator->entries);
115 errcode_t base_fs_alloc_set_target(ext2_filsys fs, const char *target_path,
116 const char *name EXT2FS_ATTR((unused)),
117 ext2_ino_t parent_ino EXT2FS_ATTR((unused)),
118 ext2_ino_t root EXT2FS_ATTR((unused)), mode_t mode)
120 struct base_fs_allocator *allocator = fs->priv_data;
126 allocator->cur_entry = ext2fs_hashmap_lookup(allocator->entries,
128 strlen(target_path));
132 errcode_t base_fs_alloc_unset_target(ext2_filsys fs,
133 const char *target_path EXT2FS_ATTR((unused)),
134 const char *name EXT2FS_ATTR((unused)),
135 ext2_ino_t parent_ino EXT2FS_ATTR((unused)),
136 ext2_ino_t root EXT2FS_ATTR((unused)), mode_t mode)
138 struct base_fs_allocator *allocator = fs->priv_data;
140 if (!allocator || !allocator->cur_entry || mode != S_IFREG)
143 fs_free_blocks_range(fs, allocator->cur_entry->head);
144 delete_block_ranges(allocator->cur_entry->head);
145 allocator->cur_entry->head = allocator->cur_entry->tail = NULL;
146 allocator->cur_entry = NULL;