Date: Fri, 03 Jul 2026 00:27:15 +0000 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: 0cff90f802fd - stable/15 - VOP_VPUT_PAIR(): handle the case when dvp == vp Message-ID: <6a4701e3.26a00.6564c021@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=0cff90f802fd96589fc8209b1dc263fc0fa4ed04 commit 0cff90f802fd96589fc8209b1dc263fc0fa4ed04 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-06-24 18:21:49 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-07-03 00:24:33 +0000 VOP_VPUT_PAIR(): handle the case when dvp == vp (cherry picked from commit be9295deedd1e837ee3645583d07e1dffbe1ead0) --- sys/kern/vfs_default.c | 28 +++++++++++++++++++++++----- sys/sys/vnode.h | 1 + sys/ufs/ffs/ffs_vnops.c | 18 +++++++++++------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 76f63b187b65..1a4ce712a4d3 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -81,7 +81,6 @@ static int vop_stdfdatasync(struct vop_fdatasync_args *ap); static int vop_stdgetpages_async(struct vop_getpages_async_args *ap); static int vop_stdread_pgcache(struct vop_read_pgcache_args *ap); static int vop_stdstat(struct vop_stat_args *ap); -static int vop_stdvput_pair(struct vop_vput_pair_args *ap); static int vop_stdgetlowvnode(struct vop_getlowvnode_args *ap); /* @@ -1623,16 +1622,35 @@ vop_stdread_pgcache(struct vop_read_pgcache_args *ap __unused) return (EJUSTRETURN); } -static int +/* + * vput(dvp). If unlock_vp is true, vput(vp). Both dvp and vp must + * be locked. This is VOP because some filesystems might need to do + * additional actions on dvp when unlocked, and need to be aware of + * any other locked vnodes. Also as the consequence, vp might become + * doomed even if unlock_vp is false. + * + * Special case: dvp == vp. If unlock_vp is true, vunref(vp); + * vput(vp), else vunref(vp). In other words, the VOP assumes that + * there are two references on the vnode on entry, and releases only + * one of them in case of !unlock_vp. + */ +int vop_stdvput_pair(struct vop_vput_pair_args *ap) { struct vnode *dvp, *vp, **vpp; dvp = ap->a_dvp; vpp = ap->a_vpp; - vput(dvp); - if (vpp != NULL && ap->a_unlock_vp && (vp = *vpp) != NULL) - vput(vp); + vp = vpp != NULL ? *vpp : NULL; + if (dvp != vp) { + vput(dvp); + if (vp != NULL && ap->a_unlock_vp) + vput(vp); + } else { + vunref(vp); + if (ap->a_unlock_vp) + vput(vp); + } return (0); } diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 0e84127cbc32..4513a7a62140 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -916,6 +916,7 @@ int vop_stdpathconf(struct vop_pathconf_args *); int vop_stdpoll(struct vop_poll_args *); int vop_stdvptocnp(struct vop_vptocnp_args *ap); int vop_stdvptofh(struct vop_vptofh_args *ap); +int vop_stdvput_pair(struct vop_vput_pair_args *ap); int vop_stdunp_bind(struct vop_unp_bind_args *ap); int vop_stdunp_connect(struct vop_unp_connect_args *ap); int vop_stdunp_detach(struct vop_unp_detach_args *ap); diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index c7e2b3f4b8e6..ee495fe3888c 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -2006,16 +2006,14 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) vpp = ap->a_vpp; vp = vpp != NULL ? *vpp : NULL; - if ((dp->i_flag & (IN_NEEDSYNC | IN_ENDOFF)) == 0) { - vput(dvp); - if (vp != NULL && ap->a_unlock_vp) - vput(vp); - return (0); - } + if ((dp->i_flag & (IN_NEEDSYNC | IN_ENDOFF)) == 0) + return (vop_stdvput_pair(ap)); mp = dvp->v_mount; if (vp != NULL) { - if (ap->a_unlock_vp) { + if (dvp == vp) { + vunref(vp); + } else if (ap->a_unlock_vp) { vput(vp); } else { MPASS(vp->v_type != VNON); @@ -2055,6 +2053,12 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) } while (error == ERELOOKUP); } + if (vp == dvp) { + if (ap->a_unlock_vp) + vput(dvp); + return (0); + } + vput(dvp); if (vp == NULL || ap->a_unlock_vp)home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a4701e3.26a00.6564c021>
