]> git.neil.brown.name Git - LaFS.git/commitdiff
Combine dirty_iblock with setting Realloc on iblock.
authorNeilBrown <neilb@suse.de>
Sat, 2 Oct 2010 05:13:25 +0000 (15:13 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 10 Oct 2010 23:33:55 +0000 (10:33 +1100)
This makes it easier to do the right thing on iblocks that
we have just split ... not that we would expect that when cleaning,
but lots of things are possible, and elegant code is good.

Signed-off-by: NeilBrown <neilb@suse.de>
block.c
index.c
inode.c
lafs.h
modify.c
roll.c

diff --git a/block.c b/block.c
index 2ac721bfc794176c4a8da722fe6c8c0f953e7fd5..85758cf55e97199a5c369aa9266d2ffc8db8e91f 100644 (file)
--- a/block.c
+++ b/block.c
@@ -646,7 +646,7 @@ lafs_erase_dblock_async(struct datablock *b)
 }
 
 void
-lafs_dirty_iblock(struct indexblock *b)
+lafs_dirty_iblock(struct indexblock *b, int want_realloc)
 {
        /* Note, only need to set the phase if locked.
         * Then no-one may change it while in phase transition.
@@ -655,6 +655,36 @@ lafs_dirty_iblock(struct indexblock *b)
         */
 
        LAFS_BUG(!test_bit(B_Pinned, &b->b.flags), &b->b);
+       LAFS_BUG(!test_bit(B_Valid, &b->b.flags), &b->b);
+
+       if (want_realloc) {
+               /* Try to make for Realloc instead.  If we cannot get the
+                * credits, fall back on Dirty
+                */
+               struct fs *fs = fs_from_inode(b->b.inode);
+               if (!test_bit(B_Realloc, &b->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, &b->b.flags))
+                                       lafs_space_return(fs, 1);
+                       } else
+                               goto dirty;
+               }
+               if (!test_bit(B_UnincCredit, &b->b.flags)) {
+                       /* Ditto for UnincCredit */
+                       if (lafs_space_alloc(fs, 1, CleanSpace) == 1) {
+                               if (test_and_set_bit(B_UnincCredit, &b->b.flags))
+                                       lafs_space_return(fs, 1);
+                       } else
+                               goto dirty;
+               }
+               return;
+       }
+dirty:
        if (!test_and_set_bit(B_Dirty, &b->b.flags)) {
                if (!test_and_clear_bit(B_Credit, &b->b.flags)) {
                        printk(KERN_ERR "Why have I no credits?\n");
diff --git a/index.c b/index.c
index 32af941d37e04f9429f968a72823b106b055e97e..ed4fe20546ae35f7010ec6c8f4ada92a14c35d00 100644 (file)
--- a/index.c
+++ b/index.c
@@ -649,7 +649,7 @@ void lafs_phase_flip(struct fs *fs, struct indexblock *ib)
        lafs_iounlock_block(&ib->b);
 
        if (ulist)
-               lafs_dirty_iblock(ib);
+               lafs_dirty_iblock(ib, 0);
        while (ulist) {
                struct block *b2 = ulist;
                ulist = b2->chain;
@@ -2176,43 +2176,7 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
        }
 
 new_parent:
-       if (test_bit(B_Dirty, &blk->flags) || phys == 0) {
-               if (!test_bit(B_Dirty, &p->b.flags)
-                   && !test_bit(B_Credit, &p->b.flags)) {
-                       printk("Oh dear: %s\n", strblk(blk));
-                       printk(".......: %s\n", strblk(&p->b));
-               }
-               lafs_dirty_iblock(p);
-       } else {
-               if (!test_bit(B_Valid, &p->b.flags)) {
-                       printk("Not valid in lafs_allocated_block: %s\n",
-                              strblk(&p->b));
-                       printk("blk is %s\n", strblk(blk));
-                       BUG();
-               }
-               LAFS_BUG(!test_bit(B_Valid, &p->b.flags), &p->b);
-               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_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);
-               }
-       }
-
+       lafs_dirty_iblock(p, !(test_bit(B_Dirty, &blk->flags) || phys == 0));
        dprintk("Uninc same phase\n");
 
        BUG_ON(!test_bit(B_Pinned, &blk->parent->b.flags));
