]> git.neil.brown.name Git - LaFS.git/commitdiff
When incorp empty child out of parent, remove from uninc list.
authorNeilBrown <neilb@suse.de>
Sun, 13 Jun 2010 07:54:43 +0000 (17:54 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 13 Jun 2010 07:57:47 +0000 (17:57 +1000)
When we notice that an index block is empty and so remove
it from the parent, we need to remove it from the uninc list
and also clear any Dirty bit.

Also, the check for children turns out to be pointless.  I
was confused by the uninc list I think.

Signed-off-by: NeilBrown <neilb@suse.de>
modify.c

index 89745f5f43b20fc98fdb69b541e2f69dd6b98c0d..cfcc109061bc8909dd14aeea653d2c5fb34775c4 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1688,7 +1688,7 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
 {
        int offset;     /* start of block where indexing is */
        struct indexblock *new = NULL, *orig_ib, *locked_ib, *nxt;
-       struct block *uninc = NULL;
+       struct block *uninc = NULL, **bp;
        int rv = 0;
        u32 next;
        char *buf;
@@ -1917,9 +1917,6 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        orig_ib = ib;
        locked_ib = ib;
  recurse:
-       if (!list_empty(&ib->children))
-               /* If there are children, we cannot treat this block as empty. */
-               return;
        if (test_bit(B_InoIdx, &ib->b.flags)) {
                /* Empty InoIdx blocks are allowed.  However depth must
                 * be 1.  This is where we suddenly collapse a now-empty
@@ -1965,6 +1962,25 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
         */
        up_write(&ib->b.inode->i_alloc_sem);
 
+       /* ib is empty and so we are going to remove it from the parent.
+        * So we need to clear any 'dirty' status and remove from the
+        * uninc list
+        */
+       if (test_bit(B_Uninc, &ib->b.flags))
+               for (bp = &ib->b.parent->uninc ; *bp ; ) {
+                       if (*bp == &ib->b) {
+                               *bp = ib->b.chain;
+                               clear_bit(B_Uninc, &ib->b.flags);
+                               putiref(ib, MKREF(uninc));
+                       } else
+                               bp = &(*bp)->chain;
+               }
+       if (test_and_clear_bit(B_Dirty, &ib->b.flags))
+               lafs_space_return(fs, 1);
+       if (test_and_clear_bit(B_Realloc, &ib->b.flags))
+               lafs_space_return(fs, 1);
+       /* refile should remove from leaf list */
+       lafs_refile(&ib->b, 0);
        /* Options for how to handle the fact that ib is now empty.
         * If this block is not yet incorporated, it can
         *    be quietly deleted.