[Cluster-devel] [fsck.gfs2 PATCH 06/30] fsck.gfs2: Change all fsck_blockmap_set to fsck_bitmap_set

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


This patch changes all functions past pass1 so that they set the
bits in the bitmap rather than bits in the blockmap. This is a
step toward being able to free the bitmap after pass1.

Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 gfs2/fsck/lost_n_found.c |  4 +--
 gfs2/fsck/metawalk.c     | 36 +++++++++++--------
 gfs2/fsck/metawalk.h     |  7 ++++
 gfs2/fsck/pass1b.c       | 90 ++++++++++++++++++++++++++++++++++--------------
 gfs2/fsck/pass2.c        | 33 ++++++++----------
 gfs2/fsck/pass3.c        | 17 +++------
 gfs2/fsck/pass4.c        | 16 ++++-----
 7 files changed, 122 insertions(+), 81 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index cd847f8..9c85f52 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -139,8 +139,8 @@ void make_sure_lf_exists(struct gfs2_inode *ip)
 		/* FIXME: i'd feel better about this if fs_mkdir returned
 		   whether it created a new directory or just found an old one,
 		   and we used that instead of the bitmap_type to run this */
-		fsck_blockmap_set(ip, lf_dip->i_di.di_num.no_addr,
-				  _("lost+found dinode"), GFS2_BLKST_DINODE);
+		fsck_bitmap_set(ip, lf_dip->i_di.di_num.no_addr,
+				_("lost+found dinode"), GFS2_BLKST_DINODE);
 		dirtree_insert(lf_dip->i_di.di_num);
 		/* root inode links to lost+found */
 		incr_link_count(sdp->md.rooti->i_di.di_num, lf_dip, _("root"));
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 3cb5a7a..ce23220 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -110,12 +110,11 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk, int error_on_dinode,
 }
 
 /*
- * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
- *                      bitmap, and adjust free space accordingly.
+ * _fsck_bitmap_set - Mark a block in the bitmap, and adjust free space.
  */
-int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
-		       const char *btype, int mark,
-		       int error_on_dinode, const char *caller, int fline)
+int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
+		     const char *btype, int mark,
+		     int error_on_dinode, const char *caller, int fline)
 {
 	int error;
 	static int prev_ino_addr = 0;
@@ -172,19 +171,26 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 		prev_mark = mark;
 		prev_caller = caller;
 	}
-
-	/* First, check the rgrp bitmap against what we think it should be.
-	   If that fails, it's an invalid block--part of an rgrp. */
 	error = check_n_fix_bitmap(ip->i_sbd, bblock, error_on_dinode, mark);
-	if (error) {
-		if (error < 0)
-			log_err( _("This block is not represented in the "
-				   "bitmap.\n"));
+	if (error < 0)
+		log_err(_("This block is not represented in the bitmap.\n"));
+	return error;
+}
+
+/*
+ * _fsck_blockmap_set - Mark a block in the 4-bit blockmap and the 2-bit
+ *                      bitmap, and adjust free space accordingly.
+ */
+int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
+		       const char *btype, int mark,
+		       int error_on_dinode, const char *caller, int fline)
+{
+	int error = _fsck_bitmap_set(ip, bblock, btype, mark, error_on_dinode,
+				     caller, fline);
+	if (error)
 		return error;
-	}
 
-	error = gfs2_blockmap_set(bl, bblock, mark);
-	return error;
+	return gfs2_blockmap_set(bl, bblock, mark);
 }
 
 struct duptree *dupfind(uint64_t block)
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 8ec38d0..90bd028 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -49,6 +49,9 @@ extern int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
 extern int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 			      const char *btype, int mark, int error_on_dinode,
 			      const char *caller, int line);
+extern int _fsck_bitmap_set(struct gfs2_inode *ip, uint64_t bblock,
+			    const char *btype, int mark, int error_on_dinode,
+			    const char *caller, int line);
 extern int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 			      int error_on_dinode, int new_blockmap_state);
 extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
@@ -65,6 +68,10 @@ extern int repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no, int lindex,
 
 #define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
 
