[Cluster-devel] [Patch 05/44] libgfs2: add generic risize function, move gfs1 structures to libgfs2

Bob Peterson rpeterso at redhat.com
Thu Aug 11 20:56:01 UTC 2011


>From e02f2523bfd3b3cc12b07cabdcc388b88c0ba769 Mon Sep 17 00:00:00 2001
From: Bob Peterson <rpeterso at redhat.com>
Date: Mon, 8 Aug 2011 11:23:47 -0500
Subject: [PATCH 05/44] libgfs2: add generic risize function, move gfs1
 structures to libgfs2

This patch moves a number of gfs1-specific structures from gfs2_edit to
libgfs2 so other utils can reference them.  In addition, this moves the
risize function so that callers of libgfs2 can reference the proper rindex
entry size depending on whether they're operating on gfs1 or gfs2.
It also changes function rindex_read so it can operate on gfs1 or gfs2
rindex files.

rhbz#675723
---
 gfs2/edit/extended.c   |   11 +++--
 gfs2/edit/hexedit.c    |   11 ++--
 gfs2/edit/hexedit.h    |  126 ------------------------------------------------
 gfs2/libgfs2/libgfs2.h |   95 ++++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/super.c   |   60 ++++++++++++++++-------
 5 files changed, 149 insertions(+), 154 deletions(-)

diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 575c387..47938e4 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -505,7 +505,8 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 
 	start_line = line;
 	error = 0;
-	print_gfs2("RG index entries found: %d.", dip->i_di.di_size / risize());
+	print_gfs2("RG index entries found: %d.", dip->i_di.di_size /
+		   risize(&sbd));
 	eol(0);
 	lines_per_row[dmode] = 6;
 	memset(highlighted_addr, 0, sizeof(highlighted_addr));
@@ -513,12 +514,14 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 	for (print_entry_ndx=0; ; print_entry_ndx++) {
 		uint64_t roff;
 
-		roff = print_entry_ndx * risize();
+		roff = print_entry_ndx * risize(&sbd);
 
 		if (sbd.gfs1)
-			error = gfs1_readi(dip, (void *)&rbuf, roff, risize());
+			error = gfs1_readi(dip, (void *)&rbuf, roff,
+					   risize(&sbd));
 		else
-			error = gfs2_readi(dip, (void *)&rbuf, roff, risize());
+			error = gfs2_readi(dip, (void *)&rbuf, roff,
+					   risize(&sbd));
 		if (!error) /* end of file */
 			break;
 		gfs2_rindex_in(&ri, rbuf);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 651c6f6..366f515 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1466,7 +1466,7 @@ uint64_t masterblock(const char *fn)
 static void rgcount(void)
 {
 	printf("%lld RGs in this file system.\n",
-	       (unsigned long long)sbd.md.riinode->i_di.di_size / risize());
+	       (unsigned long long)sbd.md.riinode->i_di.di_size / risize(&sbd));
 	inode_put(&sbd.md.riinode);
 	gfs2_rgrp_free(&sbd.rglist);
 	exit(EXIT_SUCCESS);
@@ -1481,7 +1481,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 	struct gfs2_rindex fbuf, ri;
 	uint64_t foffset, gfs1_adj = 0;
 
-	foffset = rg * risize();
+	foffset = rg * risize(&sbd);
 	if (sbd.gfs1) {
 		uint64_t sd_jbsize =
 			(sbd.bsize - sizeof(struct gfs2_meta_header));
@@ -1490,7 +1490,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 			sizeof(struct gfs2_meta_header);
 		gfs1_adj += sizeof(struct gfs2_meta_header);
 	}
-	amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj, risize());
+	amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj, risize(&sbd));
 	if (!amt) /* end of file */
 		return 0;
 	gfs2_rindex_in(&ri, (void *)&fbuf);
