From 4cb474502c1325b2325ec642a520e1ed44eb317e Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 16 May 2018 11:29:55 -0400 Subject: pretty-print the extent flags --- src/cow-extent-map.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/src/cow-extent-map.c b/src/cow-extent-map.c index 7cee70c..1d9ae2c 100644 --- a/src/cow-extent-map.c +++ b/src/cow-extent-map.c @@ -5,9 +5,10 @@ #include /* for open(2) and O_RDONLY */ #include /* for getopt_long(3gnu), struct option, optind, optarg */ #include /* PRI* */ -#include /* for printf(3p), fprintf(3p), stderr */ -#include /* exit(3p), EXIT_SUCCESS, EXIT_FAILURE */ -#include /* for strcmp(3p) */ +#include /* for bool, true, false */ +#include /* for printf(3p), fprintf(3p), sprintf(3p), stderr */ +#include /* malloc(3p), freep(3p), exit(3p), EXIT_SUCCESS, EXIT_FAILURE */ +#include /* for strcmp(3p), strlen(3p), strcpy(3p) */ #include "extent-map.h" /* for uint32_t, fiemap stuff */ @@ -18,15 +19,96 @@ exit(EXIT_INVALIDARGUMENT); \ } while(0) +struct flag { + char *name; + uint32_t value; + bool active; +}; + int print_extent(struct fiemap_extent extent) { + struct flag known_flags[] = { + {"LAST", FIEMAP_EXTENT_LAST, false}, + {"UNKNOWN", FIEMAP_EXTENT_UNKNOWN, false}, + {"DELALLOC", FIEMAP_EXTENT_DELALLOC, false}, + {"ENCODED", FIEMAP_EXTENT_ENCODED, false}, + {"DATA_ENCRYPTED", FIEMAP_EXTENT_DATA_ENCRYPTED, false}, + {"NOT_ALIGNED", FIEMAP_EXTENT_NOT_ALIGNED, false}, + {"DATA_INLINE", FIEMAP_EXTENT_DATA_INLINE, false}, + {"DATA_TAIL", FIEMAP_EXTENT_DATA_TAIL, false}, + {"UNWRITTEN", FIEMAP_EXTENT_UNWRITTEN, false}, + {"MERGED", FIEMAP_EXTENT_MERGED, false}, + {"SHARED", FIEMAP_EXTENT_SHARED, false}, + }; + uint32_t flags = extent.fe_flags; + size_t flagstr_cap = 0; + for (size_t i = 0; i < sizeof(known_flags)/sizeof(known_flags[0]); i++) { + if (!(flags & known_flags[i].value)) + continue; + known_flags[i].active = true; + flags ^= known_flags[i].value; + switch (known_flags[i].value) { + case FIEMAP_EXTENT_UNKNOWN: + if (flags & FIEMAP_EXTENT_DELALLOC) { + known_flags[i].name = "(UNKNOWN|DELALLOC)"; + flags ^= FIEMAP_EXTENT_DELALLOC; + } + break; + case FIEMAP_EXTENT_ENCODED: + if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED) { + known_flags[i].name = "(ENCODED|DATA_ENCRYPTED)"; + flags ^= FIEMAP_EXTENT_DATA_ENCRYPTED; + } + break; + case FIEMAP_EXTENT_NOT_ALIGNED: + switch (flags & (FIEMAP_EXTENT_DATA_INLINE|FIEMAP_EXTENT_DATA_TAIL)) { + case FIEMAP_EXTENT_DATA_INLINE: + known_flags[i].name = "(NOT_ALIGNED|DATA_INLINE)"; + flags ^= FIEMAP_EXTENT_DATA_INLINE; + break; + case FIEMAP_EXTENT_DATA_TAIL: + known_flags[i].name = "(NOT_ALIGNED|DATA_TAIL)"; + flags ^= FIEMAP_EXTENT_DATA_TAIL; + break; + case FIEMAP_EXTENT_DATA_INLINE|FIEMAP_EXTENT_DATA_TAIL: + known_flags[i].name = "(NOT_ALIGNED|DATA_INLINE|DATA_TAIL)"; + flags ^= FIEMAP_EXTENT_DATA_INLINE|FIEMAP_EXTENT_DATA_TAIL; + break; + } + break; + } + if (flagstr_cap) + flagstr_cap++; + flagstr_cap += strlen(known_flags[i].name); + } + if (flags) + flagstr_cap += (flagstr_cap ? 1 : 0) + 10; + char *flagstr = malloc(flagstr_cap+1); + if (!flagstr) + error(EXIT_FAILURE, errno, "malloc"); + size_t flagstr_len = 0; + for (size_t i = 0; i < sizeof(known_flags)/sizeof(known_flags[0]); i++) { + if (!known_flags[i].active) + continue; + if (flagstr_len) + flagstr[flagstr_len++] = '|'; + strcpy(&flagstr[flagstr_len], known_flags[i].name); + flagstr_len += strlen(known_flags[i].name); + } + if (flags) { + if (flagstr_len) + flagstr[flagstr_len++] = '|'; + sprintf(&flagstr[flagstr_len], "0x%08"PRIx32, flags); + }; printf("logical=%"PRIu64" " "physical=%"PRIu64" " "length=%"PRIu64" " - "flags=0x%"PRIx32"\n", + "flags=0x%08"PRIx32" (%s)\n", extent.fe_logical, extent.fe_physical, extent.fe_length, - extent.fe_flags); + extent.fe_flags, + flagstr); + free(flagstr); return 0; } -- cgit v1.2.3