From mboxrd@z Thu Jan 1 00:00:00 1970 From: rohara@sourceware.org Date: 16 Nov 2006 20:12:46 -0000 Subject: [Cluster-devel] cluster/gfs2/fsck metawalk.c Message-ID: <20061116201246.27386.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: rohara at sourceware.org 2006-11-16 20:12:46 Modified files: gfs2/fsck : metawalk.c Log message: Detect and fix potential endia problem in lf_dirent_format. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/metawalk.c.diff?cvsroot=cluster&r1=1.4&r2=1.5 --- cluster/gfs2/fsck/metawalk.c 2006/11/14 22:51:35 1.4 +++ cluster/gfs2/fsck/metawalk.c 2006/11/16 20:12:45 1.5 @@ -162,21 +162,39 @@ } } + enum update_flags u = not_updated; + lbh = bread(sbp, leaf_no); gfs2_leaf_in(&leaf, lbh->b_data); + /* + * Early versions of GFS2 had an endianess bug in the kernel + * that set lf_dirent_format to cpu_to_be16(GFS2_FORMAT_DE). + * This was fixed to use cpu_to_be32(), but we should check + * for incorrect values and replace them with the correct value. */ + + if (leaf.lf_dirent_format == (GFS2_FORMAT_DE << 16)) { + log_debug("incorrect lf_dirent_format@leaf #%" PRIu64 "\n", leaf_no); + leaf.lf_dirent_format = GFS2_FORMAT_DE; + gfs2_leaf_out(&leaf, lbh->b_data); + u = updated; + } + exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth)); log_debug("expected count %u - di_depth %u, leaf depth %u\n", exp_count, ip->i_di.di_depth, leaf.lf_depth); + if(pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) { error = check_entries(ip, lbh, index, DIR_EXHASH, update, &count, pass); /* Since the buffer possibly got - updated directly, release it now, - and grab it again later if we need it */ + * updated directly, release it now, + * and grab it again later if we need it. */ + brelse(lbh, *update); + if(error < 0) { stack; return -1; @@ -186,9 +204,8 @@ return 1; if(update && (count != leaf.lf_entries)) { - enum update_flags f; + enum update_flags f = not_updated; - f = not_updated; lbh = bread(sbp, leaf_no); gfs2_leaf_in(&leaf, lbh->b_data); @@ -210,7 +227,9 @@ * compare it against leaf->lf_entries */ break; } else { - brelse(lbh, not_updated); + if (u == updated) + log_debug("Fixing lf_dirent_format.\n"); + brelse(lbh, u); if(!leaf.lf_next) break; leaf_no = leaf.lf_next;