#include /* for errno */ #include /* for error(3gnu) */ #include /* PRI* */ #include /* for FIEMAP_EXTENT_* */ #include /* for bool, true, false */ #include /* sprintf(3p) */ #include /* for malloc(3p), EXIT_FAILURE */ #include /* for strlen(3p), strcpy(3p) */ #include "extent-map.h" struct flag { char *name; uint32_t value; bool active; }; char *strextentflags(uint32_t flags) { 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}, }; 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); }; return flagstr; }