} else
blk = getref(&b->b, MKREF(pindb));
- LAFS_BUG(!test_phase_locked(fs), &b->b);
- lafs_phase_wait(blk);
+ if (LAFSI(b->b.inode)->type != TypeSegmentMap) {
+ /* FIXME test is a hack until we get a better
+ * phase wait. TypeSegmentMap does it's own
+ * dirty management so doesn't need this.
+ */
+ LAFS_BUG(!test_phase_locked(fs), &b->b);
+ lafs_phase_wait(blk);
+ }
set_bit(B_PinPending, &b->b.flags);
err = lafs_reserve_block(blk, alloc_type);
struct inode *ino;
LAFS_BUG(b->parent == NULL && !test_bit(B_Root, &b->flags), b);
- if (!test_bit(B_Realloc, &b->flags))
+ if (!test_bit(B_Realloc, &b->flags) &&
+ LAFSI(b->inode)->type != TypeSegmentMap)
LAFS_BUG(!test_phase_locked(fs), b);
ino = b->inode;
*/
onlru = 1;
+ /* PinPending disappears with the last non-lru reference,
+ * (or possibly at other times).
+ */
+ if (atomic_read(&b->refcnt) == dec + onlru)
+ clear_bit(B_PinPending, &b->flags);
+
ph = !!test_bit(B_Phase1, &b->flags);
/* See if we still need to be pinned */
/* FIXME need some locking here ... */
continue;
}
- err = lafs_prealloc(&ss->ssblk->b, AccountSpace);
+ err = lafs_pin_dblock(ss->ssblk, AccountSpace);
if (err) {
ss_put(ss, fs);
putref(b, MKREF(segref));
ss = segsum_byaddr(fs, newaddr, ssnum);
seg_inc(fs, ss, 1, fs->qphase == phase);
- /* FIXME this doesn't belong here, does it ?*/
- lafs_checkpoint_lock(fs);
- (void)lafs_reserve_block(&ss->ssblk->b, AccountSpace);
- lafs_checkpoint_unlock(fs);
if (!moveref)
ss_put(ss, fs);
}
* to the two blocks !! */
LAFS_BUG(1, &db->b);
lafs_checkpoint_lock(fs);
- (void)lafs_reserve_block(&ssum->ssblk->b, AccountSpace);
+ (void)lafs_pin_dblock(ssum->ssblk, AccountSpace);
if (ssnum == 0)
- (void)lafs_reserve_block(&ssum->youthblk->b, AccountSpace);
+ (void)lafs_pin_dblock(ssum->youthblk, AccountSpace);
lafs_checkpoint_unlock(fs);
/* These aren't in the table any more - the segsum holds
* the necessary reference */
- 1),
NULL, GFP_KERNEL,
MKREF(youth));
- // FIXME we need to hold a ref on all youth blocks for
- // known free segments....
+ /* As we hold a ref on youth block for anything in the
+ * table, and that block was loaded at the time, it must
+ * still be valid.
+ */
BUG_ON(!test_bit(B_Valid, &db->b.flags));
goto again;
}