81 lines
1.7 KiB
C
81 lines
1.7 KiB
C
#define _GNU_SOURCE
|
|
|
|
#include "block_range.h"
|
|
#include <stdio.h>
|
|
|
|
struct block_range *new_block_range(blk64_t start, blk64_t end)
|
|
{
|
|
struct block_range *range = malloc(sizeof(*range));
|
|
range->start = start;
|
|
range->end = end;
|
|
range->next = NULL;
|
|
return range;
|
|
}
|
|
|
|
void add_blocks_to_range(struct block_range_list *list, blk64_t blk_start,
|
|
blk64_t blk_end)
|
|
{
|
|
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);
|
|
list->tail->next = range;
|
|
list->tail = range;
|
|
}
|
|
}
|
|
|
|
static void remove_head(struct block_range_list *list)
|
|
{
|
|
struct block_range *next_range = list->head->next;
|
|
|
|
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,
|
|
char *sep)
|
|
{
|
|
int len;
|
|
char *buf;
|
|
|
|
while (range) {
|
|
if (range->start == range->end)
|
|
len = asprintf(&buf, "%llu%s", range->start, sep);
|
|
else
|
|
len = asprintf(&buf, "%llu-%llu%s", range->start,
|
|
range->end, sep);
|
|
if (fwrite(buf, 1, len, f) != (size_t)len) {
|
|
free(buf);
|
|
return -1;
|
|
}
|
|
free(buf);
|
|
range = range->next;
|
|
}
|
|
|
|
len = strlen(sep);
|
|
if (fseek(f, -len, SEEK_CUR) == -len)
|
|
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;
|
|
}
|