1 #define _GNU_SOURCE
2 
3 #include "block_range.h"
4 #include <stdio.h>
5 
new_block_range(blk64_t start,blk64_t end)6 struct block_range *new_block_range(blk64_t start, blk64_t end)
7 {
8 	struct block_range *range = malloc(sizeof(*range));
9 	range->start = start;
10 	range->end = end;
11 	range->next = NULL;
12 	return range;
13 }
14 
add_blocks_to_range(struct block_range ** head,struct block_range ** tail,blk64_t blk_start,blk64_t blk_end)15 void add_blocks_to_range(struct block_range **head, struct block_range **tail,
16 			 blk64_t blk_start, blk64_t blk_end)
17 {
18 	if (*head == NULL)
19 		*head = *tail = new_block_range(blk_start, blk_end);
20 	else if ((*tail)->end + 1 == blk_start)
21 		(*tail)->end += (blk_end - blk_start + 1);
22 	else {
23 		struct block_range *range = new_block_range(blk_start, blk_end);
24 		(*tail)->next = range;
25 		*tail = range;
26 	}
27 }
28 
delete_block_ranges(struct block_range * head)29 void delete_block_ranges(struct block_range *head)
30 {
31 	struct block_range *tmp;
32 
33 	while (head) {
34 		tmp = head->next;
35 		free(head);
36 		head = tmp;
37 	}
38 }
39 
write_block_ranges(FILE * f,struct block_range * range,char * sep)40 int write_block_ranges(FILE *f, struct block_range *range,
41 				     char *sep)
42 {
43 	int len;
44 	char *buf;
45 
46 	while (range) {
47 		if (range->start == range->end)
48 			len = asprintf(&buf, "%llu%s", range->start, sep);
49 		else
50 			len = asprintf(&buf, "%llu-%llu%s", range->start,
51 				       range->end, sep);
52 		if (fwrite(buf, 1, len, f) != (size_t)len) {
53 			free(buf);
54 			return -1;
55 		}
56 		free(buf);
57 		range = range->next;
58 	}
59 
60 	len = strlen(sep);
61 	if (fseek(f, -len, SEEK_CUR) == -len)
62 		return -1;
63 	return 0;
64 }
65