]> git.neil.brown.name Git - LaFS.git/commitdiff
Add EmptyIndex flag.
authorNeilBrown <neilb@suse.de>
Tue, 22 Jun 2010 02:35:32 +0000 (12:35 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 22 Jun 2010 20:59:47 +0000 (06:59 +1000)
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 <neilb@suse.de>
checkpoint.c
index.c
modify.c
state.h

index 6689afc00b3fb35a7301ea74937c42d50cdb6558..b2ebbf2d8149051151d6247fb4273b53c3e9465b 100644 (file)
@@ -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 02241ee15194abbaed7969d45cb663d4e1d65276..4483ec1ed0ceec250c16d80951e36d519db429b5 100644 (file)
--- 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));
index 8dc192217f80db30de053db5751fa9879b4ae990..c44e4dc71c41133010ac4a0ec0aa3d5639bca434 100644 (file)
--- 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 071591f257b90b9cec8eeece7fa87cced79e2a70..26c0cd62ab159f9e8ad99cea731966eb02ecbb5d 100644 (file)
--- 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 {