From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Tue, 07 Oct 2014 13:21:03 +0100 Subject: [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields In-Reply-To: <1412684095-29967-2-git-send-email-anprice@redhat.com> References: <1412684095-29967-1-git-send-email-anprice@redhat.com> <1412684095-29967-2-git-send-email-anprice@redhat.com> Message-ID: <5433DAAF.2010107@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 > --- > 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; >