+#define fsck_bitmap_set(ip, b, bt, m) \
+	_fsck_bitmap_set(ip, b, bt, m, 0, __FUNCTION__, __LINE__)
+#define fsck_bitmap_set_noino(ip, b, bt, m) \
+	_fsck_bitmap_set(ip, b, bt, m, 1, __FUNCTION__, __LINE__)
 #define fsck_blockmap_set(ip, b, bt, m) \
 	_fsck_blockmap_set(ip, b, bt, m, 0, __FUNCTION__, __LINE__)
 #define fsck_blkmap_set_noino(ip, b, bt, m) \
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index ee636fe..20b603c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -348,9 +348,9 @@ static void resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *dt,
 				ii = inodetree_find(ip->i_di.di_num.no_addr);
 				if (ii)
 					inodetree_delete(ii);
-				fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
+				fsck_bitmap_set(ip, ip->i_di.di_num.no_addr,
 						_("duplicate referencing bad"),
-						  GFS2_BLKST_UNLINKED);
+						GFS2_BLKST_UNLINKED);
 				/* We delete the dup_handler inode count and
 				   duplicate id BEFORE clearing the metadata,
 				   because if this is the last reference to
@@ -428,8 +428,8 @@ static int clone_data(struct gfs2_inode *ip, uint64_t metablock,
 		if (!error) {
 			clone_bh = bread(ip->i_sbd, clonet->dup_block);
 			if (clone_bh) {
-				fsck_blockmap_set(ip, cloneblock, _("data"),
-						  GFS2_BLKST_USED);
+				fsck_bitmap_set(ip, cloneblock, _("data"),
+						GFS2_BLKST_USED);
 				clone_bh->b_blocknr = cloneblock;
 				bmodified(clone_bh);
 				brelse(clone_bh);
@@ -496,6 +496,46 @@ static void clone_dup_ref_in_inode(struct gfs2_inode *ip, struct duptree *dt)
 	}
 }
 
+static int set_ip_bitmap(struct gfs2_inode *ip)
+{
+	uint64_t block = ip->i_bh->b_blocknr;
+	uint32_t mode;
+	const char *ty;
+
+	if (ip->i_sbd->gfs1)
+		mode = gfs_to_gfs2_mode(ip);
+	else
+		mode = ip->i_di.di_mode & S_IFMT;
+
+	switch (mode) {
+	case S_IFDIR:
+		ty = _("directory");
+		break;
+	case S_IFREG:
+		ty = _("file");
+		break;
+	case S_IFLNK:
+		ty = _("symlink");
+		break;
+	case S_IFBLK:
+		ty = _("block device");
+		break;
+	case S_IFCHR:
+		ty = _("character device");
+		break;
+	case S_IFIFO:
+		ty = _("fifo");
+		break;
+	case S_IFSOCK:
+		ty = _("socket");
+		break;
+	default:
+		return -EINVAL;
+	}
+	fsck_bitmap_set(ip, block, ty, GFS2_BLKST_DINODE);
+	return 0;
+}
+
 static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
 				   enum dup_ref_type acceptable_ref)
 {
@@ -531,31 +571,31 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
 			     "marked invalid: Marking the block as free.\n"),
 			   (unsigned long long)id->block_no,
 			   (unsigned long long)id->block_no);
-		fsck_blockmap_set(ip, dt->block, _("reference-repaired leaf"),
+		fsck_bitmap_set(ip, dt->block, _("reference-repaired leaf"),
 				  GFS2_BLKST_FREE);
 	} else if (id->reftypecount[ref_is_inode]) {
-		set_ip_blockmap(ip, 0); /* 0=do not add to dirtree */
+		set_ip_bitmap(ip);
 	} else if (id->reftypecount[ref_as_data]) {
-		fsck_blockmap_set(ip, dt->block,  _("reference-repaired data"),
-				  GFS2_BLKST_USED);
+		fsck_bitmap_set(ip, dt->block,  _("reference-repaired data"),
+				GFS2_BLKST_USED);
 	} else if (id->reftypecount[ref_as_meta]) {
 		if (is_dir(&ip->i_di, sdp->gfs1))
-			fsck_blockmap_set(ip, dt->block,
-					  _("reference-repaired leaf"),
-					  sdp->gfs1 ? GFS2_BLKST_DINODE :
-					  GFS2_BLKST_USED);
+			fsck_bitmap_set(ip, dt->block,
+					_("reference-repaired leaf"),
+					sdp->gfs1 ? GFS2_BLKST_DINODE :
+					GFS2_BLKST_USED);
 		else
-			fsck_blockmap_set(ip, dt->block,
-					  _("reference-repaired indirect"),
-					  sdp->gfs1 ? GFS2_BLKST_DINODE :
-					  GFS2_BLKST_USED);
+			fsck_bitmap_set(ip, dt->block,
+					_("reference-repaired indirect"),
+					sdp->gfs1 ? GFS2_BLKST_DINODE :
+					GFS2_BLKST_USED);
 	} else {
 		if (acceptable_ref == ref_as_ea)
-			fsck_blockmap_set(ip, dt->block,
-					  _("reference-repaired extended "
-					    "attribute"),
-					  sdp->gfs1 ? GFS2_BLKST_DINODE :
-					  GFS2_BLKST_USED);
+			fsck_bitmap_set(ip, dt->block,
+					_("reference-repaired extended "
+					  "attribute"),
+					sdp->gfs1 ? GFS2_BLKST_DINODE :
+					GFS2_BLKST_USED);
 		else {
 			log_err(_("Error: The remaining reference to block "
 				  " %lld (0x%llx) is as extended attribute, "
@@ -574,9 +614,9 @@ static void resolve_last_reference(struct gfs2_sbd *sdp, struct duptree *dt,
 				ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT;
 				ip->i_di.di_blocks--;
 				bmodified(ip->i_bh);
-				fsck_blockmap_set(ip, dt->block,
-						  _("reference-repaired EA"),
-						  GFS2_BLKST_FREE);
+				fsck_bitmap_set(ip, dt->block,
+						_("reference-repaired EA"),
+						GFS2_BLKST_FREE);
 				log_err(_("The bad extended attribute was "
 					  "removed.\n"));
 			} else {
@@ -725,8 +765,6 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *dt)
 				    (unsigned long long)dup_blk);
 			if (dh.dt)
 				dup_delete(dh.dt);
-			/* Now fix the block type of the block in question. */
-			gfs2_blockmap_set(bl, dup_blk, GFS2_BLKST_FREE);
 			check_n_fix_bitmap(sdp, dup_blk, 0, GFS2_BLKST_FREE);
 		}
 	}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index f114d2b..214fa03 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -375,9 +375,9 @@ static int wrong_leaf(struct gfs2_inode *ip, struct gfs2_inum *entry,
 				(unsigned long long)real_leaf,
 				(unsigned long long)real_leaf,
 				(unsigned long long)ip->i_di.di_blocks);
-			fsck_blockmap_set(ip, real_leaf, _("split leaf"),
-					  sdp->gfs1 ? GFS2_BLKST_DINODE :
-					  GFS2_BLKST_USED);
+			fsck_bitmap_set(ip, real_leaf, _("split leaf"),
+					sdp->gfs1 ? GFS2_BLKST_DINODE :
+					GFS2_BLKST_USED);
 		}
 		/* If the misplaced dirent was supposed to be earlier in the
 		   hash table, we need to adjust our counts for the blocks
@@ -475,9 +475,9 @@ static int basic_dentry_checks(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			return 0;
 		}
 		/* Don't be tempted to do this:
-		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("corrupt directory entry"),
-				  GFS2_BLKST_FREE);
+		fsck_bitmap_set(ip, ip->i_di.di_num.no_addr,
+				_("corrupt directory entry"),
+				GFS2_BLKST_FREE);
 		We can't free it because another dir may have a valid reference
 		to it. Just return 1 so we can delete the bad dirent. */
 		log_err( _("Bad directory entry deleted.\n"));
