summaryrefslogtreecommitdiffstats
path: root/contrib/android/block_range.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:49:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:49:25 +0000
commit464df1d5e5ab1322e2dd0a7796939fff1aeefa9a (patch)
tree6a403684e0978f0287d7f0ec0e5aab1fd31a59e1 /contrib/android/block_range.c
parentInitial commit. (diff)
downloade2fsprogs-db58a52ab489b66cea7224323c4c6171ccc2a9dd.tar.xz
e2fsprogs-db58a52ab489b66cea7224323c4c6171ccc2a9dd.zip
Adding upstream version 1.47.0.upstream/1.47.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/android/block_range.c')
-rw-r--r--contrib/android/block_range.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/contrib/android/block_range.c b/contrib/android/block_range.c
new file mode 100644
index 0000000..0a06882
--- /dev/null
+++ b/contrib/android/block_range.c
@@ -0,0 +1,80 @@
+#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;
+}