From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 20 Feb 2007 17:52:14 -0000 Subject: [Cluster-devel] cluster/gfs/gfs_fsck metawalk.c pass2.c Message-ID: <20070220175214.2686.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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");