cluster: RHEL510 - fsck.gfs2: Don't use old_leaf if it was a duplicate

Bob Peterson rpeterso at fedoraproject.org
Fri Apr 5 13:45:47 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=1aa0537d3cbc2ede5dc994b356851952c762432f
Commit:        1aa0537d3cbc2ede5dc994b356851952c762432f
Parent:        62a86dd0925a4d914f01d041a43e26811b66f556
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Tue Aug 9 14:22:12 2011 -0500
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Apr 5 06:25:00 2013 -0700

fsck.gfs2: 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#877150
---
 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 282822e..5c09e85 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -617,7 +617,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
@@ -645,7 +645,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);
@@ -664,7 +665,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,
@@ -676,6 +681,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)


More information about the cluster-commits mailing list