]> git.neil.brown.name Git - LaFS.git/commitdiff
Release stray B_Async blocks if we find them.
authorNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 06:38:14 +0000 (16:38 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 07:58:20 +0000 (17:58 +1000)
There could still be some stray index blocks...
maybe fix that later.

Signed-off-by: NeilBrown <neilb@suse.de>
block.c
checkpoint.c
super.c

diff --git a/block.c b/block.c
index 60fe1a427a4ece35317604149a45498d4338bff4..ea64fcc2d77d9c0db304931319574aad2ce11f94 100644 (file)
--- a/block.c
+++ b/block.c
@@ -200,6 +200,10 @@ void lafs_invalidate_page(struct page *page, unsigned long offset)
                 *   wait for any pending IO to complete (so page can be freed)
                 */
                for (i = 0; i < (1<<bits); i++) {
+                       if (b_start >= offset &&
+                           test_and_clear_bit(B_Async, &b[i].b.flags))
+                               putdref(&b[i], MKREF(Async));
+
                        if (LAFSI(ino)->type >= TypeBase && start >= size)
                                /* Remove block from mapping and file */
                                lafs_erase_dblock(&b[i]);
index d3ba9fe0cae3c7966d61462b21eaea9cb01c7a7b..8bf84c5728b49bc58e347576045b36d2616cd6ab 100644 (file)
@@ -379,9 +379,14 @@ again:
        while ((b = lafs_get_flushable(fs, oldphase)) != NULL) {
                int unlock = 1;
                dprintk("Checkpoint Block %s\n", strblk(b));
-               /* FIXME I should check for Async children and
-                * de-async them.
-                */
+
+               if (test_and_clear_bit(B_Async, &b->flags)) {
+                       /* this shouldn't normally happen, but
+                        * it is possible, so check anyway
+                        */
+                       putref(b, MKREF(async));
+                       lafs_wake_thread(fs);
+               }
 
                if (!!test_bit(B_Phase1, &b->flags) != oldphase)
                        /* lafs_pin_dblock flipped phase for us */;
diff --git a/super.c b/super.c
index 9bd0ccd5c054a8a9bdcc89e3484f4d58356bc377..36e539b0097b02e938cc646353ac0ec8849d9f5e 100644 (file)
--- a/super.c
+++ b/super.c
@@ -1246,6 +1246,14 @@ void lafs_destroy_inode(struct inode *inode)
                set_bit(I_Destroyed, &LAFSI(inode)->iflags);
                putdref(db, MKREF(destroy));
        } else {
+               spin_lock(&inode->i_data.private_lock);
+               if (LAFSI(inode)->iblock)
+                       LAFS_BUG(atomic_read(&LAFSI(inode)->iblock->b.refcnt),
+                                &LAFSI(inode)->iblock->b);
+               /* FIXME could there be Async blocks keeps a refcount?
+                * we should free them
+                */
+               spin_unlock(&inode->i_data.private_lock);
                lafs_release_index(&LAFSI(inode)->free_index);
                call_rcu(&LAFSI(inode)->md.rcu,
                         kfree_inode);