All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH 1/3] libgfs2: Add generic field assignment and print functions
@ 2014-10-07 12:14 Andrew Price
  2014-10-07 12:14 ` [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields Andrew Price
  2014-10-07 12:14 ` [Cluster-devel] [PATCH 3/3] gfs2l: Switch to lgfs2_field_assign Andrew Price
  0 siblings, 2 replies; 4+ messages in thread
From: Andrew Price @ 2014-10-07 12:14 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Add lgfs2_field_str() to convert the value of any metadata field to a
string, and lgfs2_field_assign() to assign any metadata field a value.
lgfs2_find_mfield_name() is also added to make it easier to look up a
lgfs2_metafield by its name.

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/libgfs2/libgfs2.h |  3 ++
 gfs2/libgfs2/meta.c    | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 604a7de..f33b838 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -372,6 +372,9 @@ extern const unsigned lgfs2_ld1_type_size;
 extern int lgfs2_selfcheck(void);
 extern const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type, const unsigned versions);
 extern const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name, const unsigned versions);
+extern const struct lgfs2_metafield *lgfs2_find_mfield_name(const char *name, const struct lgfs2_metadata *mtype);
+extern int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct lgfs2_metafield *field, int hex);
+extern int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val);
 
 /* block_list.c */
 
diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c
index 4305393..f0eed3d 100644
--- a/gfs2/libgfs2/meta.c
+++ b/gfs2/libgfs2/meta.c
@@ -734,6 +734,19 @@ const struct lgfs2_metadata lgfs2_metadata[] = {
 
 const unsigned lgfs2_metadata_size = ARRAY_SIZE(lgfs2_metadata);
 
+const struct lgfs2_metafield *lgfs2_find_mfield_name(const char *name, const struct lgfs2_metadata *mtype)
+{
+	int j;
+	const struct lgfs2_metafield *f;
+
+	for (j = 0; j < mtype->nfields; j++) {
+		f = &mtype->fields[j];
+		if (strcmp(f->name, name) == 0)
+			return f;
+	}
+	return NULL;
+}
+
 static int check_metadata_sizes(void)
 {
 	unsigned offset;
@@ -844,3 +857,74 @@ const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name, const unsig
 
 	return NULL;
 }
+
+int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct lgfs2_metafield *field, int hex)
+{
+	const char *fieldp = blk + field->offset;
+
+	errno = EINVAL;
+	if (str == NULL)
+		return 1;
+
+	if (field->flags & LGFS2_MFF_UUID) {
+		snprintf(str, size, "%s", str_uuid((unsigned char *)fieldp));
+	} else if (field->flags & LGFS2_MFF_STRING) {
+		snprintf(str, size, "%s", fieldp);
+	} else {
+		switch(field->length) {
+		case sizeof(uint8_t):
+			snprintf(str, size, hex? "%"PRIx8 : "%"PRIu8, *(uint8_t *)fieldp);
+			break;
+		case sizeof(uint16_t):
+			snprintf(str, size, hex? "%"PRIx16 : "%"PRIu16, be16_to_cpu(*(uint16_t *)fieldp));
+			break;
+		case sizeof(uint32_t):
+			snprintf(str, size, hex? "%"PRIx32 : "%"PRIu32, be32_to_cpu(*(uint32_t *)fieldp));
+			break;
+		case sizeof(uint64_t):
+			snprintf(str, size, hex? "%"PRIx64 : "%"PRIu64, be64_to_cpu(*(uint64_t *)fieldp));
+			break;
+		default:
+			break;
+		}
+	}
+	str[size - 1] = '\0';
+	return 0;
+}
+
+int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val)
+{
+	char *fieldp = blk + field->offset;
+
+	if (field->flags & LGFS2_MFF_UUID) {
+		memcpy(fieldp, val, 16);
+		return 0;
+	}
+
+	if (field->flags & LGFS2_MFF_STRING) {
+		strncpy(fieldp, val, field->length - 1);
+		fieldp[field->length - 1] = '\0';
+		return 0;
+	}
+
+	switch(field->length) {
+	case sizeof(uint8_t):
+		*fieldp = *(uint8_t *)val;
+		return 0;
+	case sizeof(uint16_t):
+		*(uint16_t *)fieldp = cpu_to_be16(*(uint16_t *)val);
+		return 0;
+	case sizeof(uint32_t):
+		*(uint32_t *)fieldp = cpu_to_be32(*(uint32_t *)val);
+		return 0;
+	case sizeof(uint64_t):
+		*(uint64_t *)fieldp = cpu_to_be64(*(uint64_t *)val);
+		return 0;
+	default:
+		/* Will never happen */
+		break;
+	}
+
+	errno = EINVAL;
+	return 1;
+}
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields
  2014-10-07 12:14 [Cluster-devel] [PATCH 1/3] libgfs2: Add generic field assignment and print functions Andrew Price
