From nobody Fri Jul 4 15:23:49 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bYcqB1FJZz61LkZ; Fri, 04 Jul 2025 15:23:50 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bYcq96Fjyz3KLs; Fri, 04 Jul 2025 15:23:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751642629; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=mNh5IJdrGb/mceIMmKvHLA4uFgRezxHGUYldyiIvpFg=; b=GfXUO8B9km7ErKa7o2SI+kPhyYgUeGVO/L4+zk1tDWl14FNwwY1+JPabOLWxz8VxtcBVHt t+9KGiTCTXUjEFLCVo4C/Vs1h20dQsKVk0e/p3DkGcaCZ3mTBfOoUKWCX7VhFMzszELJW0 Yk3IQxhcNlH+L3V0zOH2rgH0/V7CaDXLgSBW1UpOs2aaubff2UKajlYTmmJcki9nQGr/x3 VLvABdPbEaFaDDYRb4xqOLeTz14cHkz9YyX8IgQQhmtbVGrOMo/gphiO99Xw5L6JYYcv1Q dti31iuW1IXCI/rr1ut970QwFEp7OVzelpOd3DpoMdMh4HkKS+8Tnh8fouSBBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751642629; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=mNh5IJdrGb/mceIMmKvHLA4uFgRezxHGUYldyiIvpFg=; b=IK25G7L5i+hL/ZRsRKc8og7ygYbaipdalEgW9UX10SqE4wUZBuqMQxttUR0Fy4WDxBSDYG 2mzUKl3i6FdV6lFMZUhWSIlEF9Ja9o6QpVGGaRCPzgCWPVEXuXct+QwVScWjPMqRGjcXu0 mu4ntc8+d/iXCK1vzBylvVbPYJP+Nc0Uegl5v0zNR9Kpkpr8F8miOXDyYMc871eHGHURrd k043q2rGPlpmuhPiDhPnbBuBHW4mthjf1JTadfzi/9xoIOIGQCB4Wcf1+sv2qUqSMgV6F8 veGjfZpY1n+feztVCBpykGRpVcT6wrti22P/Io9piBUq/hdJukWps2kmchQhNw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1751642629; a=rsa-sha256; cv=none; b=fcWGJC6sjIHHwXueCFd2DVUPu311XoWcrm/JhsGQINIuYtmGKF8fY4tcjeKcdK//fJGztN BOf31UvRIkwAlkOIK+NGop7FlSqL0JsMFYRpc4YxpRi+WDNFmBhv6G0krUotF4qlUQ504j jmFWDqy9ODTttbKrwqMj9sA9OAjI+QS7h4nq1DLz+10IOGe6f4wU6fNnwYmV9Q2z4n8uPq 6KV0FL54zPGt0EHdNuN2MktOkQlP3tIBx4WkyladoI4SvfEmRJjlP3pKLRFOYlniZbmc7H 27ybStWqR0gcSPFlfxFl1cbkVhafTNJzNApZ+RkjoPQ7iQd5A8CeXDPGpE31PA== 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 4bYcq957qVzw5x; Fri, 04 Jul 2025 15:23:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 564FNnp6030007; Fri, 4 Jul 2025 15:23:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 564FNnnF030004; Fri, 4 Jul 2025 15:23:49 GMT (envelope-from git) Date: Fri, 4 Jul 2025 15:23:49 GMT Message-Id: <202507041523.564FNnnF030004@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: ef6ea91593eb - main - VOP_RENAME: add mp-global lock List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org 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/main X-Git-Reftype: branch X-Git-Commit: ef6ea91593ebff73e2fc201efd9f848b71c5a125 Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ef6ea91593ebff73e2fc201efd9f848b71c5a125 commit ef6ea91593ebff73e2fc201efd9f848b71c5a125 Author: Konstantin Belousov AuthorDate: 2025-06-02 07:05:06 +0000 Commit: Konstantin Belousov CommitDate: 2025-07-04 15:23:42 +0000 VOP_RENAME: add mp-global lock It is before all vnode locks, but after vn_start_write(). The lock prevents parallel rename operations on the same mount point, which should in (near future) simplify a lot of code in VFS/fs that otherwise need to code with either the changing hierarchy, or with the lock order for vnodes due to changed hierarchy. On renames, the lock is taken on the lowest stacked filesystem. Otherwise rename could still occur in parallel, by performing one of op on the lower fs. Proposed by: mjg (long time ago) Reviewed by: markj, olce Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D50648 --- sys/kern/vfs_mount.c | 2 ++ sys/kern/vfs_subr.c | 7 +++++++ sys/kern/vfs_syscalls.c | 20 +++++++++++++++++++- sys/sys/mount.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index cb18468d28bc..8e64a7fe966b 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -156,6 +156,7 @@ mount_init(void *mem, int size, int flags) mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF); mtx_init(&mp->mnt_listmtx, "struct mount vlist mtx", NULL, MTX_DEF); lockinit(&mp->mnt_explock, PVFS, "explock", 0, 0); + lockinit(&mp->mnt_renamelock, PVFS, "rename", 0, 0); mp->mnt_pcpu = uma_zalloc_pcpu(pcpu_zone_16, M_WAITOK | M_ZERO); mp->mnt_ref = 0; mp->mnt_vfs_ops = 1; @@ -170,6 +171,7 @@ mount_fini(void *mem, int size) mp = (struct mount *)mem; uma_zfree_pcpu(pcpu_zone_16, mp->mnt_pcpu); + lockdestroy(&mp->mnt_renamelock); lockdestroy(&mp->mnt_explock); mtx_destroy(&mp->mnt_listmtx); mtx_destroy(&mp->mnt_mtx); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 877931721da4..918b256e6c59 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -5853,6 +5853,8 @@ vop_rename_pre(void *ap) struct vop_rename_args *a = ap; #ifdef DEBUG_VFS_LOCKS + struct mount *tmp; + if (a->a_tvp) ASSERT_VI_UNLOCKED(a->a_tvp, "VOP_RENAME"); ASSERT_VI_UNLOCKED(a->a_tdvp, "VOP_RENAME"); @@ -5870,6 +5872,11 @@ vop_rename_pre(void *ap) if (a->a_tvp) ASSERT_VOP_LOCKED(a->a_tvp, "vop_rename: tvp not locked"); ASSERT_VOP_LOCKED(a->a_tdvp, "vop_rename: tdvp not locked"); + + tmp = NULL; + VOP_GETWRITEMOUNT(a->a_tdvp, &tmp); + lockmgr_assert(&tmp->mnt_renamelock, KA_XLOCKED); + vfs_rel(tmp); #endif /* * It may be tempting to add vn_seqc_write_begin/end calls here and diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index c236f241bf20..d880733cbfe7 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3766,7 +3766,7 @@ int kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, const char *new, enum uio_seg pathseg) { - struct mount *mp = NULL; + struct mount *mp, *tmp; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; uint64_t tondflags; @@ -3774,6 +3774,7 @@ kern_renameat(struct thread *td, int oldfd, const char *old, int newfd, short irflag; again: + tmp = mp = NULL; bwillwrite(); #ifdef MAC if (mac_vnode_check_rename_from_enabled()) { @@ -3809,6 +3810,7 @@ again: tvp = tond.ni_vp; error = vn_start_write(fvp, &mp, V_NOWAIT); if (error != 0) { +again1: NDFREE_PNBUF(&fromnd); NDFREE_PNBUF(&tond); if (tvp != NULL) @@ -3819,11 +3821,25 @@ again: vput(tdvp); vrele(fromnd.ni_dvp); vrele(fvp); + if (tmp != NULL) { + lockmgr(&tmp->mnt_renamelock, LK_EXCLUSIVE, NULL); + lockmgr(&tmp->mnt_renamelock, LK_RELEASE, NULL); + vfs_rel(tmp); + tmp = NULL; + } error = vn_start_write(NULL, &mp, V_XSLEEP | V_PCATCH); if (error != 0) return (error); goto again; } + error = VOP_GETWRITEMOUNT(tdvp, &tmp); + if (error != 0 || tmp == NULL) + goto again1; + error = lockmgr(&tmp->mnt_renamelock, LK_EXCLUSIVE | LK_NOWAIT, NULL); + if (error != 0) { + vn_finished_write(mp); + goto again1; + } irflag = vn_irflag_read(fvp); if (((irflag & VIRF_NAMEDATTR) != 0 && tdvp != fromnd.ni_dvp) || (irflag & VIRF_NAMEDDIR) != 0) { @@ -3884,6 +3900,8 @@ out: vrele(fromnd.ni_dvp); vrele(fvp); } + lockmgr(&tmp->mnt_renamelock, LK_RELEASE, 0); + vfs_rel(tmp); vn_finished_write(mp); out1: if (error == ERESTART) diff --git a/sys/sys/mount.h b/sys/sys/mount.h index a6f858e02395..f6480b173a5c 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -267,6 +267,7 @@ struct mount { int mnt_lazyvnodelistsize; /* (l) # of lazy vnodes */ int mnt_upper_pending; /* (i) # of pending ops on mnt_uppers */ struct lock mnt_explock; /* vfs_export walkers lock */ + struct lock mnt_renamelock; /* renames and O_RESOLVE_BENEATH */ TAILQ_HEAD(, mount_upper_node) mnt_uppers; /* (i) upper mounts over us */ TAILQ_HEAD(, mount_upper_node) mnt_notify; /* (i) upper mounts for notification */ STAILQ_ENTRY(mount) mnt_taskqueue_link; /* (d) our place in deferred unmount list */