From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 20 Feb 2007 18:20:29 -0000 Subject: [Cluster-devel] cluster/gfs/gfs_fsck metawalk.c pass2.c Message-ID: <20070220182029.26210.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 Changes by: rpeterso at sourceware.org 2007-02-20 18:20:29 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&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_fsck/pass2.c.diff?cvsroot=cluster&r1=1.13&r2=1.14 --- cluster/gfs/gfs_fsck/metawalk.c 2006/02/02 01:14:56 1.8 +++ cluster/gfs/gfs_fsck/metawalk.c 2007/02/20 18:20:28 1.9 @@ -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:43:49 1.13 +++ cluster/gfs/gfs_fsck/pass2.c 2007/02/20 18:20:28 1.14 @@ -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");