Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 35

gfs2-utils-0.1.62-28.el5.src.rpm

commit 0e489a26b950339de685d22a4a2269310689885e
Author: Bob Peterson <bob@ganesha.peterson>
Date:   Fri Jan 22 13:55:51 2010 -0600

    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

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++) {