static int mark_cleaning(struct block *b)
{
int err;
+ int credits;
if (test_bit(B_Realloc, &b->flags))
/* As cleaning is single threaded,
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,
* 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);
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));
*/
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--;
}
} 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");