]> git.neil.brown.name Git - LaFS.git/commitdiff
Don't use I_ICredit for UnincCredit when cleaning.
authorNeilBrown <neilb@suse.de>
Sat, 2 Oct 2010 04:31:21 +0000 (14:31 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 10 Oct 2010 23:33:55 +0000 (10:33 +1100)
ICredit is only to be used when dirtying a block, so any setting of
UnincCredit for cleaning must get the credit from elsewhere.  If no
such credit is available, fall back on dirtying the block.

Signed-off-by: NeilBrown <neilb@suse.de>
clean.c
cluster.c
index.c

diff --git a/clean.c b/clean.c
index f135cf5a4c2abcc187bc22e2ac602f668ddc3e69..ed37560837096a96465f4a0942cd420eb5192644 100644 (file)
--- a/clean.c
+++ b/clean.c
@@ -17,6 +17,7 @@
 static int mark_cleaning(struct block *b)
 {
        int err;
+       int credits;
 
        if (test_bit(B_Realloc, &b->flags))
                /* As cleaning is single threaded,
@@ -29,13 +30,12 @@ static int mark_cleaning(struct block *b)
        if (err)
                return err;
        LAFS_BUG(!test_bit(B_Valid, &b->flags), b);
-       if (!test_bit(B_Realloc, &b->flags)) {
-               if (lafs_space_alloc(fs_from_inode(b->inode), 1, CleanSpace) == 1) {
-                       if (test_and_set_bit(B_Realloc, &b->flags))
-                               lafs_space_return(fs_from_inode(b->inode), 1);
-               } else
-                       return -EAGAIN;
-       }
+       credits = lafs_space_alloc(fs_from_inode(b->inode), 2, CleanSpace);
+       if (credits == 0)
+               return -EAGAIN;
+       if (!test_and_set_bit(B_Realloc, &b->flags))
+               credits--;
+
        lafs_pin_block(b);
        if (test_bit(B_Dirty, &b->flags)) {
                /* If dirty, then now that it is pinned,
@@ -43,14 +43,12 @@ static int mark_cleaning(struct block *b)
                 * Realloc
                 */
                if (test_and_clear_bit(B_Realloc, &b->flags))
-                       if (test_and_set_bit(B_Credit, &b->flags))
-                               lafs_space_return(fs_from_inode(b->inode), 1);
-               return 0;
+                       credits++;
        }
 
        if (!test_and_set_bit(B_UnincCredit, &b->flags))
-               if (!test_and_clear_bit(B_ICredit, &b->flags))
-                       LAFS_BUG(1, b); // ICredit should be set before we dirty a block.
+               credits--;
+       lafs_space_return(fs_from_inode(b->inode), credits);
 
        lafs_refile(b, 0);
        lafs_refile(&b->parent->b, 0);
index b94387a9b4fdb574fc03d2fdd067f55a6141fbbe..168426f385653c646e86e156dc2262d68ea96e72 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -531,13 +531,13 @@ static int flush_data_to_inode(struct block *b)
                int credits = 1;
                LAFS_BUG(!test_bit(B_Valid, &lai->iblock->b.flags),
                         &lai->iblock->b);
+               if (test_and_clear_bit(B_UnincCredit, &b->flags))
+                       credits++;
                if (!test_and_set_bit(B_Realloc, &lai->iblock->b.flags))
                        credits--;
                if (!test_and_set_bit(B_UnincCredit, &lai->iblock->b.flags))
-                       if (!test_and_clear_bit(B_ICredit,
-                                               &lai->iblock->b.flags))
-                               if (!test_and_clear_bit(B_UnincCredit, &b->flags))
-                                       LAFS_BUG(1, b); /* We needed an UnincCredit */
+                       credits--;
+               LAFS_BUG(credits < 0, b);
                lafs_space_return(fs, credits);
        } else {
                printk("Wasn't dirty or realloc: %s\n", strblk(b));
@@ -689,17 +689,20 @@ int lafs_cluster_allocate(struct block *b, int cnum)
                 */
                LAFS_BUG(!test_bit(B_Valid, &b2->flags), b2);
 
-               if (!test_and_set_bit(B_UnincCredit, &b2->flags))
-                       if (!test_and_clear_bit(B_ICredit, &b2->flags))
-                               credits--;
-
                if (cnum == 0) {
+                       if (!test_and_set_bit(B_UnincCredit, &b2->flags))
+                               if (!test_and_clear_bit(B_ICredit, &b2->flags))
+                                       credits--;
+
                        if (!test_bit(B_Dirty, &b2->flags))
                                /* need some credits... */
                                if (!test_and_set_bit(B_Credit, &b2->flags))
                                        credits--;
                        lafs_dirty_dblock(dblk(b2));
                } else {
+                       if (!test_and_set_bit(B_UnincCredit, &b2->flags))
+                               credits--;
+
                        if (!test_and_set_bit(B_Realloc, &b2->flags))
                                credits--;
                }
diff --git a/index.c b/index.c
index 5fa303782bff372dc962b11d0dff7bada430424b..32af941d37e04f9429f968a72823b106b055e97e 100644 (file)
--- a/index.c
+++ b/index.c
@@ -2203,11 +2203,14 @@ new_parent:
                        } else
                                lafs_dirty_iblock(p);
                }
-               if (!test_and_set_bit(B_UnincCredit, &p->b.flags))
-                       if (!test_and_clear_bit(B_ICredit, &p->b.flags))
-                               LAFS_BUG(1, &p->b); // ICredit should be set before
-               //we dirty a block.
-
+               if (!test_bit(B_UnincCredit, &p->b.flags)) {
+                       /* Ditto for UnincCredit */
+                       if (lafs_space_alloc(fs, 1, CleanSpace) == 1) {
+                               if (test_and_set_bit(B_UnincCredit, &p->b.flags))
+                                       lafs_space_return(fs, 1);
+                       } else
+                               lafs_dirty_iblock(p);
+               }
        }
 
        dprintk("Uninc same phase\n");