LCOV - code coverage report
Current view: top level - libgfs2 - meta.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 49 104 47.1 %
Date: 2023-10-25 12:04:14 Functions: 4 5 80.0 %

          Line data    Source code
       1             : #include <stdint.h>
       2             : #include <string.h>
       3             : #include <uuid.h>
       4             : #include "libgfs2.h"
       5             : #include "clusterautoconfig.h"
       6             : 
       7             : #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
       8             : #define SYM(x) { x, #x, 0 },
       9             : #define PREFIX_SYM(p,x) { p##x, #p #x, sizeof #p - 1 },
      10             : 
      11             : const struct lgfs2_symbolic lgfs2_metatypes[] = {
      12             : SYM(GFS2_METATYPE_NONE)
      13             : SYM(GFS2_METATYPE_SB)
      14             : SYM(GFS2_METATYPE_RG)
      15             : SYM(GFS2_METATYPE_RB)
      16             : SYM(GFS2_METATYPE_DI)
      17             : SYM(GFS2_METATYPE_IN)
      18             : SYM(GFS2_METATYPE_LF)
      19             : SYM(GFS2_METATYPE_JD)
      20             : SYM(GFS2_METATYPE_LH)
      21             : SYM(GFS2_METATYPE_LD)
      22             : SYM(GFS2_METATYPE_LB)
      23             : SYM(GFS2_METATYPE_EA)
      24             : SYM(GFS2_METATYPE_ED)
      25             : SYM(GFS2_METATYPE_QC)
      26             : };
      27             : 
      28             : const unsigned lgfs2_metatype_size = ARRAY_SIZE(lgfs2_metatypes);
      29             : 
      30             : const struct lgfs2_symbolic lgfs2_metaformats[] = {
      31             : SYM(GFS2_FORMAT_NONE)
      32             : SYM(GFS2_FORMAT_SB)
      33             : SYM(GFS2_FORMAT_RG)
      34             : SYM(GFS2_FORMAT_RB)
      35             : SYM(GFS2_FORMAT_DI)
      36             : SYM(GFS2_FORMAT_IN)
      37             : SYM(GFS2_FORMAT_LF)
      38             : SYM(GFS2_FORMAT_JD)
      39             : SYM(GFS2_FORMAT_LH)
      40             : SYM(GFS2_FORMAT_LD)
      41             : SYM(GFS2_FORMAT_LB)
      42             : SYM(GFS2_FORMAT_EA)
      43             : SYM(GFS2_FORMAT_ED)
      44             : SYM(GFS2_FORMAT_QC)
      45             : SYM(GFS2_FORMAT_RI)
      46             : SYM(GFS2_FORMAT_DE)
      47             : SYM(GFS2_FORMAT_QU)
      48             : };
      49             : 
      50             : const unsigned lgfs2_metaformat_size = ARRAY_SIZE(lgfs2_metaformats);
      51             : 
      52             : const struct lgfs2_symbolic lgfs2_di_flags[] = {
      53             : SYM(GFS2_DIF_JDATA)
      54             : SYM(GFS2_DIF_EXHASH)
      55             : SYM(GFS2_DIF_UNUSED)
      56             : SYM(GFS2_DIF_EA_INDIRECT)
      57             : SYM(GFS2_DIF_DIRECTIO)
      58             : SYM(GFS2_DIF_IMMUTABLE)
      59             : SYM(GFS2_DIF_APPENDONLY)
      60             : SYM(GFS2_DIF_NOATIME)
      61             : SYM(GFS2_DIF_SYNC)
      62             : SYM(GFS2_DIF_SYSTEM)
      63             : SYM(GFS2_DIF_TRUNC_IN_PROG)
      64             : SYM(GFS2_DIF_INHERIT_DIRECTIO)
      65             : SYM(GFS2_DIF_INHERIT_JDATA)
      66             : };
      67             : 
      68             : const unsigned lgfs2_di_flag_size = ARRAY_SIZE(lgfs2_di_flags);
      69             : 
      70             : const struct lgfs2_symbolic lgfs2_lh_flags[] = {
      71             : PREFIX_SYM(GFS2_LOG_HEAD_, UNMOUNT)
      72             : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, NORMAL)
      73             : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, SYNC)
      74             : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, SHUTDOWN)
      75             : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, FREEZE)
      76             : PREFIX_SYM(GFS2_LOG_HEAD_, RECOVERY)
      77             : PREFIX_SYM(GFS2_LOG_HEAD_, USERSPACE)
      78             : 
      79             : /* Log flush callers */
      80             : PREFIX_SYM(GFS2_LFC_, SHUTDOWN)
      81             : PREFIX_SYM(GFS2_LFC_, JDATA_WPAGES)
      82             : PREFIX_SYM(GFS2_LFC_, SET_FLAGS)
      83             : PREFIX_SYM(GFS2_LFC_, AIL_EMPTY_GL)
      84             : PREFIX_SYM(GFS2_LFC_, AIL_FLUSH)
      85             : PREFIX_SYM(GFS2_LFC_, RGRP_GO_SYNC)
      86             : PREFIX_SYM(GFS2_LFC_, INODE_GO_SYNC)
      87             : PREFIX_SYM(GFS2_LFC_, INODE_GO_INVAL)
      88             : PREFIX_SYM(GFS2_LFC_, FREEZE_GO_SYNC)
      89             : PREFIX_SYM(GFS2_LFC_, KILL_SB)
      90             : PREFIX_SYM(GFS2_LFC_, DO_SYNC)
      91             : PREFIX_SYM(GFS2_LFC_, INPLACE_RESERVE)
      92             : PREFIX_SYM(GFS2_LFC_, WRITE_INODE)
      93             : PREFIX_SYM(GFS2_LFC_, MAKE_FS_RO)
      94             : PREFIX_SYM(GFS2_LFC_, SYNC_FS)
      95             : PREFIX_SYM(GFS2_LFC_, EVICT_INODE)
      96             : PREFIX_SYM(GFS2_LFC_, TRANS_END)
      97             : PREFIX_SYM(GFS2_LFC_, LOGD_JFLUSH_REQD)
      98             : PREFIX_SYM(GFS2_LFC_, LOGD_AIL_FLUSH_REQD)
      99             : };
     100             : 
     101             : const unsigned int lgfs2_lh_flag_size = ARRAY_SIZE(lgfs2_lh_flags);
     102             : 
     103             : const struct lgfs2_symbolic lgfs2_ld_types[] = {
     104             : SYM(GFS2_LOG_DESC_METADATA)
     105             : SYM(GFS2_LOG_DESC_REVOKE)
     106             : SYM(GFS2_LOG_DESC_JDATA)
     107             : };
     108             : 
     109             : const unsigned int lgfs2_ld_type_size = ARRAY_SIZE(lgfs2_ld_types);
     110             : 
     111             : #undef SYM
     112             : 
     113             : 
     114             : 
     115             : 
     116             : #define F(f,...)  { .name = #f, \
     117             :                     .offset = offsetof(struct STRUCT, f), \
     118             :                     .length = sizeof(((struct STRUCT *)(0))->f), \
     119             :                     __VA_ARGS__ },
     120             : #define FP(f,...) F(f, .flags = LGFS2_MFF_POINTER, __VA_ARGS__)
     121             : #define RF(f) F(f, .flags = LGFS2_MFF_RESERVED)
     122             : #define RFP(f,...) F(f, .flags = LGFS2_MFF_POINTER|LGFS2_MFF_RESERVED, __VA_ARGS__)
     123             : 
     124             : 
     125             : #define MH(f) F(f.mh_magic) \
     126             :               F(f.mh_type, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metatypes, .nsyms=ARRAY_SIZE(lgfs2_metatypes)) \
     127             :               RF(f.__pad0) \
     128             :               F(f.mh_format, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metaformats, .nsyms=ARRAY_SIZE(lgfs2_metaformats)) \
     129             :               F(f.mh_jid)
     130             : 
     131             : #define IN(f,...) F(f.no_formal_ino) \
     132             :                   FP(f.no_addr, __VA_ARGS__)
     133             : 
     134             : #define INR(f,...) RF(f.no_formal_ino) \
     135             :                    RFP(f.no_addr, __VA_ARGS__)
     136             : #define ANY_COMMON_BLOCK (1 << LGFS2_MT_DIR_LEAF) | \
     137             :                          (1 << LGFS2_MT_JRNL_DATA) | \
     138             :                          (1 << LGFS2_MT_EA_ATTR) | \
     139             :                          (1 << LGFS2_MT_EA_DATA) | \
     140             :                          (1 << LGFS2_MT_DATA)
     141             : 
     142             : #define ANY_GFS2_BLOCK (1 << LGFS2_MT_GFS2_DINODE) | \
     143             :                        (1 << LGFS2_MT_GFS2_INDIRECT) | \
     144             :                        (1 << LGFS2_MT_GFS2_LOG_HEADER) | \
     145             :                        (1 << LGFS2_MT_GFS2_LOG_DESC) | \
     146             :                        (1 << LGFS2_MT_GFS2_LOG_BLOCK) | \
     147             :                        ANY_COMMON_BLOCK
     148             : 
     149             : #define ANY_GFS_BLOCK (1 << LGFS2_MT_GFS_DINODE) | \
     150             :                       (1 << LGFS2_MT_GFS_INDIRECT) | \
     151             :                       ANY_COMMON_BLOCK
     152             : 
     153             : #undef STRUCT
     154             : #define STRUCT gfs2_sb
     155             : 
     156             : static const struct lgfs2_metafield gfs2_sb_fields[] = {
     157             : MH(sb_header)
     158             : F(sb_fs_format)
     159             : F(sb_multihost_format)
     160             : RF(__pad0)
     161             : F(sb_bsize, .flags = LGFS2_MFF_BYTES)
     162             : F(sb_bsize_shift, .flags = LGFS2_MFF_BYTES|LGFS2_MFF_SHIFT)
     163             : RF(__pad1)
     164             : IN(sb_master_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     165             : INR(__pad2, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     166             : IN(sb_root_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     167             : F(sb_lockproto, .flags = LGFS2_MFF_STRING)
     168             : F(sb_locktable, .flags = LGFS2_MFF_STRING)
     169             : INR(__pad3, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     170             : INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     171             : F(sb_uuid, .flags = LGFS2_MFF_UUID)
     172             : };
     173             : 
     174             : #undef STRUCT
     175             : #define STRUCT gfs2_rindex
     176             : 
     177             : static const struct lgfs2_metafield gfs2_rindex_fields[] = {
     178             : FP(ri_addr, .points_to = (1 << LGFS2_MT_GFS2_RGRP))
     179             : F(ri_length, .flags = LGFS2_MFF_FSBLOCKS)
     180             : RF(__pad)
     181             : FP(ri_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE))
     182             : F(ri_data, .flags = LGFS2_MFF_FSBLOCKS)
     183             : F(ri_bitbytes, .flags = LGFS2_MFF_BYTES)
     184             : F(ri_reserved)
     185             : };
     186             : 
     187             : #undef STRUCT
     188             : #define STRUCT gfs2_rgrp
     189             : 
     190             : static const struct lgfs2_metafield gfs2_rgrp_fields[] = {
     191             : MH(rg_header)
     192             : F(rg_flags)
     193             : F(rg_free, .flags = LGFS2_MFF_FSBLOCKS)
     194             : F(rg_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
     195             : FP(rg_skip, .points_to = (1 << LGFS2_MT_GFS2_RGRP))
     196             : F(rg_igeneration)
     197             : FP(rg_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE))
     198             : F(rg_data, .flags = LGFS2_MFF_FSBLOCKS)
     199             : F(rg_bitbytes, .flags = LGFS2_MFF_BYTES)
     200             : F(rg_crc, .flags = LGFS2_MFF_CHECK)
     201             : RF(rg_reserved)
     202             : };
     203             : 
     204             : #undef STRUCT
     205             : struct gfs2_rgrp_bitmap { struct gfs2_meta_header rb_header; };
     206             : #define STRUCT gfs2_rgrp_bitmap
     207             : 
     208             : static const struct lgfs2_metafield gfs2_rgrp_bitmap_fields[] = {
     209             : MH(rb_header)
     210             : };
     211             : 
     212             : #undef STRUCT
     213             : #define STRUCT gfs2_dinode
     214             : 
     215             : static const struct lgfs2_metafield gfs2_dinode_fields[] = {
     216             : MH(di_header)
     217             : IN(di_num, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     218             : F(di_mode, .flags = LGFS2_MFF_MODE)
     219             : F(di_uid, .flags = LGFS2_MFF_UID)
     220             : F(di_gid, .flags = LGFS2_MFF_GID)
     221             : F(di_nlink)
     222             : F(di_size, .flags = LGFS2_MFF_BYTES)
     223             : F(di_blocks, .flags = LGFS2_MFF_FSBLOCKS)
     224             : F(di_atime, .flags = LGFS2_MFF_SECS)
     225             : F(di_mtime, .flags = LGFS2_MFF_SECS)
     226             : F(di_ctime, .flags = LGFS2_MFF_SECS)
     227             : F(di_major, .flags = LGFS2_MFF_MAJOR)
     228             : F(di_minor, .flags = LGFS2_MFF_MINOR)
     229             : FP(di_goal_meta, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE))
     230             : FP(di_goal_data, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE))
     231             : F(di_generation)
     232             : F(di_flags, .flags = LGFS2_MFF_MASK, .symtab=lgfs2_di_flags, .nsyms=ARRAY_SIZE(lgfs2_di_flags))
     233             : F(di_payload_format)
     234             : RF(__pad1)
     235             : F(di_height)
     236             : RF(__pad2)
     237             : RF(__pad3)
     238             : F(di_depth)
     239             : F(di_entries)
     240             : INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     241             : FP(di_eattr, .points_to = (1 << LGFS2_MT_EA_ATTR)|(1 << LGFS2_MT_GFS2_INDIRECT))
     242             : F(di_atime_nsec, .flags = LGFS2_MFF_NSECS)
     243             : F(di_mtime_nsec, .flags = LGFS2_MFF_NSECS)
     244             : F(di_ctime_nsec, .flags = LGFS2_MFF_NSECS)
     245             : RF(di_reserved)
     246             : };
     247             : 
     248             : #undef STRUCT
     249             : struct gfs2_indirect { struct gfs2_meta_header in_header; };
     250             : #define STRUCT gfs2_indirect
     251             : 
     252             : static const struct lgfs2_metafield gfs2_indirect_fields[] = {
     253             : MH(in_header)
     254             : };
     255             : 
     256             : #undef STRUCT
     257             : #define STRUCT gfs2_leaf
     258             : 
     259             : static const struct lgfs2_metafield gfs2_leaf_fields[] = {
     260             : MH(lf_header)
     261             : F(lf_depth)
     262             : F(lf_entries)
     263             : F(lf_dirent_format)
     264             : F(lf_next)
     265             : #ifdef GFS2_HAS_LEAF_HINTS
     266             : FP(lf_inode, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     267             : F(lf_dist)
     268             : F(lf_nsec, .flags = LGFS2_MFF_NSECS)
     269             : F(lf_sec, .flags = LGFS2_MFF_SECS)
     270             : RF(lf_reserved2)
     271             : #else
     272             : RF(lf_reserved)
     273             : #endif
     274             : };
     275             : 
     276             : #undef STRUCT
     277             : struct gfs2_jrnl_data { struct gfs2_meta_header jd_header; };
     278             : #define STRUCT gfs2_jrnl_data
     279             : 
     280             : static const struct lgfs2_metafield gfs2_jdata_fields[] = {
     281             : MH(jd_header)
     282             : };
     283             : 
     284             : #undef STRUCT
     285             : #define STRUCT gfs2_log_header
     286             : 
     287             : static const struct lgfs2_metafield gfs2_log_header_fields[] = {
     288             : MH(lh_header)
     289             : F(lh_sequence)
     290             : F(lh_flags, .flags = LGFS2_MFF_MASK, .symtab = lgfs2_lh_flags, .nsyms = ARRAY_SIZE(lgfs2_lh_flags))
     291             : F(lh_tail)
     292             : F(lh_blkno)
     293             : F(lh_hash, .flags = LGFS2_MFF_CHECK)
     294             : F(lh_crc, .flags = LGFS2_MFF_CHECK)
     295             : F(lh_nsec, .flags = LGFS2_MFF_NSECS)
     296             : F(lh_sec, .flags = LGFS2_MFF_SECS)
     297             : FP(lh_addr, .points_to = (1 << LGFS2_MT_GFS2_LOG_BLOCK))
     298             : FP(lh_jinode, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     299             : FP(lh_statfs_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     300             : FP(lh_quota_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
     301             : F(lh_local_total, .flags = LGFS2_MFF_FSBLOCKS)
     302             : F(lh_local_free, .flags = LGFS2_MFF_FSBLOCKS)
     303             : F(lh_local_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
     304             : };
     305             : 
     306             : #undef STRUCT
     307             : #define STRUCT gfs2_log_descriptor
     308             : 
     309             : static const struct lgfs2_metafield gfs2_log_desc_fields[] = {
     310             : MH(ld_header)
     311             : F(ld_type, .flags = LGFS2_MFF_ENUM, .symtab = lgfs2_ld_types, .nsyms = ARRAY_SIZE(lgfs2_ld_types))
     312             : F(ld_length, .flags = LGFS2_MFF_FSBLOCKS)
     313             : F(ld_data1)
     314             : F(ld_data2)
     315             : RF(ld_reserved)
     316             : };
     317             : 
     318             : #undef STRUCT
     319             : struct gfs2_log_block { struct gfs2_meta_header lb_header; };
     320             : #define STRUCT gfs2_log_block
     321             : 
     322             : static const struct lgfs2_metafield gfs2_log_block_fields[] = {
     323             : MH(lb_header)
     324             : };
     325             : 
     326             : #undef STRUCT
     327             : struct gfs2_ea_attr { struct gfs2_meta_header ea_header; };
     328             : #define STRUCT gfs2_ea_attr
     329             : 
     330             : static const struct lgfs2_metafield gfs2_ea_attr_fields[] = {
     331             : MH(ea_header)
     332             : };
     333             : 
     334             : #undef STRUCT
     335             : struct gfs2_ea_data { struct gfs2_meta_header ed_header; };
     336             : #define STRUCT gfs2_ea_data
     337             : 
     338             : static const struct lgfs2_metafield gfs2_ea_data_fields[] = {
     339             : MH(ed_header)
     340             : };
     341             : 
     342             : #undef STRUCT
     343             : #define STRUCT gfs2_quota_change
     344             : 
     345             : static const struct lgfs2_metafield gfs2_quota_change_fields[] = {
     346             : F(qc_change, .flags = LGFS2_MFF_FSBLOCKS)
     347             : F(qc_flags)
     348             : F(qc_id)
     349             : };
     350             : 
     351             : #undef STRUCT
     352             : #define STRUCT gfs2_dirent
     353             : 
     354             : static const struct lgfs2_metafield gfs2_dirent_fields[] = {
     355             : IN(de_inum, .points_to = (1 << LGFS2_MT_GFS_DINODE)|(1 << LGFS2_MT_GFS2_DINODE))
     356             : F(de_hash, .flags = LGFS2_MFF_CHECK)
     357             : F(de_rec_len, .flags = LGFS2_MFF_BYTES)
     358             : F(de_name_len, .flags = LGFS2_MFF_BYTES)
     359             : F(de_type)
     360             : F(de_rahead)
     361             : F(de_cookie)
     362             : RF(pad3)
     363             : };
     364             : 
     365             : #undef STRUCT
     366             : #define STRUCT gfs2_ea_header
     367             : 
     368             : static const struct lgfs2_metafield gfs2_ea_header_fields[] = {
     369             : F(ea_rec_len, .flags = LGFS2_MFF_BYTES)
     370             : F(ea_data_len, .flags = LGFS2_MFF_BYTES)
     371             : F(ea_name_len, .flags = LGFS2_MFF_BYTES)
     372             : F(ea_type)
     373             : F(ea_flags)
     374             : F(ea_num_ptrs)
     375             : RF(__pad)
     376             : };
     377             : 
     378             : #undef STRUCT
     379             : #define STRUCT gfs2_inum_range
     380             : 
     381             : static const struct lgfs2_metafield gfs2_inum_range_fields[] = {
     382             : F(ir_start)
     383             : F(ir_length)
     384             : };
     385             : 
     386             : #undef STRUCT
     387             : #define STRUCT gfs2_statfs_change
     388             : 
     389             : static const struct lgfs2_metafield gfs2_statfs_change_fields[] = {
     390             : F(sc_total, .flags = LGFS2_MFF_FSBLOCKS)
     391             : F(sc_free, .flags = LGFS2_MFF_FSBLOCKS)
     392             : F(sc_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
     393             : };
     394             : 
     395             : #undef STRUCT
     396             : 
     397             : const struct lgfs2_metadata lgfs2_metadata[] = {
     398             :         [LGFS2_MT_GFS2_SB] = {
     399             :                 .header = 1,
     400             :                 .mh_type = GFS2_METATYPE_SB,
     401             :                 .mh_format = GFS2_FORMAT_SB,
     402             :                 .name = "gfs2_sb",
     403             :                 .display = "superblock",
     404             :                 .fields = gfs2_sb_fields,
     405             :                 .nfields = ARRAY_SIZE(gfs2_sb_fields),
     406             :                 .size = sizeof(struct gfs2_sb),
     407             :         },
     408             :         [LGFS2_MT_RINDEX] = {
     409             :                 .name = "gfs2_rindex",
     410             :                 .display = "resource group index",
     411             :                 .fields = gfs2_rindex_fields,
     412             :                 .nfields = ARRAY_SIZE(gfs2_rindex_fields),
     413             :                 .size = sizeof(struct gfs2_rindex),
     414             :         },
     415             :         [LGFS2_MT_GFS2_RGRP] = {
     416             :                 .header = 1,
     417             :                 .mh_type = GFS2_METATYPE_RG,
     418             :                 .mh_format = GFS2_FORMAT_RG,
     419             :                 .name = "gfs2_rgrp",
     420             :                 .display = "resource group",
     421             :                 .fields = gfs2_rgrp_fields,
     422             :                 .nfields = ARRAY_SIZE(gfs2_rgrp_fields),
     423             :                 .size = sizeof(struct gfs2_rgrp),
     424             :         },
     425             :         [LGFS2_MT_RGRP_BITMAP] = {
     426             :                 .header = 1,
     427             :                 .mh_type = GFS2_METATYPE_RB,
     428             :                 .mh_format = GFS2_FORMAT_RB,
     429             :                 .name = "gfs2_rgrp_bitmap",
     430             :                 .display = "allocation bitmap",
     431             :                 .fields = gfs2_rgrp_bitmap_fields,
     432             :                 .nfields = ARRAY_SIZE(gfs2_rgrp_bitmap_fields),
     433             :                 .size = sizeof(struct gfs2_meta_header),
     434             :         },
     435             :         [LGFS2_MT_GFS2_DINODE] = {
     436             :                 .header = 1,
     437             :                 .mh_type = GFS2_METATYPE_DI,
     438             :                 .mh_format = GFS2_FORMAT_DI,
     439             :                 .name = "gfs2_dinode",
     440             :                 .display = "inode",
     441             :                 .fields = gfs2_dinode_fields,
     442             :                 .nfields = ARRAY_SIZE(gfs2_dinode_fields),
     443             :                 .size = sizeof(struct gfs2_dinode),
     444             :         },
     445             :         [LGFS2_MT_GFS2_INDIRECT] = {
     446             :                 .header = 1,
     447             :                 .mh_type = GFS2_METATYPE_IN,
     448             :                 .mh_format = GFS2_FORMAT_IN,
     449             :                 .name = "gfs2_indirect",
     450             :                 .display = "indirect",
     451             :                 .fields = gfs2_indirect_fields,
     452             :                 .nfields = ARRAY_SIZE(gfs2_indirect_fields),
     453             :                 .size = sizeof(struct gfs2_meta_header),
     454             :         },
     455             :         [LGFS2_MT_DIR_LEAF] = {
     456             :                 .header = 1,
     457             :                 .mh_type = GFS2_METATYPE_LF,
     458             :                 .mh_format = GFS2_FORMAT_LF,
     459             :                 .name = "gfs2_leaf",
     460             :                 .display = "leaf",
     461             :                 .fields = gfs2_leaf_fields,
     462             :                 .nfields = ARRAY_SIZE(gfs2_leaf_fields),
     463             :                 .size = sizeof(struct gfs2_leaf),
     464             :         },
     465             :         [LGFS2_MT_JRNL_DATA] = {
     466             :                 .header = 1,
     467             :                 .mh_type = GFS2_METATYPE_JD,
     468             :                 .mh_format = GFS2_FORMAT_JD,
     469             :                 .name = "gfs2_jdata",
     470             :                 .display = "journal data",
     471             :                 .fields = gfs2_jdata_fields,
     472             :                 .nfields = ARRAY_SIZE(gfs2_jdata_fields),
     473             :                 .size = sizeof(struct gfs2_meta_header),
     474             :         },
     475             :         [LGFS2_MT_GFS2_LOG_HEADER] = {
     476             :                 .header = 1,
     477             :                 .mh_type = GFS2_METATYPE_LH,
     478             :                 .mh_format = GFS2_FORMAT_LH,
     479             :                 .name = "gfs2_log_header",
     480             :                 .display = "log header",
     481             :                 .fields = gfs2_log_header_fields,
     482             :                 .nfields = ARRAY_SIZE(gfs2_log_header_fields),
     483             :                 .size = sizeof(struct gfs2_log_header),
     484             :         },
     485             :         [LGFS2_MT_GFS2_LOG_DESC] = {
     486             :                 .header = 1,
     487             :                 .mh_type = GFS2_METATYPE_LD,
     488             :                 .mh_format = GFS2_FORMAT_LD,
     489             :                 .name = "gfs2_log_desc",
     490             :                 .display = "log descriptor",
     491             :                 .fields = gfs2_log_desc_fields,
     492             :                 .nfields = ARRAY_SIZE(gfs2_log_desc_fields),
     493             :                 .size = sizeof(struct gfs2_log_descriptor),
     494             :         },
     495             :         [LGFS2_MT_GFS2_LOG_BLOCK] = {
     496             :                 .header = 1,
     497             :                 .mh_type = GFS2_METATYPE_LB,
     498             :                 .mh_format = GFS2_FORMAT_LB,
     499             :                 .name = "gfs2_log_block",
     500             :                 .display = "log",
     501             :                 .fields = gfs2_log_block_fields,
     502             :                 .nfields = ARRAY_SIZE(gfs2_log_block_fields),
     503             :                 .size = sizeof(struct gfs2_meta_header),
     504             :         },
     505             :         [LGFS2_MT_EA_ATTR] = {
     506             :                 .header = 1,
     507             :                 .mh_type = GFS2_METATYPE_EA,
     508             :                 .mh_format = GFS2_FORMAT_EA,
     509             :                 .name = "gfs2_ea_attr",
     510             :                 .display = "extended attribute",
     511             :                 .fields = gfs2_ea_attr_fields,
     512             :                 .nfields = ARRAY_SIZE(gfs2_ea_attr_fields),
     513             :                 .size = sizeof(struct gfs2_meta_header),
     514             :         },
     515             :         [LGFS2_MT_EA_DATA] = {
     516             :                 .header = 1,
     517             :                 .mh_type = GFS2_METATYPE_ED,
     518             :                 .mh_format = GFS2_FORMAT_ED,
     519             :                 .name = "gfs2_ea_data",
     520             :                 .display = "extended attribute data",
     521             :                 .fields = gfs2_ea_data_fields,
     522             :                 .nfields = ARRAY_SIZE(gfs2_ea_data_fields),
     523             :                 .size = sizeof(struct gfs2_meta_header),
     524             :         },
     525             :         [LGFS2_MT_GFS2_QUOTA_CHANGE] = {
     526             :                 .name = "gfs2_quota_change",
     527             :                 .display = "quota change",
     528             :                 .fields = gfs2_quota_change_fields,
     529             :                 .nfields = ARRAY_SIZE(gfs2_quota_change_fields),
     530             :                 .size = sizeof(struct gfs2_quota_change),
     531             :         },
     532             :         [LGFS2_MT_DIRENT] = {
     533             :                 .name = "gfs2_dirent",
     534             :                 .display = "directory entry",
     535             :                 .fields = gfs2_dirent_fields,
     536             :                 .nfields = ARRAY_SIZE(gfs2_dirent_fields),
     537             :                 .size = sizeof(struct gfs2_dirent),
     538             :         },
     539             :         [LGFS2_MT_EA_HEADER] = {
     540             :                 .name = "gfs2_ea_header",
     541             :                 .display = "extended attribute header",
     542             :                 .fields = gfs2_ea_header_fields,
     543             :                 .nfields = ARRAY_SIZE(gfs2_ea_header_fields),
     544             :                 .size = sizeof(struct gfs2_ea_header),
     545             :         },
     546             :         [LGFS2_MT_GFS2_INUM_RANGE] = {
     547             :                 .name = "gfs2_inum_range",
     548             :                 .display = "inum range",
     549             :                 .fields = gfs2_inum_range_fields,
     550             :                 .nfields = ARRAY_SIZE(gfs2_inum_range_fields),
     551             :                 .size = sizeof(struct gfs2_inum_range),
     552             :         },
     553             :         [LGFS2_MT_STATFS_CHANGE] = {
     554             :                 .name = "gfs2_statfs_change",
     555             :                 .display = "statfs change",
     556             :                 .fields = gfs2_statfs_change_fields,
     557             :                 .nfields = ARRAY_SIZE(gfs2_statfs_change_fields),
     558             :                 .size = sizeof(struct gfs2_statfs_change),
     559             :         },
     560             :         [LGFS2_MT_DATA] = {
     561             :                 .name = "data",
     562             :                 .display = "data",
     563             :         },
     564             :         [LGFS2_MT_FREE] = {
     565             :                 .name = "free",
     566             :                 .display = "free",
     567             :         },
     568             : };
     569             : 
     570             : const unsigned lgfs2_metadata_size = ARRAY_SIZE(lgfs2_metadata);
     571             : 
     572          16 : const struct lgfs2_metafield *lgfs2_find_mfield_name(const char *name, const struct lgfs2_metadata *mtype)
     573             : {
     574             :         int j;
     575             :         const struct lgfs2_metafield *f;
     576             : 
     577         210 :         for (j = 0; j < mtype->nfields; j++) {
     578         210 :                 f = &mtype->fields[j];
     579         210 :                 if (strcmp(f->name, name) == 0)
     580          16 :                         return f;
     581             :         }
     582           0 :         return NULL;
     583             : }
     584             : 
     585          23 : const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type)
     586             : {
     587          23 :         const struct lgfs2_metadata *m = lgfs2_metadata;
     588          23 :         unsigned n = 0;
     589             : 
     590             :         do {
     591         107 :                 if (m[n].mh_type == mh_type)
     592          23 :                         return &m[n];
     593          84 :                 n++;
     594          84 :         } while (n < lgfs2_metadata_size);
     595             : 
     596           0 :         return NULL;
     597             : }
     598             : 
     599           0 : const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name)
     600             : {
     601           0 :         const struct lgfs2_metadata *m = lgfs2_metadata;
     602           0 :         unsigned n = 0;
     603             : 
     604             :         do {
     605           0 :                 if (!strcmp(m[n].name, name))
     606           0 :                         return &m[n];
     607           0 :                 n++;
     608           0 :         } while (n < lgfs2_metadata_size);
     609             : 
     610           0 :         return NULL;
     611             : }
     612             : 
     613           8 : int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct lgfs2_metafield *field, int hex)
     614             : {
     615           8 :         const char *fieldp = blk + field->offset;
     616             : 
     617           8 :         errno = EINVAL;
     618           8 :         if (str == NULL)
     619           0 :                 return 1;
     620             : 
     621           8 :         if (field->flags & LGFS2_MFF_UUID) {
     622             :                 char readable_uuid[36+1];
     623             :                 uuid_t uuid;
     624             : 
     625           1 :                 memcpy(uuid, fieldp, sizeof(uuid_t));
     626           1 :                 uuid_unparse(uuid, readable_uuid);
     627           1 :                 snprintf(str, size, "%s", readable_uuid);
     628           7 :         } else if (field->flags & LGFS2_MFF_STRING) {
     629           0 :                 snprintf(str, size, "%s", fieldp);
     630             :         } else {
     631             :                 uint64_t value;
     632             : 
     633           7 :                 switch(field->length) {
     634           0 :                 case sizeof(uint8_t):
     635           0 :                         value = *(uint8_t *)fieldp;
     636           0 :                         break;
     637           0 :                 case sizeof(uint16_t):
     638           0 :                         value = be16_to_cpu(*(__be16 *)fieldp);
     639           0 :                         break;
     640           6 :                 case sizeof(uint32_t):
     641           6 :                         value = be32_to_cpu(*(__be32 *)fieldp);
     642           6 :                         break;
     643           1 :                 case sizeof(uint64_t):
     644           1 :                         value = be64_to_cpu(*(__be64 *)fieldp);
     645           1 :                         break;
     646           0 :                 default:
     647           0 :                         *str = 0;
     648           0 :                         goto out;
     649             :                 }
     650             : 
     651           7 :                 if (hex) {
     652           4 :                         snprintf(str, size, "%"PRIx64, value);
     653           4 :                         goto out;
     654             :                 }
     655           3 :                 if (field->flags & LGFS2_MFF_MASK) {
     656           0 :                         char *s = str, *end = str + size;
     657             :                         unsigned n;
     658             : 
     659           0 :                         for (n = 0; n < field->nsyms; n++) {
     660           0 :                                 const struct lgfs2_symbolic *sym = &field->symtab[n];
     661             : 
     662           0 :                                 if (!(value & sym->key))
     663           0 :                                         continue;
     664           0 :                                 if (s != str && s < end)
     665           0 :                                         *s++ = '/';
     666           0 :                                 if (s < end) {
     667           0 :                                         const char *v = sym->value + sym->prefix;
     668           0 :                                         size_t len = strlen(v);
     669             : 
     670           0 :                                         if (len > end - s)
     671           0 :                                                 len = end - s;
     672           0 :                                         memcpy(s, v, len);
     673           0 :                                         s += len;
     674             :                                 }
     675             :                         }
     676           0 :                         if (s < end)
     677           0 :                                 *s = '\0';
     678           0 :                         goto out;
     679             :                 }
     680           3 :                 snprintf(str, size, "%"PRIu64, value);
     681             :         }
     682           8 : out:
     683           8 :         str[size - 1] = '\0';
     684           8 :         return 0;
     685             : }
     686             : 
     687           9 : int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val)
     688             : {
     689           9 :         char *fieldp = blk + field->offset;
     690           9 :         uint64_t num = *(uint64_t *)val;
     691             : 
     692           9 :         if (field->flags & LGFS2_MFF_UUID) {
     693           0 :                 memcpy(fieldp, val, 16);
     694           0 :                 return 0;
     695             :         }
     696             : 
     697           9 :         errno = EINVAL;
     698           9 :         if (field->flags & LGFS2_MFF_STRING) {
     699           0 :                 size_t len = strnlen(val, field->length);
     700             : 
     701           0 :                 if (len >= field->length)
     702           0 :                         return 1;
     703           0 :                 strncpy(fieldp, val, field->length - 1);
     704           0 :                 fieldp[field->length - 1] = '\0';
     705           0 :                 return 0;
     706             :         }
     707             : 
     708           9 :         switch(field->length) {
     709           0 :         case sizeof(uint8_t):
     710           0 :                 *fieldp = (uint8_t)num;
     711           0 :                 return 0;
     712           0 :         case sizeof(uint16_t):
     713           0 :                 *(__be16 *)fieldp = cpu_to_be16((uint16_t)num);
     714           0 :                 return 0;
     715           8 :         case sizeof(uint32_t):
     716           8 :                 *(__be32 *)fieldp = cpu_to_be32((uint32_t)num);
     717           8 :                 return 0;
     718           1 :         case sizeof(uint64_t):
     719           1 :                 *(__be64 *)fieldp = cpu_to_be64((uint64_t)num);
     720           1 :                 return 0;
     721           0 :         default:
     722             :                 /* Will never happen */
     723           0 :                 break;
     724             :         }
     725             : 
     726           0 :         return 1;
     727             : }

Generated by: LCOV version 1.14