From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Tue, 18 Feb 2014 11:02:18 +0000 Subject: [Cluster-devel] [PATCH 3/4] libgfs2: Add support for new leaf hint fields In-Reply-To: <1392719780.2744.15.camel@menhir> References: <1392648480-5085-1-git-send-email-anprice@redhat.com> <1392648480-5085-3-git-send-email-anprice@redhat.com> <1392719780.2744.15.camel@menhir> Message-ID: <53033DBA.1020306@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 18/02/14 10:36, Steven Whitehouse wrote: > Hi, > > On Mon, 2014-02-17 at 14:47 +0000, Andrew Price wrote: >> Kernel commit 01bcb0de introduces new gfs2_leaf fields. This patch adds >> support for those fields to libgfs2, conditional upon them being >> discovered in the configure stage. Includes meta.c changes by Steve >> Whitehouse. >> >> Signed-off-by: Andrew Price >> --- >> configure.ac | 10 ++++------ >> gfs2/edit/extended.c | 20 ++++++++++++++++---- >> gfs2/edit/gfs2hex.c | 9 ++------- >> gfs2/edit/hexedit.c | 14 ++++++++++++++ >> gfs2/edit/hexedit.h | 5 +---- >> gfs2/fsck/metawalk.c | 2 +- >> gfs2/libgfs2/fs_ops.c | 11 +++++++++-- >> gfs2/libgfs2/meta.c | 8 ++++++++ >> gfs2/libgfs2/ondisk.c | 26 +++++++++++++++++++++++--- >> 9 files changed, 78 insertions(+), 27 deletions(-) >> >> diff --git a/configure.ac b/configure.ac >> index 628d85e..80310be 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -116,12 +116,10 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h mnt >> AC_CHECK_HEADERS([linux/dlmconstants.h linux/limits.h linux/types.h linux/netlink.h linux/fs.h],, >> [AC_MSG_ERROR([Unable to find all required kernel headers.])]) >> >> -AC_CHECK_HEADERS([linux/gfs2_ondisk.h], >> - [AC_CHECK_MEMBERS([struct gfs2_sb.sb_uuid],, >> - [AC_MSG_ERROR([Unable to find gfs2 uuid support in your headers. >> -Please update your kernel headers to a more recent version])], >> - [#include ])], >> - [AC_MSG_ERROR([Unable to find required kernel headers.])]) >> +AC_CHECK_HEADER([linux/gfs2_ondisk.h], [], [AC_MSG_ERROR([Unable to find linux/gfs2_ondisk.h])]) >> +AC_CHECK_MEMBER([struct gfs2_sb.sb_uuid], [], [], [[#include ]]) >> +AC_CHECK_MEMBER([struct gfs2_leaf.lf_inode],[AC_DEFINE([GFS2_HAS_LEAF_HINTS],[],[Leaf block hints])], >> + [], [[#include ]]) >> >> # Checks for typedefs, structures, and compiler characteristics. >> AC_C_INLINE >> diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c >> index ac1e5d7..793ef6b 100644 >> --- a/gfs2/edit/extended.c >> +++ b/gfs2/edit/extended.c >> @@ -296,8 +296,18 @@ static void print_inode_type(__be16 de_type) >> } >> } >> >> +#ifdef GFS2_HAS_LEAF_HINTS >> +#define LEAF_HINT_FMTS "lf_inode: 0x%"PRIx64", lf_dist: %"PRIu32", " \ >> + "lf_nsec: %"PRIu32", lf_sec: %"PRIu64", " >> +#define LEAF_HINT_FIELDS(lp) lp->lf_inode, lp->lf_dist, lp->lf_nsec, lp->lf_sec, >> +#else >> +#define LEAF_HINT_FMTS >> +#define LEAF_HINT_FIELDS(lp) >> +#endif >> + >> static int display_leaf(struct iinfo *ind) >> { >> + struct gfs2_leaf *leaf = &ind->ii[0].lf; >> int start_line, total_dirents = start_row[dmode]; >> int d; >> >> @@ -305,11 +315,13 @@ static int display_leaf(struct iinfo *ind) >> if (gfs2_struct_type == GFS2_METATYPE_SB) >> print_gfs2("The superblock has 2 directories"); >> else >> - print_gfs2("Directory block: lf_depth:%d, lf_entries:%d," >> + print_gfs2("Directory block: lf_depth:%d, lf_entries:%d, " >> + LEAF_HINT_FMTS >> "fmt:%d next=0x%llx (%d dirents).", >> - ind->ii[0].lf_depth, ind->ii[0].lf_entries, >> - ind->ii[0].lf_dirent_format, >> - ind->ii[0].lf_next, >> + leaf->lf_depth, leaf->lf_entries, >> + LEAF_HINT_FIELDS(leaf) >> + leaf->lf_dirent_format, >> + leaf->lf_next, >> ind->ii[0].dirents); > Hmm. It should be possible to use the metadata description to print out > any arbitrary data structure without needing to reference the fields in > the structure directly, so that this kind of thing shouldn't be > required. Yes, that's true of a lot of parts of the code and I've been planning to take care of it all at once by adding generic printing or 'tostring' functions to libgfs2. What I haven't decided yet is whether we need to store format strings ("%s" etc.) for each field in the metadata description or whether we can just use something like the field_print function in libgfs2/lang.c, which is slightly hacky: static int field_print(const struct gfs2_buffer_head *bh, const struct lgfs2_metadata *mtype, const struct lgfs2_metafield *field) { const char *fieldp = (char *)bh->iov.iov_base + field->offset; printf("%s\t%"PRIu64"\t%u\t%u\t%s\t", mtype->name, bh->b_blocknr, field->offset, field->length, field->name); if (field->flags & LGFS2_MFF_UUID) { printf("'%s'\n", str_uuid((const unsigned char *)fieldp)); } else if (field->flags & LGFS2_MFF_STRING) { printf("'%s'\n", fieldp); } else { switch(field->length) { case 1: printf("%"PRIu8"\n", *(uint8_t *)fieldp); break; case 2: printf("%"PRIu16"\n", be16_to_cpu(*(uint16_t *)fieldp)); break; case 4: printf("%"PRIu32"\n", be32_to_cpu(*(uint32_t *)fieldp)); break; case 8: printf("%"PRIu64"\n", be64_to_cpu(*(uint64_t *)fieldp)); break; default: // "Reserved" field so just print 0 printf("0\n"); return 1; } } return 0; } Andy > >> >> start_line = line; >> diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c >> index 8544bbd..979aee0 100644 >> --- a/gfs2/edit/gfs2hex.c >> +++ b/gfs2/edit/gfs2hex.c >> @@ -322,17 +322,12 @@ uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir) >> { >> int x, i; >> struct gfs2_dirent de; >> - struct gfs2_leaf leaf; >> struct gfs2_buffer_head tbh; /* kludge */ >> >> x = 0; >> memset(indir, 0, sizeof(*indir)); >> tbh.b_data = dlebuf; >> - gfs2_leaf_in(&leaf, &tbh); >> - indir->ii[0].lf_depth = leaf.lf_depth; >> - indir->ii[0].lf_entries = leaf.lf_entries; >> - indir->ii[0].lf_dirent_format = leaf.lf_dirent_format; >> - indir->ii[0].lf_next = leaf.lf_next; >> + gfs2_leaf_in(&indir->ii[0].lf, &tbh); >> /* Directory Entries: */ >> for (i = sizeof(struct gfs2_leaf); i < sbd.bsize; >> i += de.de_rec_len) { >> @@ -353,7 +348,7 @@ uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir) >> if (de.de_rec_len <= sizeof(struct gfs2_dirent)) >> break; >> } >> - return leaf.lf_next; >> + return indir->ii[0].lf.lf_next; >> } >> >> static void do_eattr_extended(struct gfs2_buffer_head *ebh) >> diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c >> index 1ed4755..cf57ec8 100644 >> --- a/gfs2/edit/hexedit.c >> +++ b/gfs2/edit/hexedit.c >> @@ -219,7 +219,15 @@ static int gfs2_leaf_printval(struct gfs2_leaf *lf, const char *strfield) >> 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 > Likewise here as well, > > Steve. > >