@@ -1559,11 +1559,12 @@ static uint64_t get_rg_addr(int rgnum)
 	else
 		gblock = masterblock("rindex");
 	riinode = inode_read(&sbd, gblock);
-	if (rgnum < riinode->i_di.di_size / risize())
+	if (rgnum < riinode->i_di.di_size / risize(&sbd))
 		rgblk = find_rgrp_block(riinode, rgnum);
 	else
 		fprintf(stderr, "Error: File system only has %lld RGs.\n",
-			(unsigned long long)riinode->i_di.di_size / risize());
+			(unsigned long long)riinode->i_di.di_size /
+			risize(&sbd));
 	inode_put(&riinode);
 	return rgblk;
 }
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 8a3c615..f7b539e 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -21,27 +21,6 @@
 enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
 #define BLOCK_STACK_SIZE 256
 
-#define GFS_FORMAT_SB           (100)  /* Super-Block */
-#define GFS_METATYPE_SB         (1)    /* Super-Block */
-#define GFS_FORMAT_FS           (1309) /* Filesystem (all-encompassing) */
-#define GFS_FORMAT_MULTI        (1401) /* Multi-Host */
-/* GFS1 Dinode types  */
-#define GFS_FILE_NON            (0)
-#define GFS_FILE_REG            (1)    /* regular file */
-#define GFS_FILE_DIR            (2)    /* directory */
-#define GFS_FILE_LNK            (5)    /* link */
-#define GFS_FILE_BLK            (7)    /* block device node */
-#define GFS_FILE_CHR            (8)    /* character device node */
-#define GFS_FILE_FIFO           (101)  /* fifo/pipe */
-#define GFS_FILE_SOCK           (102)  /* socket */
-
-/* GFS 1 journal block types: */
-#define GFS_LOG_DESC_METADATA   (300)    /* metadata */
-#define GFS_LOG_DESC_IUL        (400)    /* unlinked inode */
-#define GFS_LOG_DESC_IDA        (401)    /* de-allocated inode */
-#define GFS_LOG_DESC_Q          (402)    /* quota */
-#define GFS_LOG_DESC_LAST       (500)    /* final in a logged transaction */
-
 #define pv(struct, member, fmt, fmt2) do {				\
 		print_it("  "#member, fmt, fmt2, struct->member);	\
 	} while (FALSE);
@@ -89,71 +68,6 @@ extern int dsplines;
 extern int dsp_lines[DMODES];
 extern int combined_display;
 
