@@ -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+
189223static 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 */
949993static 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