summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-12-20 15:46:15 +0000
committerkib <kib@FreeBSD.org>2014-12-20 15:46:15 +0000
commitfebae1567de111cf7b53f8fce80317a1c9d17b86 (patch)
treeab741b6f69732b96508b4979412c08a6b733e47a /sys/kern/vfs_subr.c
parentf419d174a96322ddec019d8b2521e821d2733502 (diff)
downloadFreeBSD-src-febae1567de111cf7b53f8fce80317a1c9d17b86.zip
FreeBSD-src-febae1567de111cf7b53f8fce80317a1c9d17b86.tar.gz
MFC r275743:
Put the buffer cleanup code after inactivation.
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 56e73c2..a7e8f63 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1567,6 +1567,7 @@ buf_vlist_add(struct buf *bp, struct bufobj *bo, b_xflags_t xflags)
int error;
ASSERT_BO_WLOCKED(bo);
+ KASSERT((bo->bo_flag & BO_DEAD) == 0, ("dead bo %p", bo));
KASSERT((bp->b_xflags & (BX_VNDIRTY|BX_VNCLEAN)) == 0,
("buf_vlist_add: Buf %p has existing xflags %d", bp, bp->b_xflags));
bp->b_xflags |= xflags;
@@ -2794,16 +2795,6 @@ vgonel(struct vnode *vp)
vfs_notify_upper(vp, VFS_NOTIFY_UPPER_RECLAIM);
/*
- * Clean out any buffers associated with the vnode.
- * If the flush fails, just toss the buffers.
- */
- mp = NULL;
- if (!TAILQ_EMPTY(&vp->v_bufobj.bo_dirty.bv_hd))
- (void) vn_start_secondary_write(vp, &mp, V_WAIT);
- if (vinvalbuf(vp, V_SAVE, 0, 0) != 0)
- vinvalbuf(vp, 0, 0, 0);
-
- /*
* If purging an active vnode, it must be closed and
* deactivated before being reclaimed.
*/
@@ -2817,6 +2808,29 @@ vgonel(struct vnode *vp)
}
if (vp->v_type == VSOCK)
vfs_unp_reclaim(vp);
+
+ /*
+ * Clean out any buffers associated with the vnode.
+ * If the flush fails, just toss the buffers.
+ */
+ mp = NULL;
+ if (!TAILQ_EMPTY(&vp->v_bufobj.bo_dirty.bv_hd))
+ (void) vn_start_secondary_write(vp, &mp, V_WAIT);
+ if (vinvalbuf(vp, V_SAVE, 0, 0) != 0) {
+ while (vinvalbuf(vp, 0, 0, 0) != 0)
+ ;
+ }
+#ifdef INVARIANTS
+ BO_LOCK(&vp->v_bufobj);
+ KASSERT(TAILQ_EMPTY(&vp->v_bufobj.bo_dirty.bv_hd) &&
+ vp->v_bufobj.bo_dirty.bv_cnt == 0 &&
+ TAILQ_EMPTY(&vp->v_bufobj.bo_clean.bv_hd) &&
+ vp->v_bufobj.bo_clean.bv_cnt == 0,
+ ("vp %p bufobj not invalidated", vp));
+ vp->v_bufobj.bo_flag |= BO_DEAD;
+ BO_UNLOCK(&vp->v_bufobj);
+#endif
+
/*
* Reclaim the vnode.
*/
OpenPOWER on IntegriCloud