[Cluster-devel] [PATCH 24/32] savemeta: Call get_struct_info() in the read path

Andrew Price anprice at redhat.com
Thu Aug 6 13:37:59 UTC 2020


Makes no sense to figure out the block type and length in save_buf(),
it's too late to do much with it at that point. Move the
get_gfs_struct_info() call and other checks into check_read_block().
Which means save_buf() can now be merged with do_save_buf().

Signed-off-by: Andrew Price <anprice at redhat.com>
---
 gfs2/edit/savemeta.c | 89 +++++++++++++++++++++++---------------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index cbead772..0de7dbf9 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -335,7 +335,9 @@ static int get_gfs_struct_info(const char *buf, uint64_t owner, int *block_type,
 
 	if (block_type != NULL)
 		*block_type = 0;
-	*gstruct_len = sbd.bsize;
+
+	if (gstruct_len != NULL)
+		*gstruct_len = sbd.bsize;
 
 	gfs2_meta_header_in(&mh, buf);
 	if (mh.mh_magic != GFS2_MAGIC)
@@ -344,6 +346,9 @@ static int get_gfs_struct_info(const char *buf, uint64_t owner, int *block_type,
 	if (block_type != NULL)
 		*block_type = mh.mh_type;
 
+	if (gstruct_len == NULL)
+		return 0;
+
 	switch (mh.mh_type) {
 	case GFS2_METATYPE_SB:   /* 1 (superblock) */
 		*gstruct_len = sizeof(struct gfs_sb);
@@ -522,7 +527,7 @@ static int savemetaclose(struct metafd *mfd)
 	return close(mfd->fd);
 }
 
-static int do_save_buf(struct metafd *mfd, const char *buf, uint64_t addr, unsigned blklen)
+static int save_buf(struct metafd *mfd, const char *buf, uint64_t addr, unsigned blklen)
 {
 	struct saved_metablock *savedata;
 	size_t outsz;
@@ -554,23 +559,7 @@ static int do_save_buf(struct metafd *mfd, const char *buf, uint64_t addr, unsig
 	return 0;
 }
 
-static int save_buf(struct metafd *mfd, const char *buf, uint64_t addr, uint64_t owner, int *blktype)
-{
-	size_t blklen;
-
-	/* If this isn't metadata and isn't a system file, we don't want it.
-	   Note that we're checking "owner" here rather than blk.  That's
-	   because we want to know if the source inode is a system inode
-	   not the block within the inode "blk". They may or may not
-	   be the same thing. */
-	if (get_gfs_struct_info(buf, owner, blktype, &blklen) &&
-	    !block_is_systemfile(owner) && owner != 0)
-		return 0; /* Not metadata, and not system file, so skip it */
-
-	return do_save_buf(mfd, buf, addr, blklen);
-}
-
-static char *check_read_block(int fd, uint64_t blk)
+static char *check_read_block(int fd, uint64_t blk, uint64_t owner, int *blktype, size_t *blklen)
 {
 	char *buf = calloc(1, sbd.bsize);
 	if (buf == NULL) {
@@ -588,6 +577,11 @@ static char *check_read_block(int fd, uint64_t blk)
 		free(buf);
 		return NULL;
 	}
+	if (get_gfs_struct_info(buf, owner, blktype, blklen) &&
+	    !block_is_systemfile(owner) && owner != 0) {
+		free(buf);
+		return NULL;
+	}
 	return buf;
 }
 
@@ -614,9 +608,9 @@ static void save_ea_block(struct metafd *mfd, char *buf, uint64_t owner)
 			b = (uint64_t *)buf;
 			b += charoff + i;
 			blk = be64_to_cpu(*b);
-			_buf = check_read_block(sbd.device_fd, blk);
+			_buf = check_read_block(sbd.device_fd, blk, owner, NULL, NULL);
 			if (_buf != NULL) {
-				save_buf(mfd, _buf, blk, owner, NULL);
+				save_buf(mfd, _buf, blk, sbd.bsize);
 				free(_buf);
 			}
 		}
@@ -633,7 +627,7 @@ static void save_indirect_blocks(struct metafd *mfd, osi_list_t *cur_list,
 {
 	uint64_t old_block = 0, indir_block;
 	uint64_t *ptr;
-	int head_size, blktype;
+	int head_size;
 	struct gfs2_buffer_head *nbh;
 
 	head_size = (hgt > 1 ?
@@ -642,6 +636,8 @@ static void save_indirect_blocks(struct metafd *mfd, osi_list_t *cur_list,
 
 	for (ptr = (uint64_t *)(mybh->b_data + head_size);
 	     (char *)ptr < (mybh->b_data + sbd.bsize); ptr++) {
+		size_t blklen;
+		int blktype;
 		char *buf;
 
 		if (!*ptr)
@@ -651,9 +647,9 @@ static void save_indirect_blocks(struct metafd *mfd, osi_list_t *cur_list,
 			continue;
 		old_block = indir_block;
 
-		buf = check_read_block(sbd.device_fd, indir_block);
+		buf = check_read_block(sbd.device_fd, indir_block, owner, &blktype, &blklen);
 		if (buf != NULL) {
-			save_buf(mfd, buf, indir_block, owner, &blktype);
+			save_buf(mfd, buf, indir_block, blklen);
 			free(buf);
 		}
 
@@ -698,7 +694,7 @@ static int save_leaf_chain(struct metafd *mfd, struct gfs2_sbd *sdp, uint64_t bl
 		}
 		warm_fuzzy_stuff(blk, FALSE);
 		if (gfs2_check_meta(buf, GFS2_METATYPE_LF) == 0) {
-			int ret = save_buf(mfd, buf, blk, blk, NULL);
+			int ret = save_buf(mfd, buf, blk, sdp->bsize);
 			if (ret != 0) {
 				free(buf);
 				return ret;
@@ -806,13 +802,16 @@ static void save_inode_data(struct metafd *mfd, uint64_t iblk)
 	}
 	if (inode->i_di.di_eattr) { /* if this inode has extended attributes */
 		struct gfs2_buffer_head *lbh;
+		size_t blklen;
+		uint64_t blk;
 		int mhtype;
 		char *buf;
 
-		lbh = bread(&sbd, inode->i_di.di_eattr);
-		buf = check_read_block(sbd.device_fd, inode->i_di.di_eattr);
+		blk = inode->i_di.di_eattr;
+		lbh = bread(&sbd, blk);
+		buf = check_read_block(sbd.device_fd, blk, iblk, &mhtype, &blklen);
 		if (buf != NULL) {
-			save_buf(mfd, buf, inode->i_di.di_eattr, iblk, &mhtype);
+			save_buf(mfd, buf, blk, blklen);
 			free(buf);
 		}
 		if (mhtype == GFS2_METATYPE_EA)
@@ -875,12 +874,14 @@ static void get_journal_inode_blocks(void)
 
 static void save_allocated(struct rgrp_tree *rgd, struct metafd *mfd)
 {
-	int blktype;
 	uint64_t blk = 0;
 	unsigned i, j, m;
 	uint64_t *ibuf = malloc(sbd.bsize * GFS2_NBBY * sizeof(uint64_t));
 
 	for (i = 0; i < rgd->ri.ri_length; i++) {
+		size_t blen;
+		int btype;
+
 		m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE);
 
 		for (j = 0; j < m; j++) {
@@ -888,13 +889,13 @@ static void save_allocated(struct rgrp_tree *rgd, struct metafd *mfd)
 
 			blk = ibuf[j];
 			warm_fuzzy_stuff(blk, FALSE);
-			buf = check_read_block(sbd.device_fd, blk);
+			buf = check_read_block(sbd.device_fd, blk, blk, &btype, &blen);
 			if (buf != NULL) {
-				save_buf(mfd, buf, blk, blk, &blktype);
+				save_buf(mfd, buf, blk, blen);
 				free(buf);
+				if (btype == GFS2_METATYPE_DI)
+					save_inode_data(mfd, blk);
 			}
-			if (blktype == GFS2_METATYPE_DI)
-				save_inode_data(mfd, blk);
 		}
 		if (!sbd.gfs1)
 			continue;
@@ -903,9 +904,9 @@ static void save_allocated(struct rgrp_tree *rgd, struct metafd *mfd)
 		 * If we don't, we may run into metadata allocation issues. */
 		m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_UNLINKED);
 		for (j = 0; j < m; j++) {
-			char *buf = check_read_block(sbd.device_fd, blk);
+			char *buf = check_read_block(sbd.device_fd, blk, blk, &btype, &blen);
 			if (buf != NULL) {
-				save_buf(mfd, buf, blk, blk, &blktype);
+				save_buf(mfd, buf, blk, blen);
 				free(buf);
 			}
 		}
@@ -954,7 +955,7 @@ static void save_rgrp(struct gfs2_sbd *sdp, struct metafd *mfd, struct rgrp_tree
 	/* Save the rg and bitmaps */
 	for (unsigned i = 0; i < rgd->ri.ri_length; i++) {
 		warm_fuzzy_stuff(rgd->ri.ri_addr + i, FALSE);
-		do_save_buf(mfd, buf + (i * sdp->bsize), rgd->ri.ri_addr + i, sdp->bsize);
+		save_buf(mfd, buf + (i * sdp->bsize), rgd->ri.ri_addr + i, sdp->bsize);
 	}
 	/* Save the other metadata: inodes, etc. if mode is not 'savergs' */
 	if (withcontents)
@@ -1006,6 +1007,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 	struct gfs2_buffer_head *lbh;
 	struct metafd mfd;
 	struct osi_node *n;
+	uint64_t sb_addr;
 	int err = 0;
 	char *buf;
 
@@ -1042,9 +1044,10 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 		exit(1);
 	}
 	/* Save off the superblock */
-	buf = check_read_block(sbd.device_fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sbd.bsize);
+	sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sbd.bsize;
+	buf = check_read_block(sbd.device_fd, sb_addr, 0, NULL, NULL);
 	if (buf != NULL) {
-		save_buf(&mfd, buf, GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sbd.bsize, 0, NULL);
+		save_buf(&mfd, buf, sb_addr, sizeof(struct gfs_sb));
 		free(buf);
 	}
 	/* If this is gfs1, save off the rindex because it's not
@@ -1054,9 +1057,9 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 		int j;
 
 		blk = sbd1->sb_rindex_di.no_addr;
-		buf = check_read_block(sbd.device_fd, blk);
+		buf = check_read_block(sbd.device_fd, blk, blk, NULL, NULL);
 		if (buf != NULL) {
-			save_buf(&mfd, buf, blk, blk, NULL);
+			save_buf(&mfd, buf, blk, sbd.bsize);
 			free(buf);
 		}
 		save_inode_data(&mfd, blk);
@@ -1066,9 +1069,11 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 
 			log_debug("Saving journal #%d\n", j + 1);
 			for (blk = jb; blk < (jb + gfs1_journal_size); blk++) {
-				buf = check_read_block(sbd.device_fd, blk);
+				size_t blen;
+
+				buf = check_read_block(sbd.device_fd, blk, blk, NULL, &blen);
 				if (buf != NULL) {
-					save_buf(&mfd, buf, blk, blk, NULL);
+					save_buf(&mfd, buf, blk, blen);
 					free(buf);
 				}
 			}
-- 
2.26.2




More information about the Cluster-devel mailing list