@@ -893,9 +893,9 @@ static void pad_with_leafblks(struct gfs2_inode *ip, uint64_t *tbl,
 			(unsigned long long)new_leaf_blk,
 			(unsigned long long)new_leaf_blk,
 			lindex, lindex, new_len);
-		fsck_blockmap_set(ip, new_leaf_blk, _("pad leaf"),
-				  ip->i_sbd->gfs1 ?
-				  GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+		fsck_bitmap_set(ip, new_leaf_blk, _("pad leaf"),
+				ip->i_sbd->gfs1 ?
+				GFS2_BLKST_DINODE : GFS2_BLKST_USED);
 		/* Fix the hash table in memory to have the new leaf */
 		for (i = 0; i < new_len; i++)
 			tbl[lindex + i] = cpu_to_be64(new_leaf_blk);
@@ -997,7 +997,7 @@ static int lost_leaf(struct gfs2_inode *ip, uint64_t *tbl, uint64_t leafno,
 	log_err(_("Directory entries from misplaced leaf block were relocated "
 		  "to lost+found.\n"));
 	/* Free the lost leaf. */
-	fsck_blockmap_set(ip, leafno, _("lost leaf"), GFS2_BLKST_FREE);
+	fsck_bitmap_set(ip, leafno, _("lost leaf"), GFS2_BLKST_FREE);
 	ip->i_di.di_blocks--;
 	bmodified(ip->i_bh);
 	/* Now we have to deal with the bad hash table entries pointing to the
@@ -1228,9 +1228,9 @@ static int fix_hashtable(struct gfs2_inode *ip, uint64_t *tbl, unsigned hsize,
 			  "(0x%llx) for index %d (0x%x)\n"),
 			(unsigned long long)new_leaf_blk,
 			(unsigned long long)new_leaf_blk, lindex, lindex);
-		fsck_blockmap_set(ip, new_leaf_blk, _("split leaf"),
-				  ip->i_sbd->gfs1 ?
-				  GFS2_BLKST_DINODE : GFS2_BLKST_USED);
+		fsck_bitmap_set(ip, new_leaf_blk, _("split leaf"),
+				ip->i_sbd->gfs1 ?
+				GFS2_BLKST_DINODE : GFS2_BLKST_USED);
 		log_err(_("Hash table repaired.\n"));
 		/* Fix up the hash table in memory to include the new leaf */
 		for (i = 0; i < *proper_len; i++)
@@ -1695,7 +1695,7 @@ build_it:
 		log_err(_("Error rebuilding %s.\n"), fn);
 		return -1;
 	}
-	fsck_blockmap_set(ip, ip->i_di.di_num.no_addr, fn, GFS2_BLKST_DINODE);
+	fsck_bitmap_set(ip, ip->i_di.di_num.no_addr, fn, GFS2_BLKST_DINODE);
 	reprocess_inode(ip, fn);
 	log_err(_("System file %s rebuilt.\n"), fn);
 	goto out_good;
@@ -1742,7 +1742,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 		return -1;
 	}
 	if (error > 0)
