[Cluster-devel] [PATCH 03/42] libgfs2: let dir_split_leaf receive a "broken" lindex

rpeterso at redhat.com rpeterso at redhat.com
Mon Apr 8 14:40:35 UTC 2013


From: Bob Peterson <rpeterso at redhat.com>

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 bca622a..8994a0d 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -948,7 +948,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;
 
 	lp = calloc(1, half_len * sizeof(uint64_t));
 	if (lp == NULL) {
@@ -1151,7 +1151,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;
@@ -1173,7 +1173,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;
 
-- 
1.7.11.7




More information about the Cluster-devel mailing list