[Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields
Andrew Price
anprice at redhat.com
Tue Oct 7 12:21:03 UTC 2014
On 07/10/14 13:14, Andrew Price wrote:
> Replace the large number of separate field assignment and printing
> functions in gfs2_edit with the new functions in libgfs2. This reduces
> the amount of code involved dramatically and fixes three coverity
> complaints related to the use of the 'checkassigns' macro.
>
> This relates to the form: gfs2_edit -p 1234 field [foo] /dev/bar
Sorry, that should be: gfs2_edit -p 1234 field foo [bar] /dev/baz
Andy
>
> The 'device' variable has been changed from char[NAME_MAX] to a pointer
> to an argv member, so that now we can check whether the optional [foo]
> argument is missing properly, i.e. no longer assume the device path will
> begin with '/'. It also means the device name is no longer limited to
> 255 chars.
>
> Signed-off-by: Andrew Price <anprice at redhat.com>
> ---
> gfs2/edit/gfs2hex.c | 1 -
> gfs2/edit/hexedit.c | 465 +++++-----------------------------------------------
> gfs2/edit/hexedit.h | 1 -
> 3 files changed, 43 insertions(+), 424 deletions(-)
>
> diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
> index b6075f4..dc6bb8f 100644
> --- a/gfs2/edit/gfs2hex.c
> +++ b/gfs2/edit/gfs2hex.c
> @@ -48,7 +48,6 @@ struct gfs2_sbd sbd;
> uint64_t starting_blk;
> struct blkstack_info blockstack[BLOCK_STACK_SIZE];
> int identify = FALSE;
> -char device[NAME_MAX];
> uint64_t max_block = 0;
> int start_row[DMODES], end_row[DMODES], lines_per_row[DMODES];
> struct gfs_sb *sbd1;
> diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
> index 0982f7b..b316065 100644
> --- a/gfs2/edit/hexedit.c
> +++ b/gfs2/edit/hexedit.c
> @@ -44,291 +44,7 @@ int pgnum;
> int details = 0;
> long int gziplevel = 9;
> static int termcols;
> -
> -/* for assigning numeric fields: */
> -#define checkassign(strfield, struct, member, value) do { \
> - if (strcmp(#member, strfield) == 0) { \
> - struct->member = (typeof(struct->member)) value; \
> - return 0; \
> - } \
> - } while(0)
> -
> -/* for assigning string fields: */
> -#define checkassigns(strfield, struct, member, val) do { \
> - if (strcmp(#member, strfield) == 0) { \
> - memset(struct->member, 0, sizeof(struct->member)); \
> - strncpy((char *)struct->member, (char *)val, \
> - sizeof(struct->member)); \
> - return 0; \
> - } \
> - } while(0)
> -
> -/* for printing numeric fields: */
> -#define checkprint(strfield, struct, member) do { \
> - if (strcmp(#member, strfield) == 0) { \
> - if (dmode == HEX_MODE) \
> - printf("0x%llx\n", \
> - (unsigned long long)struct->member); \
> - else \
> - printf("%llu\n", \
> - (unsigned long long)struct->member); \
> - return 0; \
> - } \
> - } while(0)
> -
> -/* for printing string fields: */
> -#define checkprints(strfield, struct, member) do { \
> - if (strcmp(#member, strfield) == 0) { \
> - printf("%s\n", struct->member); \
> - return 0; \
> - } \
> - } while(0)
> -
> -
> -/* -------------------------------------------------------------------------
> - * field-related functions:
> - * ------------------------------------------------------------------------- */
> -static int gfs2_sb_printval(struct gfs2_sb *lsb, const char *strfield)
> -{
> - checkprint(strfield, lsb, sb_fs_format);
> - checkprint(strfield, lsb, sb_multihost_format);
> - checkprint(strfield, lsb, __pad0);
> - checkprint(strfield, lsb, sb_bsize);
> - checkprint(strfield, lsb, sb_bsize_shift);
> - checkprint(strfield, lsb, __pad1);
> - checkprint(strfield, lsb, sb_master_dir.no_addr);
> - checkprint(strfield, lsb, __pad2.no_addr);
> - checkprint(strfield, lsb, sb_root_dir.no_addr);
> - checkprints(strfield, lsb, sb_lockproto);
> - checkprints(strfield, lsb, sb_locktable);
> - checkprint(strfield, lsb, __pad3.no_addr);
> - checkprint(strfield, lsb, __pad4.no_addr);
> -#ifdef GFS2_HAS_UUID
> - if (strcmp(strfield, "sb_uuid") == 0) {
> - printf("%s\n", str_uuid(lsb->sb_uuid));
> - return 0;
> - }
> -#endif
> -
> - return -1;
> -}
> -
> -static int gfs2_sb_assignval(struct gfs2_sb *lsb, const char *strfield,
> - uint64_t value)
> -{
> - checkassign(strfield, lsb, sb_fs_format, value);
> - checkassign(strfield, lsb, sb_multihost_format, value);
> - checkassign(strfield, lsb, __pad0, value);
> - checkassign(strfield, lsb, sb_bsize, value);
> - checkassign(strfield, lsb, sb_bsize_shift, value);
> - checkassign(strfield, lsb, __pad1, value);
> - checkassign(strfield, lsb, sb_master_dir.no_addr, value);
> - checkassign(strfield, lsb, __pad2.no_addr, value);
> - checkassign(strfield, lsb, sb_root_dir.no_addr, value);
> - checkassign(strfield, lsb, __pad3.no_addr, value);
> - checkassign(strfield, lsb, __pad4.no_addr, value);
> -
> - return -1;
> -}
> -
> -static int gfs2_sb_assigns(struct gfs2_sb *lsb, const char *strfield,
> - const char *val)
> -{
> - checkassigns(strfield, lsb, sb_lockproto, val);
> - checkassigns(strfield, lsb, sb_locktable, val);
> -#ifdef GFS2_HAS_UUID
> - checkassigns(strfield, lsb, sb_uuid, val);
> -#endif
> - return -1;
> -}
> -
> -static int gfs2_dinode_printval(struct gfs2_dinode *dip, const char *strfield)
> -{
> - checkprint(strfield, dip, di_mode);
> - checkprint(strfield, dip, di_uid);
> - checkprint(strfield, dip, di_gid);
> - checkprint(strfield, dip, di_nlink);
> - checkprint(strfield, dip, di_size);
> - checkprint(strfield, dip, di_blocks);
> - checkprint(strfield, dip, di_atime);
> - checkprint(strfield, dip, di_mtime);
> - checkprint(strfield, dip, di_ctime);
> - checkprint(strfield, dip, di_major);
> - checkprint(strfield, dip, di_minor);
> - checkprint(strfield, dip, di_goal_meta);
> - checkprint(strfield, dip, di_goal_data);
> - checkprint(strfield, dip, di_flags);
> - checkprint(strfield, dip, di_payload_format);
> - checkprint(strfield, dip, di_height);
> - checkprint(strfield, dip, di_depth);
> - checkprint(strfield, dip, di_entries);
> - checkprint(strfield, dip, di_eattr);
> -
> - return -1;
> -}
> -
> -static int gfs2_dinode_assignval(struct gfs2_dinode *dia, const char *strfield,
> - uint64_t value)
> -{
> - checkassign(strfield, dia, di_mode, value);
> - checkassign(strfield, dia, di_uid, value);
> - checkassign(strfield, dia, di_gid, value);
> - checkassign(strfield, dia, di_nlink, value);
> - checkassign(strfield, dia, di_size, value);
> - checkassign(strfield, dia, di_blocks, value);
> - checkassign(strfield, dia, di_atime, value);
> - checkassign(strfield, dia, di_mtime, value);
> - checkassign(strfield, dia, di_ctime, value);
> - checkassign(strfield, dia, di_major, value);
> - checkassign(strfield, dia, di_minor, value);
> - checkassign(strfield, dia, di_goal_meta, value);
> - checkassign(strfield, dia, di_goal_data, value);
> - checkassign(strfield, dia, di_flags, value);
> - checkassign(strfield, dia, di_payload_format, value);
> - checkassign(strfield, dia, di_height, value);
> - checkassign(strfield, dia, di_depth, value);
> - checkassign(strfield, dia, di_entries, value);
> - checkassign(strfield, dia, di_eattr, value);
> -
> - return -1;
> -}
> -
> -static int gfs2_rgrp_printval(struct gfs2_rgrp *rg, const char *strfield)
> -{
> - checkprint(strfield, rg, rg_flags);
> - checkprint(strfield, rg, rg_free);
> - checkprint(strfield, rg, rg_dinodes);
> -
> - return -1;
> -}
> -
> -static int gfs2_rgrp_assignval(struct gfs2_rgrp *rg, const char *strfield,
> - uint64_t value)
> -{
> - checkassign(strfield, rg, rg_flags, value);
> - checkassign(strfield, rg, rg_free, value);
> - checkassign(strfield, rg, rg_dinodes, value);
> -
> - return -1;
> -}
> -
> -static int gfs2_leaf_printval(struct gfs2_leaf *lf, const char *strfield)
> -{
> - checkprint(strfield, lf, lf_depth);
> - checkprint(strfield, lf, lf_entries);
> - checkprint(strfield, lf, lf_dirent_format);
> - checkprint(strfield, lf, lf_next);
> -#ifdef GFS2_HAS_LEAF_HINTS
> - checkprint(strfield, lf, lf_inode);
> - checkprint(strfield, lf, lf_dist);
> - checkprint(strfield, lf, lf_nsec);
> - checkprint(strfield, lf, lf_sec);
> - checkprints(strfield, lf, lf_reserved2);
> -#else
> - checkprints(strfield, lf, lf_reserved);
> -#endif
> -
> - return -1;
> -}
> -
> -static int gfs2_leaf_assignval(struct gfs2_leaf *lf, const char *strfield,
> - uint64_t value)
> -{
> - checkassign(strfield, lf, lf_depth, value);
> - checkassign(strfield, lf, lf_entries, value);
> - checkassign(strfield, lf, lf_dirent_format, value);
> - checkassign(strfield, lf, lf_next, value);
> -#ifdef GFS2_HAS_LEAF_HINTS
> - checkassign(strfield, lf, lf_inode, value);
> - checkassign(strfield, lf, lf_dist, value);
> - checkassign(strfield, lf, lf_nsec, value);
> - checkassign(strfield, lf, lf_sec, value);
> -#endif
> -
> - return -1;
> -}
> -
> -static int gfs2_leaf_assigns(struct gfs2_leaf *lf, const char *strfield,
> - const char *val)
> -{
> - checkassigns(strfield, lf, lf_reserved, val);
> -
> - return -1;
> -}
> -
> -static int gfs2_lh_printval(struct gfs2_log_header *lh, const char *strfield)
> -{
> - checkprint(strfield, lh, lh_sequence);
> - checkprint(strfield, lh, lh_flags);
> - checkprint(strfield, lh, lh_tail);
> - checkprint(strfield, lh, lh_blkno);
> - checkprint(strfield, lh, lh_hash);
> -
> - return -1;
> -}
> -
> -static int gfs2_lh_assignval(struct gfs2_log_header *lh, const char *strfield,
> - uint64_t value)
> -{
> - checkassign(strfield, lh, lh_sequence, value);
> - checkassign(strfield, lh, lh_flags, value);
> - checkassign(strfield, lh, lh_tail, value);
> - checkassign(strfield, lh, lh_blkno, value);
> - checkassign(strfield, lh, lh_hash, value);
> -
> - return -1;
> -}
> -
> -static int gfs2_ld_printval(struct gfs2_log_descriptor *ld,
> - const char *strfield)
> -{
> - checkprint(strfield, ld, ld_type);
> - checkprint(strfield, ld, ld_length);
> - checkprint(strfield, ld, ld_data1);
> - checkprint(strfield, ld, ld_data2);
> - checkprints(strfield, ld, ld_reserved);
> -
> - return -1;
> -}
> -
> -static int gfs2_ld_assignval(struct gfs2_log_descriptor *ld,
> - const char *strfield, uint64_t value)
> -{
> - checkassign(strfield, ld, ld_type, value);
> - checkassign(strfield, ld, ld_length, value);
> - checkassign(strfield, ld, ld_data1, value);
> - checkassign(strfield, ld, ld_data2, value);
> -
> - return -1;
> -}
> -
> -static int gfs2_ld_assigns(struct gfs2_log_descriptor *ld,
> - const char *strfield, const char *val)
> -{
> - checkassigns(strfield, ld, ld_reserved, val);
> -
> - return -1;
> -}
> -
> -static int gfs2_qc_printval(struct gfs2_quota_change *qc,
> - const char *strfield)
> -{
> - checkprint(strfield, qc, qc_change);
> - checkprint(strfield, qc, qc_flags);
> - checkprint(strfield, qc, qc_id);
> -
> - return -1;
> -}
> -
> -static int gfs2_qc_assignval(struct gfs2_quota_change *qc,
> - const char *strfield, uint64_t value)
> -{
> - checkassign(strfield, qc, qc_change, value);
> - checkassign(strfield, qc, qc_flags, value);
> - checkassign(strfield, qc, qc_id, value);
> -
> - return -1;
> -}
> +char *device = NULL;
>
> /* ------------------------------------------------------------------------- */
> /* erase - clear the screen */
> @@ -2071,152 +1787,59 @@ static void find_change_block_alloc(int *newval)
> exit(0);
> }
>
> -/* ------------------------------------------------------------------------ */
> -/* process request to print a certain field from a previously pushed block */
> -/* ------------------------------------------------------------------------ */
> +/**
> + * process request to print a certain field from a previously pushed block
> + */
> static void process_field(const char *field, const char *nstr)
> {
> uint64_t fblock;
> struct gfs2_buffer_head *rbh;
> int type;
> - struct gfs2_rgrp rg;
> - struct gfs2_leaf leaf;
> - struct gfs2_sb lsb;
> - struct gfs2_log_header lh;
> - struct gfs2_log_descriptor ld;
> - struct gfs2_quota_change qc;
> - int setval = 0, setstring = 0;
> - uint64_t newval = 0;
> -
> - if (nstr[0] == '/') {
> - setval = 0;
> - } else if (nstr[0] == '0' && nstr[1] == 'x') {
> - sscanf(nstr, "%"SCNx64, &newval);
> - setval = 1;
> - } else {
> - newval = (uint64_t)atoll(nstr);
> - setval = 1;
> - }
> - if (setval && newval == 0 && nstr[0] != '0')
> - setstring = 1;
> + const struct lgfs2_metadata *mtype;
> + const struct lgfs2_metafield *mfield;
> +
> fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
> rbh = bread(&sbd, fblock);
> type = get_block_type(rbh, NULL);
> - switch (type) {
> - case GFS2_METATYPE_SB:
> - gfs2_sb_in(&lsb, rbh);
> - if (setval) {
> - if (setstring)
> - gfs2_sb_assigns(&lsb, field, nstr);
> - else
> - gfs2_sb_assignval(&lsb, field, newval);
> - gfs2_sb_out(&lsb, rbh->b_data);
> - bmodified(rbh);
> - if (!termlines)
> - gfs2_sb_printval(&lsb, field);
> - } else {
> - if (!termlines && gfs2_sb_printval(&lsb, field))
> - printf("Field '%s' not found.\n", field);
> - }
> - break;
> - case GFS2_METATYPE_RG:
> - gfs2_rgrp_in(&rg, rbh);
> - if (setval) {
> - gfs2_rgrp_assignval(&rg, field, newval);
> - gfs2_rgrp_out_bh(&rg, rbh);
> - if (!termlines)
> - gfs2_rgrp_printval(&rg, field);
> - } else {
> - if (!termlines && gfs2_rgrp_printval(&rg, field))
> - printf("Field '%s' not found.\n", field);
> - }
> - break;
> - case GFS2_METATYPE_RB:
> - if (!termlines)
> - print_block_type(fblock, type,
> - " which is not implemented");
> - break;
> - case GFS2_METATYPE_DI:
> - gfs2_dinode_in(&di, rbh);
> - if (setval) {
> - gfs2_dinode_assignval(&di, field, newval);
> - gfs2_dinode_out(&di, rbh);
> - if (!termlines)
> - gfs2_dinode_printval(&di, field);
> - } else {
> - if (!termlines && gfs2_dinode_printval(&di, field))
> - printf("Field '%s' not found.\n", field);
> - }
> - break;
> - case GFS2_METATYPE_IN:
> - if (!setval && !setstring)
> - print_block_type(fblock, type,
> - " which is not implemented");
> - break;
> - case GFS2_METATYPE_LF:
> - gfs2_leaf_in(&leaf, rbh);
> - if (setval) {
> - if (setstring)
> - gfs2_leaf_assigns(&leaf, field, nstr);
> - else
> - gfs2_leaf_assignval(&leaf, field, newval);
> - gfs2_leaf_out(&leaf, rbh);
> - if (!termlines)
> - gfs2_leaf_printval(&leaf, field);
> - } else {
> - if (!termlines && gfs2_leaf_printval(&leaf, field))
> - printf("Field '%s' not found.\n", field);
> - }
> - break;
> - case GFS2_METATYPE_LH:
> - gfs2_log_header_in(&lh, rbh);
> - if (setval) {
> - gfs2_lh_assignval(&lh, field, newval);
> - gfs2_log_header_out(&lh, rbh);
> - if (!termlines)
> - gfs2_lh_printval(&lh, field);
> +
> + mtype = lgfs2_find_mtype(type, sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2);
> + if (mtype == NULL) {
> + fprintf(stderr, "Metadata type '%d' invalid\n", type);
> + exit(1);
> + }
> +
> + mfield = lgfs2_find_mfield_name(field, mtype);
> + if (mfield == NULL) {
> + fprintf(stderr, "No field '%s' in block type '%s'\n", field, mtype->name);
> + exit(1);
> + }
> +
> + if (nstr != device) {
> + int err = 0;
> + if (mfield->flags & (LGFS2_MFF_UUID|LGFS2_MFF_STRING)) {
> + err = lgfs2_field_assign(rbh->b_data, mfield, nstr);
> } else {
> - if (!termlines && gfs2_lh_printval(&lh, field))
> - printf("Field '%s' not found.\n", field);
> - }
> - break;
> - case GFS2_METATYPE_LD:
> - gfs2_log_descriptor_in(&ld, rbh);
> - if (setval) {
> - if (setstring)
> - gfs2_ld_assigns(&ld, field, nstr);
> + uint64_t val = 0;
> + err = sscanf(nstr, "%"SCNi64, &val);
> + if (err == 1)
> + err = lgfs2_field_assign(rbh->b_data, mfield, &val);
> else
> - gfs2_ld_assignval(&ld, field, newval);
> - gfs2_log_descriptor_out(&ld, rbh);
> - if (!termlines)
> - gfs2_ld_printval(&ld, field);
> - } else {
> - if (!termlines && gfs2_ld_printval(&ld, field))
> - printf("Field '%s' not found.\n", field);
> + err = -1;
> }
> - break;
> - case GFS2_METATYPE_QC:
> - gfs2_quota_change_in(&qc, rbh);
> - if (setval) {
> - gfs2_qc_assignval(&qc, field, newval);
> - gfs2_quota_change_out(&qc, rbh);
> - if (!termlines)
> - gfs2_qc_printval(&qc, field);
> - } else {
> - if (!termlines && gfs2_qc_printval(&qc, field))
> - printf("Field '%s' not found.\n", field);
> + if (err != 0) {
> + fprintf(stderr, "Could not set '%s' to '%s': %s\n", field, nstr,
> + strerror(errno));
> + exit(1);
> }
> - break;
> - case GFS2_METATYPE_JD: /* journaled data */
> - case GFS2_METATYPE_EA: /* extended attribute */
> - case GFS2_METATYPE_ED: /* extended attribute */
> - case GFS2_METATYPE_LB:
> - default:
> - if (!termlines)
> - print_block_type(fblock, type,
> - " which is not implemented");
> - break;
> + bmodified(rbh);
> }
> +
> + if (!termlines) {
> + char str[GFS2_LOCKNAME_LEN] = "";
> + lgfs2_field_str(str, GFS2_LOCKNAME_LEN, rbh->b_data, mfield, (dmode == HEX_MODE));
> + printf("%s\n", str);
> + }
> +
> brelse(rbh);
> fsync(sbd.device_fd);
> exit(0);
> @@ -2681,9 +2304,8 @@ static void parameterpass1(int argc, char *argv[], int i)
> termlines = 0;
> else if (!strcasecmp(argv[i], "-x"))
> dmode = HEX_MODE;
> - else if (!device[0] && strchr(argv[i],'/')) {
> - strncpy(device, argv[i], NAME_MAX-1);
> - device[NAME_MAX-1] = '\0';
> + else if (device == NULL && strchr(argv[i],'/')) {
> + device = argv[i];
> }
> }
>
> @@ -2907,7 +2529,6 @@ int main(int argc, char *argv[])
>
> edit_row[GFS2_MODE] = 10; /* Start off at root inode
> pointer in superblock */
> - memset(device, 0, sizeof(device));
> termlines = 30; /* assume interactive mode until we find -p */
> process_parameters(argc, argv, 0);
> if (dmode == INIT_MODE)
> diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
> index f23c581..3e9ff5f 100644
> --- a/gfs2/edit/hexedit.h
> +++ b/gfs2/edit/hexedit.h
> @@ -57,7 +57,6 @@ extern struct gfs2_dinode di;
> extern int screen_chunk_size; /* how much of the 4K can fit on screen */
> extern int gfs2_struct_type;
> extern uint64_t block_in_mem;
> -extern char device[NAME_MAX];
> extern int identify;
> extern int color_scheme;
> extern WINDOW *wind;
>
More information about the Cluster-devel
mailing list