-		fsck_blockmap_set(sysinode, iblock, dirname, GFS2_BLKST_FREE);
+		fsck_bitmap_set(sysinode, iblock, dirname, GFS2_BLKST_FREE);
 
 	if (check_inode_eattr(sysinode, &pass2_fxns)) {
 		stack;
@@ -1888,9 +1888,6 @@ static int pass2_check_dir(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 
 		log_debug(_("Directory block %lld (0x%llx) is now marked as 'invalid'\n"),
 			   (unsigned long long)dirblk, (unsigned long long)dirblk);
-		/* Can't use fsck_blockmap_set here because we don't
-		   have an inode in memory. */
-		gfs2_blockmap_set(bl, dirblk, GFS2_BLKST_FREE);
 		check_n_fix_bitmap(sdp, dirblk, 0, GFS2_BLKST_FREE);
 	}
 
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index a3c0a60..dad1f5c 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -250,6 +250,7 @@ int pass3(struct gfs2_sbd *sdp)
 				continue;
 			}
 			q = bitmap_type(sdp, di->dinode.no_addr);
+			ip = fsck_load_inode(sdp, di->dinode.no_addr);
 			if (q == GFS2_BLKST_UNLINKED) {
 				log_err( _("Found unlinked directory "
 					   "containing bad block at block %llu"
@@ -264,12 +265,9 @@ int pass3(struct gfs2_sbd *sdp)
 						  di->dinode.no_addr,
 						  (unsigned long long)
 						  di->dinode.no_addr);
-					/* Can't use fsck_blockmap_set
-					   because we don't have ip */
-					gfs2_blockmap_set(bl, di->dinode.no_addr,
-							  GFS2_BLKST_FREE);
 					check_n_fix_bitmap(sdp, di->dinode.no_addr,
 							   0, GFS2_BLKST_FREE);
+					fsck_inode_put(&ip);
 					break;
 				} else
 					log_err( _("Unlinked directory with bad block remains\n"));
@@ -287,13 +285,10 @@ int pass3(struct gfs2_sbd *sdp)
 					    "marked as free\n"),
 					  (unsigned long long)di->dinode.no_addr,
 					  (unsigned long long)di->dinode.no_addr);
