[Cluster-devel] [fsck.gfs2 PATCH 17/30] fsck.gfs2: make blockmap global variable only to pass1

Bob Peterson rpeterso at redhat.com
Fri Apr 15 13:38:11 UTC 2016


This patch changes the variable "bl" from being a global variable
to being global only to pass1. This is another step toward allowing
pass1 to free the blockmap when it's done.

Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 gfs2/fsck/fsck.h       |   3 +-
 gfs2/fsck/initialize.c |  11 -----
 gfs2/fsck/main.c       |   1 -
 gfs2/fsck/pass1.c      | 120 +++++++++++++++++++++++++++++++++++++++++--------
 gfs2/fsck/pass5.c      |  17 +++----
 gfs2/fsck/util.c       |  66 ---------------------------
 gfs2/fsck/util.h       |   6 +--
 7 files changed, 112 insertions(+), 112 deletions(-)

diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 4cf4ce1..d57ccfd 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -119,7 +119,7 @@ extern int pass1c(struct gfs2_sbd *sdp);
 extern int pass2(struct gfs2_sbd *sdp);
 extern int pass3(struct gfs2_sbd *sdp);
 extern int pass4(struct gfs2_sbd *sdp);
-extern int pass5(struct gfs2_sbd *sdp);
+extern int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl);
 extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
 		     int *sane);
 extern int fsck_query(const char *format, ...)
