range_start = atoll(block);
block = strtok_r(NULL, "-", &saveptr2);
range_end = block ? atoll(block) : range_start;
- add_blocks_to_range(&entry->head, &entry->tail, range_start,
- range_end);
+ add_blocks_to_range(&entry->blocks, range_start, range_end);
block_range = strtok_r(NULL, ",\n", &saveptr1);
}
end:
{
struct base_fs *params = data;
- params->entry.head = params->entry.tail = NULL;
params->entry.path = LINUX_S_ISREG(inode->i_mode) ? path : NULL;
return 0;
}
struct base_fs *params = data;
if (params->entry.path && !metadata)
- add_blocks_to_range(¶ms->entry.head, ¶ms->entry.tail,
- blocknr, blocknr);
+ add_blocks_to_range(¶ms->entry.blocks, blocknr, blocknr);
return 0;
}
return 0;
if (fprintf(params->file, "%s%s ", params->mountpoint,
params->entry.path) < 0
- || write_block_ranges(params->file, params->entry.head, ",")
+ || write_block_ranges(params->file, params->entry.blocks.head, ",")
|| fwrite("\n", 1, 1, params->file) != 1)
return -1;
- delete_block_ranges(params->entry.head);
+ delete_block_ranges(¶ms->entry.blocks);
return 0;
}
struct basefs_entry {
char *path;
- struct block_range *head;
- struct block_range *tail;
+ struct block_range_list blocks;
};
extern struct fsmap_format base_fs_format;
static errcode_t basefs_block_allocator(ext2_filsys, blk64_t, blk64_t *,
struct blk_alloc_ctx *ctx);
-static void fs_free_blocks_range(ext2_filsys fs, struct block_range *blocks)
+static void fs_free_blocks_range(ext2_filsys fs,
+ struct block_range_list *list)
{
+ struct block_range *blocks = list->head;
+
while (blocks) {
ext2fs_unmark_block_bitmap_range2(fs->block_map, blocks->start,
blocks->end - blocks->start + 1);
}
}
-static void fs_reserve_blocks_range(ext2_filsys fs, struct block_range *blocks)
+static void fs_reserve_blocks_range(ext2_filsys fs,
+ struct block_range_list *list)
{
+ struct block_range *blocks = list->head;
while (blocks) {
ext2fs_mark_block_bitmap_range2(fs->block_map,
blocks->start, blocks->end - blocks->start + 1);
if (retval)
goto err_bitmap;
while ((e = ext2fs_hashmap_iter_in_order(entries, &it)))
- fs_reserve_blocks_range(fs, e->head);
+ fs_reserve_blocks_range(fs, &e->blocks);
allocator->cur_entry = NULL;
allocator->entries = entries;
blk64_t *ret, struct blk_alloc_ctx *ctx)
{
errcode_t retval;
- struct block_range *next_range;
struct base_fs_allocator *allocator = fs->priv_data;
struct basefs_entry *e = allocator->cur_entry;
/* Try to get a block from the base_fs */
- if (e && e->head && ctx && (ctx->flags & BLOCK_ALLOC_DATA)) {
- *ret = e->head->start;
- e->head->start += 1;
- if (e->head->start > e->head->end) {
- next_range = e->head->next;
- free(e->head);
- e->head = next_range;
- }
+ if (e && e->blocks.head && ctx && (ctx->flags & BLOCK_ALLOC_DATA)) {
+ *ret = consume_next_block(&e->blocks);
} else { /* Allocate a new block */
retval = ext2fs_new_block2(fs, goal, fs->block_map, ret);
if (retval)
struct base_fs_allocator *allocator = fs->priv_data;
while ((e = ext2fs_hashmap_iter_in_order(allocator->entries, &it))) {
- fs_free_blocks_range(fs, e->head);
- delete_block_ranges(e->head);
- e->head = e->tail = NULL;
+ fs_free_blocks_range(fs, &e->blocks);
+ delete_block_ranges(&e->blocks);
}
fs->priv_data = NULL;
if (!allocator || !allocator->cur_entry || mode != S_IFREG)
return 0;
- fs_free_blocks_range(fs, allocator->cur_entry->head);
- delete_block_ranges(allocator->cur_entry->head);
- allocator->cur_entry->head = allocator->cur_entry->tail = NULL;
- allocator->cur_entry = NULL;
+ fs_free_blocks_range(fs, &allocator->cur_entry->blocks);
+ delete_block_ranges(&allocator->cur_entry->blocks);
return 0;
}
FILE *f;
const char *mountpoint;
- struct {
- const char *filename;
- struct block_range *head;
- struct block_range *tail;
- } entry;
+ const char *filename;
+ struct block_range_list blocks;
};
static void *init(const char *file, const char *mountpoint)
{
- struct block_list *params = malloc(sizeof(*params));
+ struct block_list *params = calloc(1, sizeof(*params));
if (!params)
return NULL;
{
struct block_list *params = data;
- params->entry.head = params->entry.tail = NULL;
- params->entry.filename = LINUX_S_ISREG(inode->i_mode) ? path : NULL;
+ params->filename = LINUX_S_ISREG(inode->i_mode) ? path : NULL;
return 0;
}
{
struct block_list *params = data;
- if (params->entry.filename && !metadata)
- add_blocks_to_range(¶ms->entry.head, ¶ms->entry.tail,
- blocknr, blocknr);
+ if (params->filename && !metadata)
+ add_blocks_to_range(¶ms->blocks, blocknr, blocknr);
return 0;
}
{
struct block_list *params = data;
- if (!params->entry.filename || !params->entry.head)
+ if (!params->filename || !params->blocks.head)
return 0;
if (fprintf(params->f, "%s%s ", params->mountpoint,
- params->entry.filename) < 0
- || write_block_ranges(params->f, params->entry.head, " ")
+ params->filename) < 0
+ || write_block_ranges(params->f, params->blocks.head, " ")
|| fwrite("\n", 1, 1, params->f) != 1)
return -1;
- delete_block_ranges(params->entry.head);
+ delete_block_ranges(¶ms->blocks);
return 0;
}
return range;
}
-void add_blocks_to_range(struct block_range **head, struct block_range **tail,
- blk64_t blk_start, blk64_t blk_end)
+void add_blocks_to_range(struct block_range_list *list, blk64_t blk_start,
+ blk64_t blk_end)
{
- if (*head == NULL)
- *head = *tail = new_block_range(blk_start, blk_end);
- else if ((*tail)->end + 1 == blk_start)
- (*tail)->end += (blk_end - blk_start + 1);
+ if (list->head == NULL)
+ list->head = list->tail = new_block_range(blk_start, blk_end);
+ else if (list->tail->end + 1 == blk_start)
+ list->tail->end += (blk_end - blk_start + 1);
else {
struct block_range *range = new_block_range(blk_start, blk_end);
- (*tail)->next = range;
- *tail = range;
+ list->tail->next = range;
+ list->tail = range;
}
}
-void delete_block_ranges(struct block_range *head)
+static void remove_head(struct block_range_list *list)
{
- struct block_range *tmp;
+ struct block_range *next_range = list->head->next;
- while (head) {
- tmp = head->next;
- free(head);
- head = tmp;
- }
+ free(list->head);
+ if (next_range == NULL)
+ list->head = list->tail = NULL;
+ else
+ list->head = next_range;
+}
+
+void delete_block_ranges(struct block_range_list *list)
+{
+ while (list->head)
+ remove_head(list);
}
int write_block_ranges(FILE *f, struct block_range *range,
return -1;
return 0;
}
+
+blk64_t consume_next_block(struct block_range_list *list)
+{
+ blk64_t ret = list->head->start;
+
+ list->head->start += 1;
+ if (list->head->start > list->head->end)
+ remove_head(list);
+ return ret;
+}
struct block_range *next;
};
-void add_blocks_to_range(struct block_range **head, struct block_range **tail,
- blk64_t blk_start, blk64_t blk_end);
-void delete_block_ranges(struct block_range *head);
+struct block_range_list {
+ struct block_range *head;
+ struct block_range *tail;
+};
+
+void add_blocks_to_range(struct block_range_list *list, blk64_t blk_start,
+ blk64_t blk_end);
+void delete_block_ranges(struct block_range_list *list);
int write_block_ranges(FILE *f, struct block_range *range, char *sep);
+/*
+ * Given a non-empty range list, return the next block and remove it from the
+ * list.
+ */
+blk64_t consume_next_block(struct block_range_list *list);
+
#endif /* !BLOCK_RANGE_H */