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

Bob Peterson rpeterso at redhat.com
Mon May 20 16:02:07 UTC 2013


----- Original Message -----
| 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.

Hi,

Good idea. I've implemented your change, and the replacement patch is
given below.

Regards,

Bob Peterson
Red Hat File Systems
---
commit 7e1170eec23957b084ca80828eac9fd1c8988062
Author: Bob Peterson <rpeterso at redhat.com>
Date:   Thu Feb 21 09:36:01 2013 -0700

    libgfs2: let dir_split_leaf receive a "broken" lindex
    
    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.

diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 89adf32..d009e2f 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -925,13 +925,13 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
 	}
 }
 
-void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex, uint64_t leaf_no,
+void dir_split_leaf(struct gfs2_inode *dip, uint32_t start, uint64_t leaf_no,
 		    struct gfs2_buffer_head *obh)
 {
 	struct gfs2_buffer_head *nbh;
 	struct gfs2_leaf *nleaf, *oleaf;
 	struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
-	uint32_t start, len, half_len, divider;
+	uint32_t len, half_len, divider;
 	uint64_t bn, *lp;
 	uint32_t name_len;
 	int x, moved = FALSE;
@@ -957,8 +957,6 @@ 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));
-
 	lp = calloc(1, half_len * sizeof(uint64_t));
 	if (lp == NULL) {
 		fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
@@ -1160,7 +1158,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 +1180,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;
 
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3147c83..3055355 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -468,7 +468,7 @@ extern void block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 extern void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t index,
 			     uint64_t *leaf_out);
 extern void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out);
-extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
+extern void dir_split_leaf(struct gfs2_inode *dip, uint32_t start,
 			   uint64_t leaf_no, struct gfs2_buffer_head *obh);
 extern void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block);
 extern int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t block);




More information about the Cluster-devel mailing list