Date: Sat, 11 Jul 2015 11:21:57 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285384 - head/sys/kern Message-ID: <201507111121.t6BBLvaF022898@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sat Jul 11 11:21:56 2015 New Revision: 285384 URL: https://svnweb.freebsd.org/changeset/base/285384 Log: Do not allow creation of the dirty buffers for the dead buffer objects, i.e. for buffer objects which vnode was reclaimed. Buffer cache cannot write such buffers. Return the error and discard the buffer immediately on write attempt. BO_DIRTY now always set during vnode reclamation, since it is used not only for the INVARIANTS checks. Do allow placement of the clean buffers on dead bufobj list, otherwise filesystems cannot use bufcache at all after the devvp reclaim. Reported and tested by: trasz Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Modified: head/sys/kern/vfs_bio.c head/sys/kern/vfs_subr.c Modified: head/sys/kern/vfs_bio.c ============================================================================== --- head/sys/kern/vfs_bio.c Sat Jul 11 04:55:01 2015 (r285383) +++ head/sys/kern/vfs_bio.c Sat Jul 11 11:21:56 2015 (r285384) @@ -1205,6 +1205,12 @@ bufwrite(struct buf *bp) int vp_md; CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags); + if ((bp->b_bufobj->bo_flag & BO_DEAD) != 0) { + bp->b_flags |= B_INVAL | B_RELBUF; + bp->b_flags &= ~B_CACHE; + brelse(bp); + return (ENXIO); + } if (bp->b_flags & B_INVAL) { brelse(bp); return (0); Modified: head/sys/kern/vfs_subr.c ============================================================================== --- head/sys/kern/vfs_subr.c Sat Jul 11 04:55:01 2015 (r285383) +++ head/sys/kern/vfs_subr.c Sat Jul 11 11:21:56 2015 (r285384) @@ -1584,7 +1584,8 @@ buf_vlist_add(struct buf *bp, struct buf int error; ASSERT_BO_WLOCKED(bo); - KASSERT((bo->bo_flag & BO_DEAD) == 0, ("dead bo %p", bo)); + KASSERT((xflags & BX_VNDIRTY) == 0 || (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; @@ -2841,7 +2842,7 @@ vgonel(struct vnode *vp) 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 && @@ -2850,7 +2851,6 @@ vgonel(struct vnode *vp) ("vp %p bufobj not invalidated", vp)); vp->v_bufobj.bo_flag |= BO_DEAD; BO_UNLOCK(&vp->v_bufobj); -#endif /* * Reclaim the vnode.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507111121.t6BBLvaF022898>