From: NeilBrown Date: Tue, 22 Jun 2010 02:35:32 +0000 (+1000) Subject: Add EmptyIndex flag. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=577b926302f3dab482fe4996c372a562f4bd9e81;p=LaFS.git Add EmptyIndex flag. This signals that an index block is known to be empty and should normally be ignored. It may never be set on an InoIdx block. Normally it stays set once set. However for the first index block in a parent, it can be cleared again if any children appear. Signed-off-by: NeilBrown --- diff --git a/checkpoint.c b/checkpoint.c index 6689afc..b2ebbf2 100644 --- a/checkpoint.c +++ b/checkpoint.c @@ -118,6 +118,8 @@ static char *strflags(struct block *b) strcat(ans, "PhysValid,"); if (test_bit(B_PrimaryRef, &b->flags)) strcat(ans, "PrimaryRef,"); + if (test_bit(B_EmptyIndex, &b->flags)) + strcat(ans, "EmptyIndex,"); if (test_bit(B_Uninc, &b->flags)) strcat(ans, "Uninc,"); diff --git a/index.c b/index.c index 02241ee..4483ec1 100644 --- a/index.c +++ b/index.c @@ -355,6 +355,13 @@ block_adopt(struct block *blk, struct indexblock *parent) } LAFS_BUG(blk->parent != parent, blk); } else { + if (test_bit(B_EmptyIndex, &parent->b.flags)) { + LAFS_BUG(!test_bit(B_Index, &parent->b.flags), &parent->b); + LAFS_BUG(test_bit(B_InoIdx, &parent->b.flags), &parent->b); + LAFS_BUG(parent->b.fileaddr != parent->b.parent->b.fileaddr, &parent->b); + + clear_bit(B_EmptyIndex, &parent->b.flags); + } LAFS_BUG(parent == iblk(blk), blk); blk->parent = parent; getiref(parent, MKREF(child)); diff --git a/modify.c b/modify.c index 8dc1922..c44e4dc 100644 --- a/modify.c +++ b/modify.c @@ -117,7 +117,8 @@ static int incorp_index(struct block *b) struct block, siblings); LAFS_BUG(b->siblings.prev == &b->parent->children, b); putref(pb, MKREF(primary)); - lafs_hash_iblock(iblk(b)); + if (!test_bit(B_EmptyIndex, &b->flags)) + lafs_hash_iblock(iblk(b)); } putref(b, MKREF(uninc)); return cr; diff --git a/state.h b/state.h index 071591f..26c0cd6 100644 --- a/state.h +++ b/state.h @@ -401,6 +401,9 @@ struct indexblock { #define dblk(__bl) container_of(__bl, struct datablock, b) enum { + /* NOTE: 32 flags in used. Need to overlap 'data' with 'index' if + * we need more + */ /* First flags that are meaningful for both Data and Index blocks * Currently 23 */ B_Phase1 = 0, /* phase when pinned - must be '1' - used for indexing */ @@ -463,6 +466,12 @@ enum { * which is either the primary or another block holding * a PrimaryRef. */ + B_EmptyIndex, /* Index block is empty, has no (non-EmptyIndex) children, + * will be destroyed soon. Indexing must avoid it + * unless if the first child of parent. + * Gets allocated to '0'. + * Flag only set under B_IOLock. + */ }; /* indexing info stays in the block, not in the inode */ struct lafs_inode {