Date: Sat, 14 Aug 2021 10:22:34 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 94cb19f46114 - stable/13 - null_vput_pair(): release use reference on dvp earlier Message-ID: <202108141022.17EAMY67029936@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=94cb19f46114950586fc363b518550c171849291 commit 94cb19f46114950586fc363b518550c171849291 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-03-07 21:08:38 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-08-14 10:21:59 +0000 null_vput_pair(): release use reference on dvp earlier (cherry picked from commit 16dea8341024b8ee8be619c27d4e63bd81bd9b6c) --- sys/fs/nullfs/null_vnops.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c index 6a6df55a0bef..e3a320a22bfa 100644 --- a/sys/fs/nullfs/null_vnops.c +++ b/sys/fs/nullfs/null_vnops.c @@ -1084,33 +1084,50 @@ null_vput_pair(struct vop_vput_pair_args *ap) vpp = ap->a_vpp; vp = NULL; lvp = NULL; - if (vpp != NULL) { + mp = NULL; + if (vpp != NULL) vp = *vpp; - if (vp != NULL) { + if (vp != NULL) { + lvp = NULLVPTOLOWERVP(vp); + vref(lvp); + if (!ap->a_unlock_vp) { vhold(vp); + vhold(lvp); mp = vp->v_mount; - lvp = NULLVPTOLOWERVP(vp); - if (ap->a_unlock_vp) - vref(lvp); + vfs_ref(mp); } } - res = VOP_VPUT_PAIR(ldvp, &lvp, ap->a_unlock_vp); + res = VOP_VPUT_PAIR(ldvp, lvp != NULL ? &lvp : NULL, true); + if (vp != NULL && ap->a_unlock_vp) + vrele(vp); + vrele(dvp); - /* lvp might have been unlocked and vp reclaimed */ - if (vp != NULL) { - if (!ap->a_unlock_vp && vp->v_vnlock != lvp->v_vnlock) { + if (vp == NULL || ap->a_unlock_vp) + return (res); + + /* lvp has been unlocked and vp might be reclaimed */ + VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY); + if (vp->v_data == NULL && vfs_busy(mp, MBF_NOWAIT) == 0) { + vput(vp); + vget(lvp, LK_EXCLUSIVE | LK_RETRY); + if (VN_IS_DOOMED(lvp)) { + vput(lvp); + vget(vp, LK_EXCLUSIVE | LK_RETRY); + } else { error = null_nodeget(mp, lvp, &vp1); if (error == 0) { - vput(vp); *vpp = vp1; + } else { + vget(vp, LK_EXCLUSIVE | LK_RETRY); } } - if (ap->a_unlock_vp) - vrele(vp); - vdrop(vp); + vfs_unbusy(mp); } - vrele(dvp); + vdrop(lvp); + vdrop(vp); + vfs_rel(mp); + return (res); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108141022.17EAMY67029936>