Skip to content

Commit d72ab68

Browse files
committed
btrfs-progs: print-tree: use readable_flag_entry for inode flags
The current print-tree can not handle unsupported inode flags, e.g. created by Synology's out-of-tree btrfs implementation. The existing one just checks all the supported flags, and if no flag hits, it will output "none" no matter if there is any unsupported one. Fix this by implementing sprint_readable_flag(), and use the same handling of print_readable_flag(). Although for inode flag, adds one extra handling to output "none" if no flag hit at all. Signed-off-by: Qu Wenruo <wqu@suse.com>
1 parent 010b93f commit d72ab68

File tree

1 file changed

+58
-31
lines changed

1 file changed

+58
-31
lines changed

kernel-shared/print-tree.c

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,43 @@ static void print_inode_ref_item(struct extent_buffer *eb, u32 size,
183183
}
184184
}
185185

186+
struct readable_flag_entry {
187+
u64 bit;
188+
char *output;
189+
};
190+
186191
/* The minimal length for the string buffer of block group/chunk flags */
187192
#define BG_FLAG_STRING_LEN 64
188193

194+
static void sprint_readable_flag(char *restrict dest, u64 flag,
195+
struct readable_flag_entry *array,
196+
int array_size)
197+
{
198+
int i;
199+
u64 supported_flags = 0;
200+
int cur = 0;
201+
202+
dest[0] = '\0';
203+
for (i = 0; i < array_size; i++)
204+
supported_flags |= array[i].bit;
205+
206+
for (i = 0; i < array_size; i++) {
207+
struct readable_flag_entry *entry = array + i;
208+
209+
if ((flag & supported_flags) && (flag & entry->bit)) {
210+
if (dest[0])
211+
cur += sprintf(dest + cur, "|");
212+
cur += sprintf(dest + cur, "%s", entry->output);
213+
}
214+
}
215+
flag &= ~supported_flags;
216+
if (flag) {
217+
if (dest[0])
218+
cur += sprintf(dest + cur, "|");
219+
cur += sprintf(dest + cur, "UNKNOWN: 0x%llx", flag);
220+
}
221+
}
222+
189223
static void bg_flags_to_str(u64 flags, char *ret)
190224
{
191225
int empty = 1;
@@ -932,37 +966,35 @@ static void print_uuid_item(struct extent_buffer *l, unsigned long offset,
932966
}
933967
}
934968

935-
/* Btrfs inode flag stringification helper */
936-
#define STRCAT_ONE_INODE_FLAG(flags, name, empty, dst) ({ \
937-
if (flags & BTRFS_INODE_##name) { \
938-
if (!empty) \
939-
strcat(dst, "|"); \
940-
strcat(dst, #name); \
941-
empty = 0; \
942-
} \
943-
})
969+
#define DEF_INODE_FLAG_ENTRY(name) \
970+
{ BTRFS_INODE_##name, #name }
971+
972+
static struct readable_flag_entry inode_flags_array[] = {
973+
DEF_INODE_FLAG_ENTRY(NODATASUM),
974+
DEF_INODE_FLAG_ENTRY(NODATACOW),
975+
DEF_INODE_FLAG_ENTRY(READONLY),
976+
DEF_INODE_FLAG_ENTRY(NOCOMPRESS),
977+
DEF_INODE_FLAG_ENTRY(PREALLOC),
978+
DEF_INODE_FLAG_ENTRY(SYNC),
979+
DEF_INODE_FLAG_ENTRY(IMMUTABLE),
980+
DEF_INODE_FLAG_ENTRY(APPEND),
981+
DEF_INODE_FLAG_ENTRY(NODUMP),
982+
DEF_INODE_FLAG_ENTRY(NOATIME),
983+
DEF_INODE_FLAG_ENTRY(DIRSYNC),
984+
DEF_INODE_FLAG_ENTRY(COMPRESS),
985+
DEF_INODE_FLAG_ENTRY(ROOT_ITEM_INIT),
986+
};
987+
static const int inode_flags_num = ARRAY_SIZE(inode_flags_array);
944988

945989
/*
946-
* Caller should ensure sizeof(*ret) >= 102: all characters plus '|' of
947-
* BTRFS_INODE_* flags
990+
* Caller should ensure sizeof(*ret) >= 129: all characters plus '|' of
991+
* BTRFS_INODE_* flags + "UNKNOWN: 0xffffffffffffffff"
948992
*/
949993
static void inode_flags_to_str(u64 flags, char *ret)
950994
{
951-
int empty = 1;
952-
953-
STRCAT_ONE_INODE_FLAG(flags, NODATASUM, empty, ret);
954-
STRCAT_ONE_INODE_FLAG(flags, NODATACOW, empty, ret);
955-
STRCAT_ONE_INODE_FLAG(flags, READONLY, empty, ret);
956-
STRCAT_ONE_INODE_FLAG(flags, NOCOMPRESS, empty, ret);
957-
STRCAT_ONE_INODE_FLAG(flags, PREALLOC, empty, ret);
958-
STRCAT_ONE_INODE_FLAG(flags, SYNC, empty, ret);
959-
STRCAT_ONE_INODE_FLAG(flags, IMMUTABLE, empty, ret);
960-
STRCAT_ONE_INODE_FLAG(flags, APPEND, empty, ret);
961-
STRCAT_ONE_INODE_FLAG(flags, NODUMP, empty, ret);
962-
STRCAT_ONE_INODE_FLAG(flags, NOATIME, empty, ret);
963-
STRCAT_ONE_INODE_FLAG(flags, DIRSYNC, empty, ret);
964-
STRCAT_ONE_INODE_FLAG(flags, COMPRESS, empty, ret);
965-
if (empty)
995+
sprint_readable_flag(ret, flags, inode_flags_array, inode_flags_num);
996+
/* No flag hit at all, set the output to "none"*/
997+
if (!ret[0])
966998
strcat(ret, "none");
967999
}
9681000

@@ -1876,11 +1908,6 @@ static int check_csum_sblock(void *sb, int csum_size, u16 csum_type)
18761908
return !memcmp(sb, result, csum_size);
18771909
}
18781910

1879-
struct readable_flag_entry {
1880-
u64 bit;
1881-
char *output;
1882-
};
1883-
18841911
#define DEF_COMPAT_RO_FLAG_ENTRY(bit_name) \
18851912
{BTRFS_FEATURE_COMPAT_RO_##bit_name, #bit_name}
18861913

0 commit comments

Comments
 (0)