cluster: RHEL56 - fsck.gfs2: metawalk needs to check for no valid leaf blocks

Bob Peterson rpeterso at fedoraproject.org
Sat Apr 10 04:53:22 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0e489a26b950339de685d22a4a2269310689885e
Commit:        0e489a26b950339de685d22a4a2269310689885e
Parent:        9107ed8993d8efc19be0c34e4874db3f229c1869
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Fri Jan 22 13:55:51 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Apr 9 23:35:19 2010 -0500

fsck.gfs2: metawalk needs to check for no valid leaf blocks

The code that validates directory leaf blocks was failing in rare
cases where the directory had no valid leaf blocks at all.
It would give a good return code and pretend everything was okay
when, in fact, it left corruption out there.

rhbz#455300
---
 gfs2/fsck/metawalk.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index f14f59b..85c6adb 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -544,7 +544,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	int error;
 	struct gfs2_leaf leaf, oldleaf;
 	uint64_t leaf_no, old_leaf, bad_leaf = -1;
-	uint64_t first_leaf_ptr = -1, first_ok_leaf = -1;
+	uint64_t first_ok_leaf;
 	struct gfs2_buffer_head *lbh;
 	int lindex;
 	struct gfs2_sbd *sbp = ip->i_sbd;
@@ -554,21 +554,27 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	/* 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
 	   with the first valid leaf. */
-	first_ok_leaf = -1;
+	first_ok_leaf = leaf_no = -1;
 	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
-		gfs2_get_leaf_nr(ip, lindex, &first_ok_leaf);
-		if (first_leaf_ptr == -1)
-			first_leaf_ptr = first_ok_leaf;
-		if(gfs2_check_range(ip->i_sbd, first_ok_leaf) == 0) {
-			lbh = bread(sbp, first_ok_leaf);
+		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
+		if (gfs2_check_range(ip->i_sbd, leaf_no) == 0) {
+			lbh = bread(sbp, leaf_no);
 			/* Make sure it's really a valid leaf block. */
 			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
 				brelse(lbh);
+				first_ok_leaf = leaf_no;
 				break;
 			}
 			brelse(lbh);
 		}
 	}
+	if (first_ok_leaf == -1) { /* no valid leaf found */
+		log_err( _("Directory #%llu (0x%llx) has no valid leaf "
+			   "blocks\n"),
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr);
+		return 1;
+	}
 	old_leaf = -1;
 	memset(&oldleaf, 0, sizeof(oldleaf));
 	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {


More information about the cluster-commits mailing list