LCOV - code coverage report
Current view: top level - libgfs2 - meta.c (source / functions) Coverage Total Hit
Test: gfs2-utils.info Lines: 47.1 % 104 49
Test Date: 2024-03-07 16:24:06 Functions: 80.0 % 5 4

            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 2.0-1