-				/* Can't use fsck_blockmap_set
-				   because we don't have ip */
-				gfs2_blockmap_set(bl, di->dinode.no_addr,
-						  GFS2_BLKST_FREE);
 				check_n_fix_bitmap(sdp, di->dinode.no_addr, 0,
 						   GFS2_BLKST_FREE);
 				log_err( _("The block was cleared\n"));
+				fsck_inode_put(&ip);
 				break;
 			}
 
@@ -301,17 +296,15 @@ int pass3(struct gfs2_sbd *sdp)
 				   " (0x%llx)\n"),
 				 (unsigned long long)di->dinode.no_addr,
 				 (unsigned long long)di->dinode.no_addr);
-			ip = fsck_load_inode(sdp, di->dinode.no_addr);
 			/* Don't skip zero size directories with eattrs */
 			if (!ip->i_di.di_size && !ip->i_di.di_eattr){
 				log_err( _("Unlinked directory has zero "
 					   "size.\n"));
 				if (query( _("Remove zero-size unlinked "
 					    "directory? (y/n) "))) {
-					fsck_blockmap_set(ip,
-							  di->dinode.no_addr,
+					fsck_bitmap_set(ip, di->dinode.no_addr,
 						_("zero-sized unlinked inode"),
-							  GFS2_BLKST_FREE);
+							GFS2_BLKST_FREE);
 					fsck_inode_put(&ip);
 					break;
 				} else {
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index dcd5ba7..25c63b7 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -82,9 +82,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
 					check_metatree(ip, &pass4_fxns_delete);
-					fsck_blockmap_set(ip, ii->di_num.no_addr,
-							  _("bad unlinked"),
-							  GFS2_BLKST_FREE);
+					fsck_bitmap_set(ip, ii->di_num.no_addr,
+							_("bad unlinked"),
+							GFS2_BLKST_FREE);
 					fsck_inode_put(&ip);
 					continue;
 				} else
@@ -101,9 +101,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
 					check_metatree(ip, &pass4_fxns_delete);
-					fsck_blockmap_set(ip, ii->di_num.no_addr,
-						  _("invalid unlinked"),
-							  GFS2_BLKST_FREE);
+					fsck_bitmap_set(ip, ii->di_num.no_addr,
+							_("invalid unlinked"),
+							GFS2_BLKST_FREE);
 					fsck_inode_put(&ip);
 					log_err( _("The inode was deleted\n"));
 				} else {
@@ -122,9 +122,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 				log_err( _("Unlinked inode has zero size\n"));
 				if (query(_("Clear zero-size unlinked inode? "
 					   "(y/n) "))) {
-					fsck_blockmap_set(ip, ii->di_num.no_addr,
+					fsck_bitmap_set(ip, ii->di_num.no_addr,
 						_("unlinked zero-length"),
-							  GFS2_BLKST_FREE);
+							GFS2_BLKST_FREE);
 					fsck_inode_put(&ip);
 					continue;
 				}
-- 
2.5.5




More information about the Cluster-devel mailing list