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,
} 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));
*/
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);
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))