@ 2014-10-07 12:14 ` Andrew Price
  2014-10-07 12:21   ` Andrew Price
  2014-10-07 12:14 ` [Cluster-devel] [PATCH 3/3] gfs2l: Switch to lgfs2_field_assign Andrew Price
  1 sibling, 1 reply; 4+ messages in thread
From: Andrew Price @ 2014-10-07 12:14 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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

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@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;
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Cluster-devel] [PATCH 3/3] gfs2l: Switch to lgfs2_field_assign
  2014-10-07 12:14 [Cluster-devel] [PATCH 1/3] libgfs2: Add generic field assignment and print functions Andrew Price
  2014-10-07 12:14 ` [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields Andrew Price
@ 2014-10-07 12:14 ` Andrew Price
  1 sibling, 0 replies; 4+ messages in thread
From: Andrew Price @ 2014-10-07 12:14 UTC (permalink / raw)
  To: cluster-devel.redhat.com

The new lgfs2_field_assign function was based on code in gfs2l, which
can now be converted to use the new libgfs2 functions.

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/libgfs2/lang.c | 78 ++++++++++++++++-------------------------------------
 gfs2/libgfs2/meta.c |  6 ++++-
 2 files changed, 28 insertions(+), 56 deletions(-)

diff --git a/gfs2/libgfs2/lang.c b/gfs2/libgfs2/lang.c
index b4a743f..13333a1 100644
--- a/gfs2/libgfs2/lang.c
+++ b/gfs2/libgfs2/lang.c
@@ -471,7 +471,7 @@ invalid:
 static int ast_field_set(struct gfs2_buffer_head *bh, const struct lgfs2_metafield *field,
                                                                         struct ast_node *val)
 {
-	char *fieldp = (char *)bh->iov.iov_base + field->offset;
+	int err = 0;
 
 	if (field->flags & LGFS2_MFF_UUID) {
 		uint8_t uuid[16];
@@ -479,56 +479,21 @@ static int ast_field_set(struct gfs2_buffer_head *bh, const struct lgfs2_metafie
 
 		if (ret != AST_INTERP_SUCCESS)
 			return ret;
-
-		memcpy(fieldp, uuid, 16);
-		bmodified(bh);
-		return AST_INTERP_SUCCESS;
+		err = lgfs2_field_assign(bh->b_data, field, uuid);
+	} else if (field->flags & LGFS2_MFF_STRING) {
+		err = lgfs2_field_assign(bh->b_data, field, val->ast_str);
+	} else {
+		err = lgfs2_field_assign(bh->b_data, field, &val->ast_num);
 	}
 
-	if ((field->flags & LGFS2_MFF_STRING) && strlen(val->ast_str) > field->length) {
-		fprintf(stderr, "String '%s' is too long for field '%s'\n", val->ast_str, field->name);
+	if (err) {
+		fprintf(stderr, "Invalid field assignment: %s (size %d) = %s\n",
+	                field->name, field->length, val->ast_text);
 		return AST_INTERP_INVAL;
 	}
 
-	if (field->flags & (LGFS2_MFF_STRING|LGFS2_MFF_UUID)) {
-		strncpy(fieldp, val->ast_str, field->length - 1);
-		fieldp[field->length - 1] = '\0';
-		bmodified(bh);
-		return AST_INTERP_SUCCESS;
-	} else {
-		// Numeric fields
-		switch(field->length) {
-		case 1:
-			if (val->ast_num > UINT8_MAX)
-				break;
-			*fieldp = (uint8_t)val->ast_num;
-			bmodified(bh);
-			return AST_INTERP_SUCCESS;
-		case 2:
-			if (val->ast_num > UINT16_MAX)
-				break;
-			*(uint16_t *)fieldp = cpu_to_be16((uint16_t)val->ast_num);
-			bmodified(bh);
-			return AST_INTERP_SUCCESS;
-		case 4:
-			if (val->ast_num > UINT32_MAX)
-				break;
-			*(uint32_t *)fieldp = cpu_to_be32((uint32_t)val->ast_num);
-			bmodified(bh);
-			return AST_INTERP_SUCCESS;
-		case 8:
-			*(uint64_t *)fieldp = cpu_to_be64((uint64_t)val->ast_num);
-			bmodified(bh);
-			return AST_INTERP_SUCCESS;
-		default:
-			// This should never happen
-			return AST_INTERP_ERR;
-		}
-	}
-
-	fprintf(stderr, "Invalid field assignment: %s (size %d) = %s\n",
-	                     field->name, field->length, val->ast_text);
-	return AST_INTERP_INVAL;
+	bmodified(bh);
+	return AST_INTERP_SUCCESS;
 }
 
 static const struct lgfs2_metadata *lang_find_mtype(struct ast_node *node, struct gfs2_buffer_head *bh, unsigned ver)
@@ -558,7 +523,6 @@ static struct lgfs2_lang_result *ast_interp_set(struct lgfs2_lang_state *state,
 	struct ast_node *fieldspec;
 	struct ast_node *fieldname;
 	struct ast_node *fieldval;
-	int i = 0;
 	int ret = 0;
 	unsigned ver = sbd->gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2;
 
@@ -592,17 +556,21 @@ static struct lgfs2_lang_result *ast_interp_set(struct lgfs2_lang_state *state,
 	for (fieldspec = lookup->ast_right;
 	     fieldspec != NULL && fieldspec->ast_type == AST_EX_FIELDSPEC;
 	     fieldspec = fieldspec->ast_left) {
+		const struct lgfs2_metafield *mfield;
 
 		fieldname = fieldspec->ast_right;
 		fieldval = fieldname->ast_right;
-		for (i = 0; i < result->lr_mtype->nfields; i++) {
-			if (!strcmp(result->lr_mtype->fields[i].name, fieldname->ast_str)) {
-				ret = ast_field_set(result->lr_bh, &result->lr_mtype->fields[i], fieldval);
-				if (ret != AST_INTERP_SUCCESS) {
-					goto out_err;
-				}
-				break;
-			}
+
+		mfield = lgfs2_find_mfield_name(fieldname->ast_str, result->lr_mtype);
+		if (mfield == NULL) {
+			fprintf(stderr, "No field '%s' found in '%s'\n",
+			        fieldname->ast_str, result->lr_mtype->name);
+			goto out_err;
+		}
+
+		ret = ast_field_set(result->lr_bh, mfield, fieldval);
+		if (ret != AST_INTERP_SUCCESS) {
+			goto out_err;
 		}
 	}
 
diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c
index f0eed3d..79de64d 100644
--- a/gfs2/libgfs2/meta.c
+++ b/gfs2/libgfs2/meta.c
@@ -901,7 +901,12 @@ int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const voi
 		return 0;
 	}
 
+	errno = EINVAL;
 	if (field->flags & LGFS2_MFF_STRING) {
+		size_t len = strnlen(val, field->length);
+
+		if (len >= field->length)
+			return 1;
 		strncpy(fieldp, val, field->length - 1);
 		fieldp[field->length - 1] = '\0';
 		return 0;
@@ -925,6 +930,5 @@ int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const voi
 		break;
 	}
 
-	errno = EINVAL;
 	return 1;
 }
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields
  2014-10-07 12:14 ` [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields Andrew Price
@ 2014-10-07 12:21   ` Andrew Price
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Price @ 2014-10-07 12:21 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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@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;
>



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-10-07 12:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-07 12:14 [Cluster-devel] [PATCH 1/3] libgfs2: Add generic field assignment and print functions Andrew Price
2014-10-07 12:14 ` [Cluster-devel] [PATCH 2/3] gfs2_edit: Use metadata description to print and assign fields Andrew Price
2014-10-07 12:21   ` Andrew Price
2014-10-07 12:14 ` [Cluster-devel] [PATCH 3/3] gfs2l: Switch to lgfs2_field_assign Andrew Price

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.