]> git.neil.brown.name Git - LaFS.git/commitdiff
Be sure to remove all credits when releasing a block from a page.
authorNeilBrown <neilb@suse.de>
Sat, 8 Aug 2009 04:56:29 +0000 (14:56 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 8 Aug 2009 04:56:29 +0000 (14:56 +1000)
As it has just become unlinked.

block.c

diff --git a/block.c b/block.c
index ba828032e51f2205a5323bab670d937267e96c2b..cfe8da3a5850fcd731978375de5d899a7f4175de 100644 (file)
--- a/block.c
+++ b/block.c
@@ -217,6 +217,7 @@ int lafs_release_page(struct page *page, gfp_t gfp_flags)
        struct address_space * const mapping = page->mapping;
        int bits = PAGE_SHIFT - mapping->host->i_blkbits;
        int i;
+       int credits = 0;
        struct indexblock *parents[1<<bits];
        struct datablock *b = NULL;
 
@@ -278,6 +279,14 @@ int lafs_release_page(struct page *page, gfp_t gfp_flags)
                list_del_init(&b[i].b.lru);
                list_del_init(&b[i].b.peers);
                (void)getdref_locked(&b[i], MKREF(lafs_release));
+               if (test_and_clear_bit(B_Credit, &b[i].b.flags))
+                       credits++;
+               if (test_and_clear_bit(B_ICredit, &b[i].b.flags))
+                       credits++;
+               if (test_and_clear_bit(B_NCredit, &b[i].b.flags))
+                       credits++;
+               if (test_and_clear_bit(B_NICredit, &b[i].b.flags))
+                       credits++;
                /* When !PagePrivate(page), && refcnt, we hold a ref on the
                 * first block which holds a ref on the page.
                 * When ref on firstblock with !PagePrivate(page) becomes zero,
@@ -293,6 +302,7 @@ int lafs_release_page(struct page *page, gfp_t gfp_flags)
        ClearPagePrivate(page);
 
        spin_unlock(&mapping->private_lock);
+       lafs_space_return(fs_from_inode(mapping->host), credits);
 
        for (i = 0; i < (1<<bits); i++) {
                putdref(&b[i], MKREF(lafs_release));