[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	rpeterso sourceware org	2007-02-20 18:55:34

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

Log message:
	Resolves: bz 229220: 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=RHEL5&r1=1.8&r2=1.8.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_fsck/pass2.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.12.2.1&r2=1.12.2.2

--- cluster/gfs/gfs_fsck/metawalk.c	2006/02/02 01:14:56	1.8
+++ cluster/gfs/gfs_fsck/metawalk.c	2007/02/20 18:55:34	1.8.2.1
@@ -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 17:00:09	1.12.2.1
+++ cluster/gfs/gfs_fsck/pass2.c	2007/02/20 18:55:34	1.12.2.2
@@ -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");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]