[Ocfs2-tools-devel] [PATCH 2/3] fsck.ocfs2: Fix the cluster count if we changed it in pass 0.

Joel Becker joel.becker at oracle.com
Fri Jun 19 22:08:21 PDT 2009


At the start of pass 0, we fix the superblock's cluster count to match
the global bitmap.  After we do that, we actually verify the global
bitmap.  If we end up repairing the global bitmap in any way, we never
check to see if its cluster count changed.

This patch checks to see if the cluster count changed during repair.  If
so, the user is prompted to trust the new values.  This triggers a
reinit of the fsck state and a rescan of the global bitmap.  While the
fixed bitmap should be fine, the rescan is necessary to pick up the
clusters used.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 fsck.ocfs2/fsck.ocfs2.checks.8.in |    7 ++++++
 fsck.ocfs2/pass0.c                |   42 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index b780561..5aa8023 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -118,6 +118,13 @@ bitmap. This is only possible due to a failed volume resize operation.
 Answering yes updates the total clusters in the super block to the value
 specified in the global bitmap.
 
+.SS "FIXED_CHAIN_CLUSTERS"
+The global bitmap inode was repaired, resulting in a change to the total
+cluster count of the filesystem.
+
+Answering yes updates the total clusters in the super block to the value
+specified in the global bitmap.
+
 \" pass0.c
 
 .SS "GROUP_UNEXPECTED_DESC"
diff --git a/fsck.ocfs2/pass0.c b/fsck.ocfs2/pass0.c
index 66e18c7..a32bd18 100644
--- a/fsck.ocfs2/pass0.c
+++ b/fsck.ocfs2/pass0.c
@@ -1060,13 +1060,14 @@ errcode_t o2fsck_pass0(o2fsck_state *ost)
 {
 	errcode_t ret;
 	uint64_t blkno;
+	uint32_t pre_repair_clusters;
 	char *blocks = NULL;
 	char *pre_cache_buf = NULL;
 	struct ocfs2_dinode *di = NULL;
 	ocfs2_filesys *fs = ost->ost_fs;
 	ocfs2_cached_inode **ci;
 	int max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
-	int i, type;
+	int i, type, bitmap_retried = 0;
 
 	printf("Pass 0a: Checking cluster allocation chains\n");
 
@@ -1159,12 +1160,51 @@ errcode_t o2fsck_pass0(o2fsck_state *ost)
 		}
 	}
 
+retry_bitmap:
+	pre_repair_clusters = di->i_clusters;
 	ret = verify_bitmap_descs(ost, di, blocks + ost->ost_fs->fs_blocksize,
 				  blocks + (ost->ost_fs->fs_blocksize * 2));
 
 	if (ret)
 		goto out;
 
+	if (pre_repair_clusters != di->i_clusters) {
+		if (prompt(ost, PY, PR_FIXED_CHAIN_CLUSTERS,
+			   "Repair of global_bitmap changed the filesystem "
+			   "from %u clusters to %u clusters.  Trust "
+			   "global_bitmap?",
+			   pre_repair_clusters, di->i_clusters)) {
+			ost->ost_num_clusters = di->i_clusters;
+			fs->fs_clusters = di->i_clusters;
+			fs->fs_blocks = ocfs2_clusters_to_blocks(fs,
+							 fs->fs_clusters);
+			ret = o2fsck_state_reinit(fs, ost);
+			if (ret) {
+				com_err(whoami, ret, "while reinit "
+					"o2fsck_state.");
+				goto out;
+			}
+
+			/*
+			 * The reinit clears the bits found during the
+			 * scan of the global bitmap.  We need to go over
+			 * them again.  They really should come out clean
+			 * this time.  If they don't, we probably have
+			 * a serious problem.
+			 *
+			 * In an interactive run, the user can keep
+			 * retrying and abort when they give up.  In a
+			 * non-interactive mode, we can't loop forever.
+			 */
+			if (ost->ost_ask || !bitmap_retried) {
+				bitmap_retried = 1;
+				verbosef("Restarting global_bitmap %s\n",
+					 "scan");
+				goto retry_bitmap;
+			}
+		}
+	}
+
 	printf("Pass 0b: Checking inode allocation chains\n");
 
 	/* first the global inode alloc and then each of the node's
-- 
1.6.3.1




More information about the Ocfs2-tools-devel mailing list