/* Remove from the per-inode free list */
if (!test_bit(B_InoIdx, &blk->flags))
list_move(&blk->siblings, &parent->children);
- else
+ else {
+ /* Remove from ->free_index list */
list_del_init(&blk->siblings);
+ /* Having set ->parent, we take a ref on the dblock.
+ * The dblock must exist because we can only reach here from
+ * lafs_make_iblock which can only be called while holding a ref
+ * on the dblock
+ */
+ (void)getdref(LAFSI(blk->inode)->dblock, MKREF(pdblock));
+ }
}
spin_unlock(&as->private_lock);
}
del_ref(&b->parent->b, MKREF(child),
__FILE__, __LINE__);
b->parent = NULL;
+
+ if (test_bit(B_InoIdx, &b->flags)) {
+ /* While an InoIdx has a parent we hold a count on
+ * the dblock. Now we have dropped one, we must drop the
+ * other
+ */
+ struct datablock *db = LAFSI(b->inode)->dblock;
+ if (&db->b.parent->b != next_parent &&
+ &db->b != next_parent) {
+ printk("db = %s\n", strblk(&db->b));
+ printk("dp->p = %s\n", strblk(&db->b.parent->b));
+ printk("np = %s\n", strblk(next_parent));
+ printk("b = %s\n", strblk(b));
+ }
+ BUG_ON(&db->b.parent->b != next_parent && &db->b != next_parent);
+ if (atomic_dec_and_test(&next_parent->refcnt))
+ LAFS_BUG(1, b);
+ next_parent = &db->b;
+ del_ref(&db->b, MKREF(pdblock), __FILE__, __LINE__);
+ }
if (test_and_clear_bit(B_SegRef, &b->flags))
physref = b->physaddr;
spin_lock(&b->inode->i_data.private_lock);