From: NeilBrown Date: Sun, 13 Jun 2010 07:54:43 +0000 (+1000) Subject: When incorp empty child out of parent, remove from uninc list. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=228e0f9cd1db5dcbb7b280812e13b771036ffa51;p=LaFS.git When incorp empty child out of parent, remove from uninc list. 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 --- diff --git a/modify.c b/modify.c index 89745f5..cfcc109 100644 --- 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.