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

Bob Peterson rpeterso at redhat.com
Tue May 14 16:21:26 UTC 2013


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;
 
 	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;
 
-- 
1.7.11.7




More information about the Cluster-devel mailing list