Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > cbb671ab88b26cace8ea014e0c2e80eb > files > 9

gfs-utils-0.1.20-14.el5.src.rpm

commit 1c9c96f17d03c51fd875eea94f14f517f2c2c446
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Thu Aug 4 14:40:32 2011 -0500

    fsck.gfs can not check file system with 500,000 files
    
    This patch allows fsck.gfs2 to properly process "continuation
    leaf blocks" in directories.  This enables gfs_fsck to process
    directories properly when they get very big.
    
    rhbz#704328

diff --git a/gfs/gfs_fsck/metawalk.c b/gfs/gfs_fsck/metawalk.c
index e28a1cc..e14d4dc 100644
--- a/gfs/gfs_fsck/metawalk.c
+++ b/gfs/gfs_fsck/metawalk.c
@@ -251,35 +251,39 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update,
 			ref_count++;
 			continue;
 		}
-		if(check_range(sbp, old_leaf) == 0 && ref_count != exp_count){
-			log_err("Dir #%"PRIu64" has an incorrect number "
-				"of pointers to leaf #%"PRIu64"\n"
-				"\tFound: %u,  Expected: %u\n",
-				ip->i_num.no_addr, old_leaf, ref_count,
-				exp_count);
-			errors_found++;
-			if (query(ip->i_sbd, "Attempt to fix it? (y/n) ")) {
-				int factor = 0, divisor = ref_count;
-
-				errors_corrected++;
-				get_and_read_buf(sbp, old_leaf, &lbh);
-				while (divisor > 1) {
-					factor++;
-					divisor /= 2;
+		do {
+			if(check_range(sbp, old_leaf) == 0 &&
+			   ref_count != exp_count){
+				log_err("Dir #%"PRIu64" has an incorrect "
+					"number of pointers to leaf #%"PRIu64
+					"\n\tFound: %u,  Expected: %u\n",
+					ip->i_num.no_addr, old_leaf, ref_count,
+					exp_count);
+				errors_found++;
+				if (query(ip->i_sbd, "Attempt to fix it? "
+					  "(y/n) ")) {
+					int factor = 0, divisor = ref_count;
+
+					errors_corrected++;
+					get_and_read_buf(sbp, old_leaf, &lbh);
+					while (divisor > 1) {
+						factor++;
+						divisor /= 2;
+					}
+					gfs_leaf_in(&oldleaf, BH_DATA(lbh));
+					oldleaf.lf_depth = ip->i_di.di_depth -
+						factor;
+					gfs_leaf_out(&oldleaf, BH_DATA(lbh));
+					write_buf(sbp, lbh, 0);
+					relse_buf(sbp, lbh);
 				}
-				gfs_leaf_in(&oldleaf, BH_DATA(lbh));
-				oldleaf.lf_depth = ip->i_di.di_depth - factor;
-				gfs_leaf_out(&oldleaf, BH_DATA(lbh));
-				write_buf(sbp, lbh, 0);
-				relse_buf(sbp, lbh);
+				else
+					return 1;
 			}
-			else
-				return 1;
-		}
-		ref_count = 1;
+			ref_count = 1;
+
+			count = 0;
 
-		count = 0;
-		do {
 			if (fsck_abort)
 				break;
 			/* Make sure the block number is in range. */
@@ -376,19 +380,16 @@ static int check_leaf_blks(struct fsck_inode *ip, int *update,
 					}
 					relse_buf(sbp, lbh);
 				}
-				/* FIXME: Need to get entry count and
-				 * compare it against leaf->lf_entries */
-				break; /* not a chain; go back to outer loop */
-			} else {
+			} else
 				relse_buf(sbp, lbh);
-				if(!leaf.lf_next)
-					break;
-				leaf_no = leaf.lf_next;
-				log_debug("Leaf chain detected.\n");
-			}
+			old_leaf = leaf_no;
+			memcpy(&oldleaf, &leaf, sizeof(oldleaf));
+			if (!leaf.lf_next)
+				break;
+			leaf_no = leaf.lf_next;
+			log_debug("Leaf chain 0x%llx detected.\n",
+				  (unsigned long long)leaf_no);
 		} while(1); /* while we have chained leaf blocks */
-		old_leaf = leaf_no;
-		memcpy(&oldleaf, &leaf, sizeof(oldleaf));
 	} /* for every leaf block */
 	return 0;
 }