-struct gfs_jindex {
-        uint64_t ji_addr;       /* starting block of the journal */
-        uint32_t ji_nsegment;   /* number (quantity) of segments in journal */
-        uint32_t ji_pad;
-
-        char ji_reserved[64];
-};
-
-struct gfs_log_descriptor {
-	struct gfs2_meta_header ld_header;
-
-	uint32_t ld_type;       /* GFS_LOG_DESC_... Type of this log chunk */
-	uint32_t ld_length;     /* Number of buffers in this chunk */
-	uint32_t ld_data1;      /* descriptor-specific field */
-	uint32_t ld_data2;      /* descriptor-specific field */
-	char ld_reserved[64];
-};
-
-struct gfs_log_header {
-	struct gfs2_meta_header lh_header;
-
-	uint32_t lh_flags;      /* GFS_LOG_HEAD_... */
-	uint32_t lh_pad;
-
-	uint64_t lh_first;     /* Block number of first header in this trans */
-	uint64_t lh_sequence;   /* Sequence number of this transaction */
-
-	uint64_t lh_tail;       /* Block number of log tail */
-	uint64_t lh_last_dump;  /* Block number of last dump */
-
-	char lh_reserved[64];
-};
-
-struct gfs_rindex {
-	uint64_t ri_addr;     /* block # of 1st block (header) in rgrp */
-	uint32_t ri_length;   /* # fs blocks containing rgrp header & bitmap */
-	uint32_t ri_pad;
-
-	uint64_t ri_data1;    /* block # of first data/meta block in rgrp */
-	uint32_t ri_data;     /* number (qty) of data/meta blocks in rgrp */
-
-	uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */
-
-	char ri_reserved[64];
-};
-
-struct gfs_rgrp {
-	struct gfs2_meta_header rg_header;
-
-	uint32_t rg_flags;      /* ?? */
-
-	uint32_t rg_free;       /* Number (qty) of free data blocks */
-
-	/* Dinodes are USEDMETA, but are handled separately from other METAs */
-	uint32_t rg_useddi;     /* Number (qty) of dinodes (used or free) */
-	uint32_t rg_freedi;     /* Number (qty) of unused (free) dinodes */
-	struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */
-
-	/* These META statistics do not include dinodes (used or free) */
-	uint32_t rg_usedmeta;   /* Number (qty) of used metadata blocks */
-	uint32_t rg_freemeta;   /* Number (qty) of unused metadata blocks */
-
-	char rg_reserved[64];
-};
-
 struct gfs2_dirents {
 	uint64_t block;
 	struct gfs2_dirent dirent;
@@ -189,35 +103,6 @@ struct blkstack_info {
 	struct metapath mp;
 };
 
-struct gfs_sb {
-	/*  Order is important; need to be able to read old superblocks
-	    in order to support on-disk version upgrades */
-	struct gfs2_meta_header sb_header;
-
-	uint32_t sb_fs_format;         /* GFS_FORMAT_FS (on-disk version) */
-	uint32_t sb_multihost_format;  /* GFS_FORMAT_MULTI */
-	uint32_t sb_flags;             /* ?? */
-
-	uint32_t sb_bsize;             /* fundamental FS block size in bytes */
-	uint32_t sb_bsize_shift;       /* log2(sb_bsize) */
-	uint32_t sb_seg_size;          /* Journal segment size in FS blocks */
-
-	/* These special inodes do not appear in any on-disk directory. */
-	struct gfs2_inum sb_jindex_di;  /* journal index inode */
-	struct gfs2_inum sb_rindex_di;  /* resource group index inode */
-	struct gfs2_inum sb_root_di;    /* root directory inode */
-
-	/* Default inter-node locking protocol (lock module) and namespace */
-	char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */
-	char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */
-
-	/* More special inodes */
-	struct gfs2_inum sb_quota_di;   /* quota inode */
-	struct gfs2_inum sb_license_di; /* license inode */
-
-	char sb_reserved[96];
-};
-
 extern struct blkstack_info blockstack[BLOCK_STACK_SIZE];
 extern struct iinfo *indirect; /* more than the most indirect
 			       pointers possible for any given 4K block */
@@ -226,17 +111,6 @@ extern int indirect_blocks;  /* count of indirect blocks */
 extern enum dsp_mode dmode;
 
 /* ------------------------------------------------------------------------ */
-/* risize - size of one rindex entry, whether gfs1 or gfs2                  */
-/* ------------------------------------------------------------------------ */
-static inline int risize(void)
-{
-	if (sbd.gfs1)
-		return sizeof(struct gfs_rindex);
-	else
-		return sizeof(struct gfs2_rindex);
-}
-
-/* ------------------------------------------------------------------------ */
 /* block_is_rglist - there's no such block as the rglist.  This is a        */
 /*                   special case meant to parse the rindex and follow the  */
 /*                   blocks to the real rgs.                                */
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 82c39f1..6ddfd19 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -568,6 +568,100 @@ struct gfs_dinode {
 	char di_reserved[56];
 };
 
+struct gfs_sb {
+	/*  Order is important; need to be able to read old superblocks
+	    in order to support on-disk version upgrades */
+	struct gfs2_meta_header sb_header;
+
+	uint32_t sb_fs_format;         /* GFS_FORMAT_FS (on-disk version) */
+	uint32_t sb_multihost_format;  /* GFS_FORMAT_MULTI */
+	uint32_t sb_flags;             /* ?? */
+
+	uint32_t sb_bsize;             /* fundamental FS block size in bytes */
+	uint32_t sb_bsize_shift;       /* log2(sb_bsize) */
+	uint32_t sb_seg_size;          /* Journal segment size in FS blocks */
+
+	/* These special inodes do not appear in any on-disk directory. */
+	struct gfs2_inum sb_jindex_di;  /* journal index inode */
+	struct gfs2_inum sb_rindex_di;  /* resource group index inode */
+	struct gfs2_inum sb_root_di;    /* root directory inode */
+
+	/* Default inter-node locking protocol (lock module) and namespace */
+	char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */
+	char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */
+
+	/* More special inodes */
+	struct gfs2_inum sb_quota_di;   /* quota inode */
+	struct gfs2_inum sb_license_di; /* license inode */
+
+	char sb_reserved[96];
+};
+
+struct gfs_rgrp {
+	struct gfs2_meta_header rg_header;
+
+	uint32_t rg_flags;      /* ?? */
+
+	uint32_t rg_free;       /* Number (qty) of free data blocks */
+
+	/* Dinodes are USEDMETA, but are handled separately from other METAs */
+	uint32_t rg_useddi;     /* Number (qty) of dinodes (used or free) */
+	uint32_t rg_freedi;     /* Number (qty) of unused (free) dinodes */
+	struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */
+
+	/* These META statistics do not include dinodes (used or free) */
+	uint32_t rg_usedmeta;   /* Number (qty) of used metadata blocks */
+	uint32_t rg_freemeta;   /* Number (qty) of unused metadata blocks */
+
+	char rg_reserved[64];
+};
+
+struct gfs_log_header {
+	struct gfs2_meta_header lh_header;
+
+	uint32_t lh_flags;      /* GFS_LOG_HEAD_... */
+	uint32_t lh_pad;
+
+	uint64_t lh_first;     /* Block number of first header in this trans */
+	uint64_t lh_sequence;   /* Sequence number of this transaction */
+
+	uint64_t lh_tail;       /* Block number of log tail */
+	uint64_t lh_last_dump;  /* Block number of last dump */
+
+	char lh_reserved[64];
+};
+
+struct gfs_rindex {
+	uint64_t ri_addr;     /* block # of 1st block (header) in rgrp */
+	uint32_t ri_length;   /* # fs blocks containing rgrp header & bitmap */
+	uint32_t ri_pad;
+
+	uint64_t ri_data1;    /* block # of first data/meta block in rgrp */
+	uint32_t ri_data;     /* number (qty) of data/meta blocks in rgrp */
+
+	uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */
+
+	char ri_reserved[64];
+};
+
+struct gfs_jindex {
+        uint64_t ji_addr;       /* starting block of the journal */
+        uint32_t ji_nsegment;   /* number (quantity) of segments in journal */
+        uint32_t ji_pad;
+
+        char ji_reserved[64];
+};
+
+struct gfs_log_descriptor {
+	struct gfs2_meta_header ld_header;
+
+	uint32_t ld_type;       /* GFS_LOG_DESC_... Type of this log chunk */
+	uint32_t ld_length;     /* Number of buffers in this chunk */
+	uint32_t ld_data1;      /* descriptor-specific field */
+	uint32_t ld_data2;      /* descriptor-specific field */
+	char ld_reserved[64];
+};
+
 extern void gfs1_lookup_block(struct gfs2_inode *ip,
 			      struct gfs2_buffer_head *bh,
 			      unsigned int height, struct metapath *mp,
@@ -696,6 +790,7 @@ extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 /* super.c */
 extern int check_sb(struct gfs2_sb *sb, int allow_gfs);
 extern int read_sb(struct gfs2_sbd *sdp, int allow_gfs);
+extern int risize(struct gfs2_sbd *sdp);
 extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
 extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
 extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 7d82d2d..4b53299 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -129,6 +129,17 @@ int read_sb(struct gfs2_sbd *sdp, int allow_gfs)
 	return gfs1;
 }
 
+/*
+ * risize - size of one rindex entry, whether gfs1 or gfs2
+ */
+int risize(struct gfs2_sbd *sdp)
+{
+	if (sdp->gfs1)
+		return sizeof(struct gfs_rindex);
+	else
+		return sizeof(struct gfs2_rindex);
+}
+
 /**
  * rindex_read - read in the rg index file
  * @sdp: the incore superblock pointer
@@ -143,25 +154,32 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 {
 	unsigned int rg;
 	int error;
-	struct gfs2_rindex buf;
+	union {
+		struct gfs_rindex bufgfs1;
+		struct gfs2_rindex bufgfs2;
+	} buf;
 	struct rgrp_list *rgd, *prev_rgd;
 	uint64_t prev_length = 0;
 
 	*sane = 1;
 	*count1 = 0;
 	prev_rgd = NULL;
-	if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex))
+	if (!fd && sdp->md.riinode->i_di.di_size % risize(sdp))
 		*sane = 0; /* rindex file size must be a multiple of 96 */
 	for (rg = 0; ; rg++) {
 		if (fd > 0)
-			error = read(fd, &buf, sizeof(struct gfs2_rindex));
+			error = read(fd, &buf, risize(sdp));
+		else if (sdp->gfs1)
+			error = gfs1_readi(sdp->md.riinode,
+					   (char *)&buf.bufgfs1,
+					   rg * risize(sdp), risize(sdp));
 		else
-			error = gfs2_readi(sdp->md.riinode, (char *)&buf,
-					   rg * sizeof(struct gfs2_rindex),
-					   sizeof(struct gfs2_rindex));
+			error = gfs2_readi(sdp->md.riinode,
+					   (char *)&buf.bufgfs2,
+					   rg * risize(sdp), risize(sdp));
 		if (!error)
 			break;
-		if (error != sizeof(struct gfs2_rindex))
+		if (error != risize(sdp))
 			return -1;
 
 		rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list));
