if (dec && _putref_norefile(b)) {
- spin_lock(&lafs_hash_lock);
- /* PinPending disappears with the last non-lru reference,
- * (or possibly at other times).
- */
+ spin_lock(&lafs_hash_lock);
+ /* PinPending disappears with the last non-lru reference,
+ * (or possibly at other times).
+ */
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 ... */
- if (test_bit(B_Pinned, &b->flags) &&
- !test_bit(B_PinPending, &b->flags) &&
- !test_bit(B_Dirty, &b->flags) &&
- !test_bit(B_Realloc, &b->flags) &&
- (!test_bit(B_Index, &b->flags) ||
- (iblk(b)->uninc_table.pending_cnt == 0 &&
- iblk(b)->uninc == NULL &&
- iblk(b)->uninc_next == NULL &&
- atomic_read(&iblk(b)->pincnt[0]) == 0 &&
- atomic_read(&iblk(b)->pincnt[1]) == 0))
- ) {
- /* Don't need to be Pinned any more */
- lafs_checkpoint_lock(fs);
- if (test_and_clear_bit(B_Pinned, &b->flags)) {
- if (test_bit(B_Index, &b->flags) && !list_empty_careful(&b->lru)) {
- spin_lock(&fs->lock);
- list_del_init(&b->lru);
- spin_unlock(&fs->lock);
- }
- if (test_bit(B_InoIdx, &b->flags) &&
- b->inode->i_nlink)
- checkpin = b->inode;
- if (!test_bit(B_Root, &b->flags)) {
- struct block *nb;
- atomic_dec(&b->parent->pincnt[ph]);
- if (test_bit(B_InoIdx, &b->flags))
- nb = &LAFSI(b->inode)->dblock->b;
- else
- nb = &b->parent->b;
- if (next_parent != nb) {
- LAFS_BUG(next_parent, b);
- next_parent = nb;
- atomic_inc(&nb->refcnt);
+ ph = !!test_bit(B_Phase1, &b->flags);
+ /* See if we still need to be pinned */
+ /* FIXME need some locking here ... */
+ if (test_bit(B_Pinned, &b->flags) &&
+ !test_bit(B_PinPending, &b->flags) &&
+ !test_bit(B_Dirty, &b->flags) &&
+ !test_bit(B_Realloc, &b->flags) &&
+ (!test_bit(B_Index, &b->flags) ||
+ (iblk(b)->uninc_table.pending_cnt == 0 &&
+ iblk(b)->uninc == NULL &&
+ iblk(b)->uninc_next == NULL &&
+ atomic_read(&iblk(b)->pincnt[0]) == 0 &&
+ atomic_read(&iblk(b)->pincnt[1]) == 0))
+ ) {
+ /* Don't need to be Pinned any more */
+ lafs_checkpoint_lock(fs);
+ if (test_and_clear_bit(B_Pinned, &b->flags)) {
+ if (test_bit(B_Index, &b->flags) && !list_empty_careful(&b->lru)) {
+ spin_lock(&fs->lock);
+ list_del_init(&b->lru);
+ spin_unlock(&fs->lock);
+ }
+ if (test_bit(B_InoIdx, &b->flags) &&
+ b->inode->i_nlink)
+ checkpin = b->inode;
+ if (!test_bit(B_Root, &b->flags)) {
+ struct block *nb;
+ atomic_dec(&b->parent->pincnt[ph]);
+ if (test_bit(B_InoIdx, &b->flags))
+ nb = &LAFSI(b->inode)->dblock->b;
+ else
+ nb = &b->parent->b;
+ if (next_parent != nb) {
+ LAFS_BUG(next_parent, b);
+ next_parent = nb;
+ atomic_inc(&nb->refcnt);
+ }
}
}
+ lafs_checkpoint_unlock(fs);
}
- lafs_checkpoint_unlock(fs);
- }
- /* check the ->parent link */
+ /* check the ->parent link */
if (b->parent &&
!(b->flags & (
(1<<B_Pinned) |
}
freelist.freecnt++;
}
- /* last reference to a dblock with no page
- * requires special handling
- * The first block on a page must be freed,
- * the other blocks hold a reference on that
- * first block which must be dropped.
- */
- db = dblk(b);
- if (!test_bit(B_Index, &b->flags) &&
- !PagePrivate(db->page)) {
- int bits = (PAGE_SHIFT -
- b->inode->i_blkbits);
- int mask = (1<<bits) - 1;
- int bnum = b->fileaddr & mask;
-
- LAFS_BUG(next, next);
- if (bnum) {
- next = &db[-bnum].b;
- del_ref(next, "lafs_release_0",
- __FILE__, __LINE__);
- } else {
- free_me = 1;
- put_page(db->page);
- }
- }
- /* last reference to an iblock requires that we
- * deref the dblock
- */
- if (test_bit(B_InoIdx, &b->flags)) {
- spin_lock(&b->inode->i_data
- .private_lock);
- LAFS_BUG(LAFSI(b->inode)->iblock
- != iblk(b), b);
- LAFS_BUG(next, next);
- next = &LAFSI(b->inode)->dblock->b;
- del_ref(next, MKREF(iblock),
+ /* last reference to a dblock with no page
+ * requires special handling
+ * The first block on a page must be freed,
+ * the other blocks hold a reference on that
+ * first block which must be dropped.
+ */
+ db = dblk(b);
+ if (!test_bit(B_Index, &b->flags) &&
+ !PagePrivate(db->page)) {
+ int bits = (PAGE_SHIFT -
+ b->inode->i_blkbits);
+ int mask = (1<<bits) - 1;
+ int bnum = b->fileaddr & mask;
+
+ LAFS_BUG(next, next);
+ if (bnum) {
+ next = &db[-bnum].b;
+ del_ref(next, "lafs_release_0",
__FILE__, __LINE__);
- spin_unlock(&b->inode->i_data
- .private_lock);
+ } else {
+ free_me = 1;
+ put_page(db->page);
}
+ }
+ /* last reference to an iblock requires that we
+ * deref the dblock
+ */
+ if (test_bit(B_InoIdx, &b->flags)) {
+ spin_lock(&b->inode->i_data
+ .private_lock);
+ LAFS_BUG(LAFSI(b->inode)->iblock
+ != iblk(b), b);
+ LAFS_BUG(next, next);
+ next = &LAFSI(b->inode)->dblock->b;
+ del_ref(next, MKREF(iblock),
+ __FILE__, __LINE__);
+ spin_unlock(&b->inode->i_data
+ .private_lock);
+ }
- /* Free a delayed-release inode */
- if (!test_bit(B_Index, &b->flags) &&
- (myi = rcu_my_inode(dblk(b))) != NULL &&
- (!PagePrivate(dblk(b)->page) ||
- test_bit(I_Destroyed, &LAFSI(myi)->iflags))) {
- dblk(b)->my_inode = NULL;
- LAFSI(myi)->dblock = NULL;
- LAFSI(myi)->iblock = NULL;
- spin_unlock(&lafs_hash_lock);
- if (test_bit(I_Destroyed, &LAFSI(myi)->iflags))
- lafs_destroy_inode(myi);
- } else
- spin_unlock(&lafs_hash_lock);
+ /* Free a delayed-release inode */
+ if (!test_bit(B_Index, &b->flags) &&
+ (myi = rcu_my_inode(dblk(b))) != NULL &&
+ (!PagePrivate(dblk(b)->page) ||
+ test_bit(I_Destroyed, &LAFSI(myi)->iflags))) {
+ dblk(b)->my_inode = NULL;
+ LAFSI(myi)->dblock = NULL;
+ LAFSI(myi)->iblock = NULL;
+ spin_unlock(&lafs_hash_lock);
+ if (test_bit(I_Destroyed, &LAFSI(myi)->iflags))
+ lafs_destroy_inode(myi);
+ } else
+ spin_unlock(&lafs_hash_lock);
}
rcu_iput(myi);