From 532016c4d9216e64ee3e9fc7cbd0ea3ce8602d54 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 2 Oct 2010 15:13:25 +1000 Subject: [PATCH] Combine dirty_iblock with setting Realloc on iblock. 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 --- block.c | 32 +++++++++++++++++++++++++++++++- index.c | 40 ++-------------------------------------- inode.c | 4 ++-- lafs.h | 2 +- modify.c | 4 ++-- roll.c | 2 +- 6 files changed, 39 insertions(+), 45 deletions(-) diff --git a/block.c b/block.c index 2ac721b..85758cf 100644 --- 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 32af941..ed4fe20 100644 --- 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 e2fcac2..679371d 100644 --- 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 30f9424..8dfae2b 100644 --- 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); diff --git a/modify.c b/modify.c index 4b74a65..2f9feb1 100644 --- 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 12d5bff..ba986cb 100644 --- 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... */ -- 2.39.5