Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=d25f31ad78e... Commit: d25f31ad78e5fe96e9cd7b73fc737e7f1130d55c Parent: 1b27340e8afd3eea8d746c31ae461ce35145de36 Author: Andrew Price anprice@redhat.com AuthorDate: Tue Oct 7 11:19:18 2014 +0100 Committer: Andrew Price anprice@redhat.com CommitterDate: Tue Oct 7 13:22:42 2014 +0100
libgfs2: Add generic field assignment and print functions
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(+), 0 deletions(-)
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; +}