@@ -172,23 +190,27 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 		memset(rgd, 0, sizeof(struct rgrp_list));
 		osi_list_add_prev(&rgd->list, &sdp->rglist);
 
-		gfs2_rindex_in(&rgd->ri, (char *)&buf);
+		gfs2_rindex_in(&rgd->ri, (char *)&buf.bufgfs2);
 
 		rgd->start = rgd->ri.ri_addr;
 		if (prev_rgd) {
 			/* If rg addresses go backwards, it's not sane
 			   (or it's converted from gfs1). */
-			if (prev_rgd->start >= rgd->start)
-				*sane = 0;
-			/* If rg lengths are not consistent, it's not sane
-			   (or it's converted from gfs1).  The first RG will
-			   be a different length due to space allocated for
-			   the superblock, so we can't detect this until
-			   we check rgrp 3, when we can compare the distance
-			   between rgrp 1 and rgrp 2. */
-			if (rg > 2 && prev_length &&
-			    prev_length != rgd->start - prev_rgd->start)
-				*sane = 0;
+			if (!sdp->gfs1) {
+				if (prev_rgd->start >= rgd->start)
+					*sane = 0;
+				/* If rg lengths are not consistent, it's not
+				   sane (or it's converted from gfs1).  The
+				   first RG will be a different length due to
+				   space allocated for the superblock, so we
+				   can't detect this until we check rgrp 3,
+				   when we can compare the distance between
+				   rgrp 1 and rgrp 2. */
+				if (rg > 2 && prev_length &&
+				    prev_length != rgd->start -
+				    prev_rgd->start)
+					*sane = 0;
+			}
 			prev_length = rgd->start - prev_rgd->start;
 			prev_rgd->length = prev_length;
 		}
-- 
1.7.4.4




More information about the Cluster-devel mailing list