[Cluster-devel] cluster/gfs/gfs_fsck metawalk.c pass2.c

rpeterso at sourceware.org rpeterso at sourceware.org
Tue Feb 20 17:52:14 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	STABLE
Changes by:	rpeterso at sourceware.org	2007-02-20 17:52:13

Modified files:
	gfs/gfs_fsck   : metawalk.c pass2.c 

Log message:
	Resolves: bz 229200: gfs_fsck stuck in infinite loop

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_fsck/metawalk.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.4.2.3.6.2&r2=1.4.2.3.6.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_fsck/pass2.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.3.2.4.6.2&r2=1.3.2.4.6.3

--- cluster/gfs/gfs_fsck/metawalk.c	2006/02/02 01:16:10	1.4.2.3.6.2
+++ cluster/gfs/gfs_fsck/metawalk.c	2007/02/20 17:52:13	1.4.2.3.6.3
@@ -83,6 +83,12 @@
 			  }*/
 		}
 
+		if (de.de_rec_len < sizeof(struct gfs_dirent)) {
+			log_err("Entry %"PRIu64" of directory %"
+				PRIu64" is corrupt, skipping.\n",
+				BH_BLKNO(bh), ip->i_di.di_num.no_addr);
+			break;
+		}
 		if ((char *)dent + de.de_rec_len >= bh_end){
 			log_debug("Last entry processed.\n");
 			break;
@@ -184,6 +190,14 @@
 			}
 			gfs_leaf_in(&leaf, BH_DATA(lbh));
 
+			/* Make sure it's really a leaf. */
+			if (leaf.lf_header.mh_type != GFS_METATYPE_LF) {
+				log_err("Inode %" PRIu64 " points to bad leaf "
+					PRIu64 ".\n", ip->i_di.di_num.no_addr,
+					leaf_no);
+				relse_buf(sbp, lbh);
+				break;
+			}
 			exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth));
 			log_debug("expected count %u - %u %u\n", exp_count,
 				  ip->i_di.di_depth, leaf.lf_depth);
--- cluster/gfs/gfs_fsck/pass2.c	2006/11/17 16:32:49	1.3.2.4.6.2
+++ cluster/gfs/gfs_fsck/pass2.c	2007/02/20 17:52:13	1.3.2.4.6.3
@@ -277,10 +277,9 @@
 			tmp_name);
 		if(query(ip->i_sbd, "Clear directory entry tp out of range block? (y/n) ")) {
 			log_err("Clearing %s\n", tmp_name);
-			if(dirent_del(ip, bh, prev_de, dent)) {
-				stack;
-				return -1;
-			}
+			if(dirent_del(ip, bh, prev_de, dent))
+				log_err("Error encountered while removing bad "
+					"directory entry.  Skipping.\n");
 			return 1;
 		} else {
 			log_err("Directory entry to out of range block remains\n");
@@ -339,10 +338,9 @@
 			/* FIXME: make sure all blocks referenced by
 			 * this inode are cleared in the bitmap */
 
-			if(dirent_del(ip, bh, prev_de, dent)) {
-				stack;
-				return -1;
-			}
+			if(dirent_del(ip, bh, prev_de, dent))
+				log_err("Error encountered while removing bad "
+					"directory entry.  Skipping.\n");
 			log_warn("Directory entry '%s' cleared\n", tmp_name);
 			return 1;
 		} else {
@@ -369,10 +367,9 @@
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			free_inode(&entry_ip);
 
-			if(dirent_del(ip, bh, prev_de, dent)) {
-				stack;
-				return -1;
-			}
+			if(dirent_del(ip, bh, prev_de, dent))
+				log_err("Error encountered while removing bad "
+					"directory entry.  Skipping.\n");
 			return 1;
 		} else {
 			log_err("Stale directory entry remains\n");




More information about the Cluster-devel mailing list