• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #endif
4 
5 #include "block_range.h"
6 #include <stdio.h>
7 
new_block_range(blk64_t start,blk64_t end)8 struct block_range *new_block_range(blk64_t start, blk64_t end)
9 {
10 	struct block_range *range = malloc(sizeof(*range));
11 	range->start = start;
12 	range->end = end;
13 	range->next = NULL;
14 	return range;
15 }
16 
add_blocks_to_range(struct block_range_list * list,blk64_t blk_start,blk64_t blk_end)17 void add_blocks_to_range(struct block_range_list *list, blk64_t blk_start,
18 			 blk64_t blk_end)
19 {
20 	if (list->head == NULL)
21 		list->head = list->tail = new_block_range(blk_start, blk_end);
22 	else if (list->tail->end + 1 == blk_start)
23 		list->tail->end += (blk_end - blk_start + 1);
24 	else {
25 		struct block_range *range = new_block_range(blk_start, blk_end);
26 		list->tail->next = range;
27 		list->tail = range;
28 	}
29 }
30 
remove_head(struct block_range_list * list)31 static void remove_head(struct block_range_list *list)
32 {
33 	struct block_range *next_range = list->head->next;
34 
35 	free(list->head);
36 	if (next_range == NULL)
37 		list->head = list->tail = NULL;
38 	else
39 		list->head = next_range;
40 }
41 
delete_block_ranges(struct block_range_list * list)42 void delete_block_ranges(struct block_range_list *list)
43 {
44 	while (list->head)
45 		remove_head(list);
46 }
47 
write_block_ranges(FILE * f,struct block_range * range,char * sep)48 int write_block_ranges(FILE *f, struct block_range *range,
49 				     char *sep)
50 {
51 	int len;
52 	char *buf;
53 
54 	while (range) {
55 		if (range->start == range->end)
56 			len = asprintf(&buf, "%llu%s", range->start, sep);
57 		else
58 			len = asprintf(&buf, "%llu-%llu%s", range->start,
59 				       range->end, sep);
60 		if (fwrite(buf, 1, len, f) != (size_t)len) {
61 			free(buf);
62 			return -1;
63 		}
64 		free(buf);
65 		range = range->next;
66 	}
67 
68 	len = strlen(sep);
69 	if (fseek(f, -len, SEEK_CUR) == -len)
70 		return -1;
71 	return 0;
72 }
73 
consume_next_block(struct block_range_list * list)74 blk64_t consume_next_block(struct block_range_list *list)
75 {
76 	blk64_t ret = list->head->start;
77 
78 	list->head->start += 1;
79 	if (list->head->start > list->head->end)
80 		remove_head(list);
81 	return ret;
82 }
83