[Cluster-devel] [PATCH 3/4] libgfs2: Add support for new leaf hint fields

Andrew Price anprice at redhat.com
Tue Feb 18 11:02:18 UTC 2014


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 <anprice at redhat.com>
>> ---
>>   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 <linux/gfs2_ondisk.h>])],
>> -		 [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 <linux/gfs2_ondisk.h>]])
>> +AC_CHECK_MEMBER([struct gfs2_leaf.lf_inode],[AC_DEFINE([GFS2_HAS_LEAF_HINTS],[],[Leaf block hints])],
>> +                [], [[#include <linux/gfs2_ondisk.h>]])
>>
>>   # 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.
>
>




More information about the Cluster-devel mailing list