@@ -142,7 +142,6 @@ struct gfs2_options {
 extern struct gfs2_options opts;
 extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
 extern int lf_was_created;
-extern struct gfs2_bmap *bl;
 extern uint64_t last_fs_block, last_reported_block;
 extern int64_t last_reported_fblock;
 extern int skip_this_pass, fsck_abort;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 84d39cd..d54ab0d 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -115,8 +115,6 @@ static void empty_super_block(struct gfs2_sbd *sdp)
 	log_info( _("Freeing buffers.\n"));
 	gfs2_rgrp_free(&sdp->rgtree);
 
-	if (bl)
-		gfs2_bmap_destroy(sdp, bl);
 	gfs2_inodetree_free();
 	gfs2_dirtree_free();
 	gfs2_dup_free();
@@ -674,7 +672,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	uint64_t inumbuf = 0;
 	char *buf;
 	struct gfs2_statfs_change sc;
-	uint64_t addl_mem_needed;
 	int err;
 
 	/*******************************************************************
@@ -841,14 +838,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		goto fail;
 	}
 
-	bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
-	if (!bl) {
-		log_crit( _("This system doesn't have enough memory and swap space to fsck this file system.\n"));
-		log_crit( _("Additional memory needed is approximately: %lluMB\n"),
-			 (unsigned long long)(addl_mem_needed / 1048576ULL));
-		log_crit( _("Please increase your swap space by that amount and run gfs2_fsck again.\n"));
-		goto fail;
-	}
 	return 0;
  fail:
 	empty_super_block(sdp);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 2cedb30..91ebe28 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -27,7 +27,6 @@
 struct gfs2_options opts = {0};
 struct gfs2_inode *lf_dip = NULL; /* Lost and found directory inode */
 int lf_was_created = 0;
-struct gfs2_bmap *bl = NULL;
 uint64_t last_fs_block, last_reported_block = -1;
 int64_t last_reported_fblock = -1000000;
 int skip_this_pass = FALSE, fsck_abort = FALSE;
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 876e565..49f6c6e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -30,6 +30,7 @@
 #include "fs_recovery.h"
 
 struct special_blocks gfs1_rindex_blks;
+struct gfs2_bmap *bl = NULL;
 
 struct block_count {
 	uint64_t indir_count;
@@ -88,6 +89,24 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
 static int delete_block(struct gfs2_inode *ip, uint64_t block,
 			struct gfs2_buffer_head **bh, const char *btype,
 			void *private);
+
+static int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock, int mark)
+{
+	static unsigned char *byte;
+	static uint64_t b;
+
+	if (!bmap)
+		return 0;
+	if (bblock > bmap->size)
+		return -1;
+
+	byte = bmap->map + BLOCKMAP_SIZE2(bblock);
+	b = BLOCKMAP_BYTE_OFFSET2(bblock);
+	*byte &= ~(BLOCKMAP_MASK2 << b);
+	*byte |= (mark & BLOCKMAP_MASK2) << b;
+	return 0;
+}
+
 /*
  * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
  *                      bitmap, and adjust free space accordingly.
@@ -253,7 +272,7 @@ static int p1check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 	   check in metawalk: gfs2_check_meta(lbh, GFS2_METATYPE_LF).
 	   So we know it's a leaf block. */
 	bc->indir_count++;
-	q = block_type(block);
+	q = block_type(bl, block);
 	if (q != GFS2_BLKST_FREE) {
 		log_err( _("Found duplicate block #%llu (0x%llx) referenced "
 			   "as a directory leaf in dinode "
@@ -311,7 +330,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 		iblk_type = GFS2_METATYPE_IN;
 		blktypedesc = _("a journaled data block");
 	}
-	q = block_type(block);
+	q = block_type(bl, block);
 	if (q != GFS2_BLKST_FREE) {
 		log_err( _("Found duplicate block #%llu (0x%llx) referenced "
 			   "as metadata in indirect block for dinode "
@@ -502,7 +521,7 @@ static int check_data(struct gfs2_inode *ip, uint64_t metablock,
 		return -1;
 	}
 	bc->data_count++; /* keep the count sane anyway */
-	q = block_type(block);
+	q = block_type(bl, block);
 	if (q != GFS2_BLKST_FREE) {
 		struct gfs2_buffer_head *bh;
 		struct gfs2_meta_header mh;
@@ -623,7 +642,7 @@ static int undo_eattr_indir_or_leaf(struct gfs2_inode *ip, uint64_t block,
 
 	/* Need to check block_type before undoing the reference, which can
 	   set it to free, which would cause the test below to fail. */
-	q = block_type(block);
+	q = block_type(bl, block);
 
 	error = undo_reference(ip, block, 0, private);
 	if (error)
@@ -672,7 +691,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
 		 * in pass1c */
 		return 1;
 	}
-	q = block_type(indirect);
+	q = block_type(bl, indirect);
 
 	/* Special duplicate processing:  If we have an EA block,
 	   check if it really is an EA.  If it is, let duplicate
@@ -756,7 +775,7 @@ static int check_ealeaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
 	int q;
 	struct block_count *bc = (struct block_count *) private;
 
-	q = block_type(block);
+	q = block_type(bl, block);
 	/* Special duplicate processing:  If we have an EA block, check if it
 	   really is an EA.  If it is, let duplicate handling sort it out.
 	   If it isn't, clear it but don't count it as a duplicate. */
@@ -1027,7 +1046,7 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
 		return meta_is_good;
 	}
 
-	q = block_type(block);
+	q = block_type(bl, block);
 	if (q != GFS2_BLKST_FREE) {
 		if (was_duplicate)
 			*was_duplicate = 1;
@@ -1126,7 +1145,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 			return meta_error; /* Exits check_metatree quicker */
 	}
 	/* See how many duplicate blocks it has */
-	q = block_type(block);
+	q = block_type(bl, block);
 	if (q != GFS2_BLKST_FREE) {
 		(*bad_pointers)++;
 		log_info( _("Duplicated %s block pointer (violation %ld, block"
@@ -1595,7 +1614,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 		}
 	}
 	if (*sysinode) {
-		ds.q = block_type(iblock);
+		ds.q = block_type(bl, iblock);
 		/* If the inode exists but the block is marked free, we might
 		   be recovering from a corrupt bitmap.  In that case, don't
 		   rebuild the inode.  Just reuse the inode and fix the
@@ -1858,7 +1877,7 @@ static int pass1_process_bitmap(struct gfs2_sbd *sdp, struct rgrp_tree *rgd, uin
 		check_magic = ((struct gfs2_meta_header *)
 			       (bh->b_data))->mh_magic;
 
-		q = block_type(block);
+		q = block_type(bl, block);
 		if (q != GFS2_BLKST_FREE) {
 			if (be32_to_cpu(check_magic) == GFS2_MAGIC &&
 			    sdp->gfs1 && !is_inode) {
@@ -1971,6 +1990,55 @@ out:
 	return ret;
 }
 
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
+{
+	bmap->size = size;
+
+	/* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
+	 * must be 1-based */
+	bmap->mapsize = BLOCKMAP_SIZE2(size) + 1;
+
+	if (!(bmap->map = calloc(bmap->mapsize, sizeof(char))))
+		return -ENOMEM;
+	return 0;
+}
+
+static struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+					  uint64_t *addl_mem_needed)
+{
+	struct gfs2_bmap *il;
+
+	*addl_mem_needed = 0L;
+	il = calloc(1, sizeof(*il));
+	if (!il)
+		return NULL;
+
+	if (gfs2_blockmap_create(il, size)) {
+		*addl_mem_needed = il->mapsize;
+		free(il);
+		il = NULL;
+	}
+	return il;
+}
+
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
+{
+	if (bmap->map)
+		free(bmap->map);
+	bmap->size = 0;
+	bmap->mapsize = 0;
+}
+
+static void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
+{
+	if (il) {
+		gfs2_blockmap_destroy(il);
+		free(il);
+		il = NULL;
+	}
+	return il;
+}
+
 /**
  * pass1 - walk through inodes and check inode state
  *
@@ -1990,9 +2058,18 @@ int pass1(struct gfs2_sbd *sdp)
 	struct rgrp_tree *rgd;
 	uint64_t i;
 	uint64_t rg_count = 0;
-	int ret;
 	struct timeval timer;
-
+	int ret = FSCK_OK;
+	uint64_t addl_mem_needed;
+
+	bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
+	if (!bl) {
+		log_crit( _("This system doesn't have enough memory and swap space to fsck this file system.\n"));
+		log_crit( _("Additional memory needed is approximately: %lluMB\n"),
+			 (unsigned long long)(addl_mem_needed / 1048576ULL));
+		log_crit( _("Please increase your swap space by that amount and run gfs2_fsck again.\n"));
+		return FSCK_ERROR;
+	}
 	osi_list_init(&gfs1_rindex_blks.list);
 
 	/* FIXME: In the gfs fsck, we had to mark things like the
@@ -2014,8 +2091,10 @@ int pass1(struct gfs2_sbd *sdp)
 	 * things - we can change the method later if necessary.
 	 */
 	for (n = osi_first(&sdp->rgtree); n; n = next, rg_count++) {
-		if (fsck_abort)
-			return FSCK_CANCELED;
+		if (fsck_abort) {
+			ret = FSCK_CANCELED;
+			goto out;
+		}
 		next = osi_next(n);
 		log_debug( _("Checking metadata in Resource Group #%llu\n"),
 				 (unsigned long long)rg_count);
@@ -2028,7 +2107,8 @@ int pass1(struct gfs2_sbd *sdp)
 					      GFS2_BLKST_USED)) {
 				stack;
 				gfs2_special_free(&gfs1_rindex_blks);
-				return FSCK_ERROR;
+				ret = FSCK_ERROR;
+				goto out;
 			}
 			/* rgrps and bitmaps don't have bits to represent
 			   their blocks, so don't do this:
@@ -2038,13 +2118,15 @@ int pass1(struct gfs2_sbd *sdp)
 
 		ret = pass1_process_rgrp(sdp, rgd);
 		if (ret)
-			return ret;
-
+			goto out;
 	}
 	log_notice(_("Reconciling bitmaps.\n"));
 	gettimeofday(&timer, NULL);
-	pass5(sdp);
+	pass5(sdp, bl);
 	print_pass_duration("reconcile_bitmaps", &timer);
+out:
 	gfs2_special_free(&gfs1_rindex_blks);
-	return FSCK_OK;
+	if (bl)
+		gfs2_bmap_destroy(sdp, bl);
+	return ret;
 }
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 99ff0a1..7d81bfa 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -12,9 +12,10 @@
 #include "fsck.h"
 #include "util.h"
 
-static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
-			      unsigned int buflen, uint64_t *rg_block,
-			      uint64_t rg_data, uint32_t *count)
+static int check_block_status(struct gfs2_sbd *sdp,  struct gfs2_bmap *bl,
+			      char *buffer, unsigned int buflen,
+			      uint64_t *rg_block, uint64_t rg_data,
+			      uint32_t *count)
 {
 	unsigned char *byte, *end;
 	unsigned int bit;
@@ -34,7 +35,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return 0;
 
-		q = block_type(block);
+		q = block_type(bl, block);
 		/* GFS1 file systems will have to suffer from slower fsck run
 		 * times because in GFS, there's no 1:1 relationship between
 		 * bits and counts. If a bit is marked "dinode" in GFS1, it
@@ -124,7 +125,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 }
 
 static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
-			uint32_t *count)
+			struct gfs2_bmap *bl, uint32_t *count)
 {
 	uint32_t i;
 	struct gfs2_bitmap *bits;
@@ -136,7 +137,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
 		bits = &rgp->bits[i];
 
 		/* update the bitmaps */
-		if (check_block_status(sdp, bits->bi_bh->b_data + bits->bi_offset,
+		if (check_block_status(sdp, bl, bits->bi_bh->b_data + bits->bi_offset,
 		                       bits->bi_len, &rg_block, rgp->ri.ri_data0, count))
 			return;
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -209,7 +210,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
  * fix free block maps
  * fix used inode maps
  */
-int pass5(struct gfs2_sbd *sdp)
+int pass5(struct gfs2_sbd *sdp, struct gfs2_bmap *bl)
 {
 	struct osi_node *n, *next = NULL;
 	struct rgrp_tree *rgp = NULL;
@@ -227,7 +228,7 @@ int pass5(struct gfs2_sbd *sdp)
 
 		rg_count++;
 		/* Compare the bitmaps and report the differences */
-		update_rgrp(sdp, rgp, count);
+		update_rgrp(sdp, rgp, bl, count);
 	}
 	/* Fix up superblock info based on this - don't think there's
 	 * anything to do here... */
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index d6d664a..2e77000 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -525,72 +525,6 @@ void dirtree_delete(struct dir_info *b)
 	free(b);
 }
 
-static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
-{
-	bmap->size = size;
-
-	/* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
-	 * must be 1-based */
-	bmap->mapsize = BLOCKMAP_SIZE2(size) + 1;
-
-	if (!(bmap->map = calloc(bmap->mapsize, sizeof(char))))
-		return -ENOMEM;
-	return 0;
-}
-
-static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
-{
-	if (bmap->map)
-		free(bmap->map);
-	bmap->size = 0;
-	bmap->mapsize = 0;
-}
-
-struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
-				   uint64_t *addl_mem_needed)
-{
-	struct gfs2_bmap *il;
-
-	*addl_mem_needed = 0L;
-	il = calloc(1, sizeof(*il));
-	if (!il)
-		return NULL;
-
-	if (gfs2_blockmap_create(il, size)) {
-		*addl_mem_needed = il->mapsize;
-		free(il);
-		il = NULL;
-	}
-	return il;
-}
-
-int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock, int mark)
-{
-	static unsigned char *byte;
-	static uint64_t b;
-
-	if (!bmap)
-		return 0;
-	if (bblock > bmap->size)
-		return -1;
-
-	byte = bmap->map + BLOCKMAP_SIZE2(bblock);
-	b = BLOCKMAP_BYTE_OFFSET2(bblock);
-	*byte &= ~(BLOCKMAP_MASK2 << b);
-	*byte |= (mark & BLOCKMAP_MASK2) << b;
-	return 0;
-}
-
-void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
-{
-	if (il) {
-		gfs2_blockmap_destroy(il);
-		free(il);
-		il = NULL;
-	}
-	return il;
-}
-
 uint64_t find_free_blk(struct gfs2_sbd *sdp)
 {
 	struct osi_node *n, *next = NULL;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 50a3c8d..aa01552 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -32,7 +32,7 @@ struct fsck_pass {
 	int (*f)(struct gfs2_sbd *sdp);
 };
 
-static inline int block_type(uint64_t bblock)
+static inline int block_type(struct gfs2_bmap *bl, uint64_t bblock)
 {
 	static unsigned char *byte;
 	static uint64_t b;
@@ -100,10 +100,6 @@ static inline uint32_t gfs_to_gfs2_mode(struct gfs2_inode *ip)
 }
 
 extern enum dup_ref_type get_ref_type(struct inode_with_dups *id);
-extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
-					  uint64_t *addl_mem_needed);
-extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
-extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block, int mark);
 extern char generic_interrupt(const char *caller, const char *where,
                        const char *progress, const char *question,
                        const char *answers);
-- 
2.5.5




More information about the Cluster-devel mailing list