Hi, On Tue, 2013-05-14 at 11:21 -0500, Bob Peterson wrote: > For ordinary leaf blocks, the hash table must follow the rules, > which means it needs to follow a power-of-two boundary. In other > words, it needs to enforce that: start = (lindex & ~(len - 1)); > But when doing repairs, fsck will need to detect when hash tables > violate this rule and fix it. In that case, it may need to pass > in an invalid starting offset for a leaf to split. This patch > moves the responsibility for checking the starting block to the > calling function. > > rhbz#902920 > --- > gfs2/libgfs2/fs_ops.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c > index 89adf32..11ef6b4 100644 > --- a/gfs2/libgfs2/fs_ops.c > +++ b/gfs2/libgfs2/fs_ops.c > @@ -957,7 +957,7 @@ void dir_split_leaf(struct gfs2_inode *dip, uint32_t > lindex, uint64_t leaf_no, > len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth)); > half_len = len >> 1; > > - start = (lindex & ~(len - 1)); > + start = lindex; Why not just rename the lindex as start? Otherwise this might be confusing to have two names for the same variable,
Steve. > > lp = calloc(1, half_len * sizeof(uint64_t)); > if (lp == NULL) { > @@ -1160,7 +1160,7 @@ static int dir_e_add(struct gfs2_inode *dip, const char > *filename, int len, > struct gfs2_buffer_head *bh, *nbh; > struct gfs2_leaf *leaf, *nleaf; > struct gfs2_dirent *dent; > - uint32_t lindex; > + uint32_t lindex, llen; > uint32_t hash; > uint64_t leaf_no, bn; > int err = 0; > @@ -1182,7 +1182,10 @@ restart: > if (dirent_alloc(dip, bh, len, &dent)) { > > if (be16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) { > - dir_split_leaf(dip, lindex, leaf_no, bh); > + llen = 1 << (dip->i_di.di_depth - > + be16_to_cpu(leaf->lf_depth)); > + dir_split_leaf(dip, lindex & ~(llen - 1), > + leaf_no, bh); > brelse(bh); > goto restart; >