BUG_ON(li->dblock == NULL);
BUG_ON(atomic_read(&li->dblock->b.refcnt) == 0);
+ retry:
if (next)
*next = 0xFFFFFFFF;
dprintk("WARN %llu != %llu\n",
ib2->b.physaddr, iphys);
}
+
+ if (test_bit(B_PhysValid, &ib2->b.flags) &&
+ ib2->b.physaddr == 0) {
+ /* this block has been invalidated, we must be
+ * racing with some sort of truncate.
+ * try again from the top.
+ * FIXME should wait for something here.
+ */
+ putiref(ib2, REF);
+ lafs_iounlock_block(&ib->b);
+ putiref(ib, REF);
+ goto retry;
+ }
#ifdef FIXME
if (!(ib2->b.flags & B_Linked)) {
struct block *b2 = peer_find(fs, inode->filesys,
temp_credits = 0;
lafs_space_return(fs, uit.credits);
- /* If this index block is now empty, we clear
- * B_Valid so that it doesn't get written out,
- * but rather gets allocated as '0'.
+ /* If this internal index block is now empty, we either
+ * invalidate it or merge it with the first dependent block.
+ * If it is the first index block in it's parent we need to
+ * adjust the start of parent and possibly other ancestors,
+ * and incorporate them immediately.
*/
if (test_bit(B_Valid, &ib->b.flags) &&
- list_empty(&ib->children)) {
- if (ib->depth == 1 &&
- lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF)
- clear_bit(B_Valid, &ib->b.flags);
- if (ib->depth > 1 &&
- lafs_index_empty(ib))
- clear_bit(B_Valid, &ib->b.flags);
+ list_empty(&ib->children) &&
+ ib->depth > 1 &&
+ lafs_index_empty(ib)) {
+ struct block *nxt = list_entry(ib->b.siblings.next,
+ struct block, siblings);
+ if (ib->b.siblings.next != &ib->b.parent->children &&
+ test_bit(B_PrimaryRef, &nxt->flags)) {
+ /* */
+ }
}
}