gfs2-utils: master - fsck.gfs2: Don't use old_leaf if it was a duplicate

Bob Peterson rpeterso at fedoraproject.org
Tue Aug 30 20:26:18 UTC 2011


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=7bc8438a4cd6019174c8f2f93757765849d796df
Commit:        7bc8438a4cd6019174c8f2f93757765849d796df
Parent:        defac4ceed053f5d94a4e423d080719ec75800d5
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Tue Aug 9 14:22:12 2011 -0500
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Mon Aug 29 12:53:53 2011 -0500

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#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 860790d..adaf8a0 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)


More information about the cluster-commits mailing list