From owner-dev-commits-src-branches@freebsd.org Wed Feb 24 07:59:04 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 80A0C553D38; Wed, 24 Feb 2021 07:59:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DlpGG6JRzz4ZXq; Wed, 24 Feb 2021 07:59:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8235B28D8E; Wed, 24 Feb 2021 07:58:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 11O7wwLV046712; Wed, 24 Feb 2021 07:58:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11O7wwgW046711; Wed, 24 Feb 2021 07:58:58 GMT (envelope-from git) Date: Wed, 24 Feb 2021 07:58:58 GMT Message-Id: <202102240758.11O7wwgW046711@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: bbf612a1af56 - stable/13 - Stop ignoring ERELOOKUP from VOP_INACTIVE() MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: bbf612a1af56cc4307650c5f38ec63deeefdbe32 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Feb 2021 07:59:04 -0000 The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=bbf612a1af56cc4307650c5f38ec63deeefdbe32 commit bbf612a1af56cc4307650c5f38ec63deeefdbe32 Author: Konstantin Belousov AuthorDate: 2021-01-30 19:17:29 +0000 Commit: Konstantin Belousov CommitDate: 2021-02-24 07:46:59 +0000 Stop ignoring ERELOOKUP from VOP_INACTIVE() (cherry picked from commit b59a8e63d6bf9092419b7a421c655d0ae2099662) --- sys/kern/vfs_subr.c | 47 ++++++++++++++++++++++++++++++++-------------- sys/sys/vnode.h | 3 ++- sys/ufs/ffs/ffs_snapshot.c | 8 +++++++- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 047e4c54f0c5..04cd0e0175f9 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3159,9 +3159,21 @@ vput_final(struct vnode *vp, enum vput_op func) break; } if (error == 0) { - vinactive(vp); - if (want_unlock) - VOP_UNLOCK(vp); + if (func == VUNREF) { + VNASSERT((vp->v_vflag & VV_UNREF) == 0, vp, + ("recursive vunref")); + vp->v_vflag |= VV_UNREF; + } + for (;;) { + error = vinactive(vp); + if (want_unlock) + VOP_UNLOCK(vp); + if (error != ERELOOKUP || !want_unlock) + break; + VOP_LOCK(vp, LK_EXCLUSIVE); + } + if (func == VUNREF) + vp->v_vflag &= ~VV_UNREF; vdropl(vp); } else { vdefer_inactive(vp); @@ -3546,10 +3558,11 @@ vdropl(struct vnode *vp) * Call VOP_INACTIVE on the vnode and manage the DOINGINACT and OWEINACT * flags. DOINGINACT prevents us from recursing in calls to vinactive. */ -static void +static int vinactivef(struct vnode *vp) { struct vm_object *obj; + int error; ASSERT_VOP_ELOCKED(vp, "vinactive"); ASSERT_VI_LOCKED(vp, "vinactive"); @@ -3575,14 +3588,15 @@ vinactivef(struct vnode *vp) vm_object_page_clean(obj, 0, 0, 0); VM_OBJECT_WUNLOCK(obj); } - VOP_INACTIVE(vp); + error = VOP_INACTIVE(vp); VI_LOCK(vp); VNASSERT(vp->v_iflag & VI_DOINGINACT, vp, ("vinactive: lost VI_DOINGINACT")); vp->v_iflag &= ~VI_DOINGINACT; + return (error); } -void +int vinactive(struct vnode *vp) { @@ -3591,14 +3605,14 @@ vinactive(struct vnode *vp) CTR2(KTR_VFS, "%s: vp %p", __func__, vp); if ((vp->v_iflag & VI_OWEINACT) == 0) - return; + return (0); if (vp->v_iflag & VI_DOINGINACT) - return; + return (0); if (vp->v_usecount > 0) { vp->v_iflag &= ~VI_OWEINACT; - return; + return (0); } - vinactivef(vp); + return (vinactivef(vp)); } /* @@ -3911,10 +3925,15 @@ vgonel(struct vnode *vp) */ if (active) VOP_CLOSE(vp, FNONBLOCK, NOCRED, td); - if ((oweinact || active) && !doinginact) { - VI_LOCK(vp); - vinactivef(vp); - VI_UNLOCK(vp); + if (!doinginact) { + do { + if (oweinact || active) { + VI_LOCK(vp); + vinactivef(vp); + oweinact = (vp->v_iflag & VI_OWEINACT) != 0; + VI_UNLOCK(vp); + } + } while (oweinact); } if (vp->v_type == VSOCK) vfs_unp_reclaim(vp); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 78fbec1bd0ba..639a16881e09 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -269,6 +269,7 @@ struct xvnode { #define VV_MD 0x0800 /* vnode backs the md device */ #define VV_FORCEINSMQ 0x1000 /* force the insmntque to succeed */ #define VV_READLINK 0x2000 /* fdescfs linux vnode */ +#define VV_UNREF 0x4000 /* vunref, do not drop lock in inactive() */ #define VMP_LAZYLIST 0x0001 /* Vnode is on mnt's lazy list */ @@ -710,7 +711,7 @@ void vgone(struct vnode *vp); void vhold(struct vnode *); void vholdnz(struct vnode *); bool vhold_smr(struct vnode *); -void vinactive(struct vnode *vp); +int vinactive(struct vnode *vp); int vinvalbuf(struct vnode *vp, int save, int slpflag, int slptimeo); int vtruncbuf(struct vnode *vp, off_t length, int blksize); void v_inval_buf_range(struct vnode *vp, daddr_t startlbn, daddr_t endlbn, diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index b5daec14decf..72c8061917d8 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -2595,6 +2595,7 @@ process_deferred_inactive(struct mount *mp) continue; } vholdl(vp); +retry_vnode: error = vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK); if (error != 0) { vdrop(vp); @@ -2609,7 +2610,12 @@ process_deferred_inactive(struct mount *mp) UFS_INODE_SET_FLAG(ip, IN_MODIFIED); } VI_LOCK(vp); - vinactive(vp); + error = vinactive(vp); + if (error == ERELOOKUP && vp->v_usecount == 0) { + VI_UNLOCK(vp); + VOP_UNLOCK(vp); + goto retry_vnode; + } VI_UNLOCK(vp); VOP_UNLOCK(vp); vdrop(vp);