[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