From b59ea7302971e64e609846bec32f8f055897d9bc Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 20 Aug 2017 10:07:45 +0000 Subject: [PATCH] Allow vinvalbuf() to operate with the shared vnode lock. This mode allows other clean buffers to arrive while we flush the buf lists for the vnode, which is fine for the targeted use. We only need that all buffers existed at the time of the function start were flushed. In fact, only one assert has to be relaxed. In collaboration with: pho Reviewed by: rmacklem Sponsored by: The FreeBSD Foundation MFC after: 2 weeks X-Differential revision: https://reviews.freebsd.org/D12083 --- sys/kern/vfs_subr.c | 8 ++++++-- sys/sys/vnode.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index afe4553cdc0..080e4238b15 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1698,9 +1698,13 @@ bufobj_invalbuf(struct bufobj *bo, int flags, int slpflag, int slptimeo) #ifdef INVARIANTS BO_LOCK(bo); - if ((flags & (V_ALT | V_NORMAL | V_CLEANONLY | V_VMIO)) == 0 && - (bo->bo_dirty.bv_cnt > 0 || bo->bo_clean.bv_cnt > 0)) + if ((flags & (V_ALT | V_NORMAL | V_CLEANONLY | V_VMIO | + V_ALLOWCLEAN)) == 0 && (bo->bo_dirty.bv_cnt > 0 || + bo->bo_clean.bv_cnt > 0)) panic("vinvalbuf: flush failed"); + if ((flags & (V_ALT | V_NORMAL | V_CLEANONLY | V_VMIO)) == 0 && + bo->bo_dirty.bv_cnt > 0) + panic("vinvalbuf: flush dirty failed"); BO_UNLOCK(bo); #endif return (0); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 3865ed354a7..8a92f2b9671 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -399,6 +399,7 @@ extern int vttoif_tab[]; #define V_NORMAL 0x0004 /* vinvalbuf: invalidate only regular bufs */ #define V_CLEANONLY 0x0008 /* vinvalbuf: invalidate only clean bufs */ #define V_VMIO 0x0010 /* vinvalbuf: called during pageout */ +#define V_ALLOWCLEAN 0x0020 /* vinvalbuf: allow clean buffers after flush */ #define REVOKEALL 0x0001 /* vop_revoke: revoke all aliases */ #define V_WAIT 0x0001 /* vn_start_write: sleep for suspend */ #define V_NOWAIT 0x0002 /* vn_start_write: don't sleep for suspend */