[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [Patch 29/44] fsck.gfs2: check_leaf_blks: Don't use old_leaf if it was a duplicate



>From 98ccc0cb40a604a943e029f1a475dd911807c22b Mon Sep 17 00:00:00 2001
From: Bob Peterson <rpeterso redhat com>
Date: Tue, 9 Aug 2011 14:22:12 -0500
Subject: [PATCH 29/44] fsck.gfs2: check_leaf_blks: Don't use old_leaf if it
 was a duplicate

In function check_leaf_blks fsck.gfs2 keeps track of the current leaf
and the previous leaf.  It can only check the number of pointers is
correct for the old leaf after it finds a new leaf block.  However,
it was getting confused if the old leaf was a duplicate reference.
If the old leaf was a duplicate referenced by a different dinode, we
can't check the number of pointers because the number of pointers may
be for that other dinode's reference, not this one.  The other dinode
referencing this leaf block may have the correct depth and this one
may not.  This patch adds an extra check for the old leaf block being
a duplicate before checking the number of pointers.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index fe1ae25..965bdd1 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -602,7 +602,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	struct gfs2_buffer_head *lbh;
 	int lindex;
 	struct gfs2_sbd *sdp = ip->i_sbd;
-	int ref_count = 0;
+	int ref_count = 0, old_was_dup;
 
 	/* Find the first valid leaf pointer in range and use it as our "old"
 	   leaf. That way, bad blocks at the beginning will be overwritten
@@ -630,7 +630,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	}
 	old_leaf = -1;
 	memset(&oldleaf, 0, sizeof(oldleaf));
-	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+	old_was_dup = 0;
+	for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
 		if (fsck_abort)
 			break;
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
@@ -649,7 +650,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		do {
 			if (fsck_abort)
 				return 0;
-			if (pass->check_num_ptrs &&
+			/* If the old leaf was a duplicate referenced by a
+			   previous dinode, we can't check the number of
+			   pointers because the number of pointers may be for
+			   that other dinode's reference, not this one. */
+			if (pass->check_num_ptrs && !old_was_dup &&
 			    valid_block(ip->i_sbd, old_leaf)) {
 				error = pass->check_num_ptrs(ip, old_leaf,
 							     &ref_count,
@@ -661,6 +666,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			error = check_leaf(ip, lindex, pass, &ref_count,
 					   &leaf_no, old_leaf, &bad_leaf,
 					   first_ok_leaf, &leaf, &oldleaf);
+			old_was_dup = (error == -EEXIST);
 			old_leaf = leaf_no;
 			memcpy(&oldleaf, &leaf, sizeof(oldleaf));
 			if (!leaf.lf_next || error)
-- 
1.7.4.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]