]> git.neil.brown.name Git - LaFS.git/commitdiff
Don't use B_Credit to set B_Realloc
authorNeilBrown <neilb@suse.de>
Mon, 3 Aug 2009 01:28:37 +0000 (11:28 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 3 Aug 2009 01:28:37 +0000 (11:28 +1000)
We need to keep B_Credit to possibly set B_Dirty (if a B_Realloc
block gets dirtied while being written to the 'clean' cluster we
still need to write it to a normal cluster).
So Find B_Realloc from elsewhere, use lafs_space_alloc if needed,
or as a last result setting B_Dirty.

clean.c
cluster.c
index.c

diff --git a/clean.c b/clean.c
index 897d111e9b853a200625657bcdfc10a3afb5ec8b..0680682722185c2123c343349662ada387591b7f 100644 (file)
--- a/clean.c
+++ b/clean.c
@@ -154,20 +154,12 @@ static int mark_cleaning(struct block *b)
        if (err)
                return err;
        BUG_ON(!test_bit(B_Valid, &b->flags));
-       if (!test_and_set_bit(B_Realloc, &b->flags)) {
-               if (!test_and_clear_bit(B_Credit, &b->flags)) {
-                       if (!test_bit(B_Dirty, &b->flags))
-                               BUG();
-                       else {
-                               /* Set Realloc but couldn't recover credit
-                                * because we raced with dirty_dblock.
-                                * so just clear B_Realloc and let it
-                                * get flushed as dirty.
-                                */
-                               clear_bit(B_Realloc, &b->flags);
-                       }
-               }
-       }
+       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;
        lafs_pin_block(b);
        if (test_bit(B_Dirty, &b->flags)) {
                /* If dirty, then now that it is pinned,
index 09220bdf370df808cfbc9627b87f42eb4421da0f..61ab257382e498d5ae49261d1ae2e2dc4246fc0d 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -459,15 +459,13 @@ static int flush_data_to_inode(struct block *b)
        } else if (test_and_clear_bit(B_Realloc, &b->flags)) {
                int credits = 1;
                BUG_ON(!test_bit(B_Valid, &lai->iblock->b.flags));
-               if (!test_and_set_bit(B_Realloc, &lai->iblock->b.flags)) {
-                       if (!test_and_clear_bit(B_Credit,
-                                               &lai->iblock->b.flags))
+               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))
-                               credits--;
+                               if (!test_and_clear_bit(B_UnincCredit, &b->flags))
+                                       BUG(); /* We needed an UnincCredit */
                lafs_space_return(fs, credits);
        } else {
                printk("Wasn't dirty or realloc: %s\n", strblk(b));
@@ -649,33 +647,29 @@ unsigned long long lafs_cluster_allocate(struct block *b, int cnum)
                 */
                BUG_ON(!test_bit(B_Valid, &b2->flags));
 
-               if (!test_bit(B_Dirty, &b2->flags) &&
-                   !test_bit(B_Realloc, &b2->flags))
-                       /* need some credits... */
-                       if (!test_and_set_bit(B_Credit, &b2->flags))
-                               credits--;
-               if (!test_bit(B_UnincCredit, &b2->flags))
-                       if (!test_and_set_bit(B_ICredit, &b2->flags))
-                               credits--;
-               BUG_ON(credits < 0);
-               lafs_space_return(fs, credits);
+               if (cnum == 0) {
+                       if (!test_bit(B_Dirty, &b2->flags))
+                               /* need some credits... */
+                               if (!test_and_set_bit(B_Credit, &b2->flags))
+                                       credits--;
+                       if (!test_bit(B_UnincCredit, &b2->flags))
+                               if (!test_and_set_bit(B_ICredit, &b2->flags))
+                                       credits--;
 
-               if (cnum == 0)
                        __lafs_dirty_dblock(dblk(b2));
-               else {
+               else {
                        /* FIXME this code should be in clean.c
-                        * it is copied from lafs_dirty_dblock() */
+                        * it is copied from __lafs_dirty_dblock() */
                        BUG_ON(!test_bit(B_Valid, &b2->flags));
-                       if (!test_and_set_bit(B_Realloc, &b2->flags)) {
-                               if (!test_and_clear_bit(B_Credit, &b2->flags))
-                                       BUG(); // Credit should have been set.
-                       }
+                       if (!test_and_set_bit(B_Realloc, &b2->flags))
+                               credits--;
 
                        if (!test_and_set_bit(B_UnincCredit, &b2->flags))
                                if (!test_and_clear_bit(B_ICredit, &b2->flags))
-                                       BUG(); // ICredit should be set 
-                                               //before we dirty a block.
+                                       credits--;
                }
+               BUG_ON(credits < 0);
+               lafs_space_return(fs, credits);
                /* make sure 'dirty' status is registered */
                lafs_refile(b2, 0);
                lafs_iounlock_block(b, 0);
diff --git a/index.c b/index.c
index 8752248da1367cc70e3c3bb4080f29b15414f337..361ff55e2ac92407a0d0901bacb48cf5a31049d9 100644 (file)
--- a/index.c
+++ b/index.c
@@ -1903,11 +1903,17 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
                        printk("blk is %s\n", strblk(blk));
                }
                BUG_ON(!test_bit(B_Valid, &p->b.flags));
-               if (!test_and_set_bit(B_Realloc, &p->b.flags)) {
-                       if (!test_and_clear_bit(B_Credit, &p->b.flags)) {
-                               printk("not realloc %s\n", strblk(&p->b));
-                               printk(" for %s\n", strblk(blk));
-                               BUG();
+               if (!test_bit(B_Realloc, &p->b.flags)) {
+                       /* I cannot use B_Credit to fill B_Realloc as that
+                        * might still be needed for B_Dirty.
+                        * So if we cannot allocated a new credit,
+                        * just set the block as 'dirty' now.
+                        */
+                       if (lafs_space_alloc(fs, 1, CleanSpace) == 1) {
+                               if (test_and_set_bit(B_Realloc, &p->b.flags))
+                                       lafs_space_return(fs, 1);
+                               else
+                                       lafs_dirty_iblock(p);
                        }
                }
                if (!test_and_set_bit(B_UnincCredit, &p->b.flags))