diff --git a/inode.c b/inode.c
index e2fcac2b924be2b6626e276fafe4764325fafe89..679371d2871faf489c5b27e7766cf49915d8eb8f 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -1016,7 +1016,7 @@ int lafs_inode_handle_orphan(struct datablock *b)
                 */
                if (ib->uninc_table.pending_cnt == 0 &&
                    ib->uninc == NULL) {
-                       lafs_dirty_iblock(ib);
+                       lafs_dirty_iblock(ib, 0);
                        /* FIXME this just removes 8 blocks at a time,
                         * which is not enough
                         */
@@ -1042,7 +1042,7 @@ int lafs_inode_handle_orphan(struct datablock *b)
            ib->b.physaddr != 0) {
                lafs_walk_leaf_index(ib, prune, ib);
                lafs_clear_index(ib);
-               lafs_dirty_iblock(ib);
+               lafs_dirty_iblock(ib, 0);
        }
        if (test_bit(B_Dirty, &ib->b.flags))
                lafs_incorporate(fs, ib);
diff --git a/lafs.h b/lafs.h
index 30f9424d3eb14bdd070284b0b045058c291935d1..8dfae2bca4e73357e7ea1bdb70a6c1280a47b5a8 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -651,7 +651,7 @@ int lafs_reserve_block(struct block *b, int alloc_type);
 void lafs_dirty_dblock(struct datablock *b);
 void lafs_erase_dblock(struct datablock *b);
 int lafs_erase_dblock_async(struct datablock *b);
-void lafs_dirty_iblock(struct indexblock *b);
+void lafs_dirty_iblock(struct indexblock *b, int want_realloc);
 void block_drop_addr(struct fs *fs, struct inode *ino, u32 addr);
 void lafs_flush(struct datablock *b);
 
index 4b74a650de24de6b7d196dde066f1ef5ed0f614c..2f9feb1117cd735440751cc26ff39f301d271b36 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1818,7 +1818,7 @@ retry:
                        uit.credits--;
                }
 
-               lafs_dirty_iblock(new); // or Realloc?? FIXME
+               lafs_dirty_iblock(new, !test_bit(B_Dirty, &ib->b.flags));
                lafs_iounlock_block(&new->b);
                temp_credits = uit.credits;
                putiref(new, MKREF(inc));
@@ -1834,7 +1834,7 @@ retry:
                        uit.credits--;
                }
 
-               lafs_dirty_iblock(new); // or Realloc?? FIXME
+               lafs_dirty_iblock(new, !test_bit(B_Dirty, &ib->b.flags));
                dprintk("Just Grew %s\n", strblk(&new->b));
                dprintk("     from %s\n", strblk(&ib->b));
                lafs_iounlock_block(&new->b);
diff --git a/roll.c b/roll.c
index 12d5bffaf17fcca9608a036a14453987150b9bce..ba986cb8b8e600a0e440825054121a39c9048f4e 100644 (file)
--- a/roll.c
+++ b/roll.c
@@ -350,7 +350,7 @@ roll_block(struct fs *fs, int fsnum, int inum, int trunc, int flg,
                lafs_summary_update(fs, blk->b.inode, blk->b.physaddr, baddr,
                                    0, fs->phase, 1);
                blk->b.physaddr = baddr;
-               lafs_dirty_iblock(blk->b.parent);
+               lafs_dirty_iblock(blk->b.parent, 0);
                /* FIXME maybe set Writeback and unlock */
                if (lafs_add_block_address(fs, &blk->b) == 0)
                        /* FIXME if the table becomes full, we have a problem... */