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