From nobody Tue Feb 24 01:44:51 2026 X-Original-To: dev-commits-src-branches@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 4fKgWm34tSz6SvrW for ; Tue, 24 Feb 2026 01:44:52 +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 "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fKgWm0x7Mz3xvY for ; Tue, 24 Feb 2026 01:44:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1771897492; 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=4spjuUXCNlii6lM4pGt1fPUUe+t7EMtVmAU8TPlg69I=; b=Jj/QxnsqDzztVtTq30Eef9p8bYIlzGXZC+v+GoC8Hv1Q5Iihgh3l2gXYsB6P7vua5EctQG tSH7z9eW7kizHTb9QXHgMiEcNfE5v1Qg91YIeGCDPGnAuSLqJztJbOEez8ygBAXbJewtCZ cwWb4x2O8ErDBBG40JMk6BA7gefjlJMDBWmZ7ppet51N07iVyEoZtQmXRby7yzM8J9VrSA 5F740iE3Nr1xBUQL2hloORvyavGG+GEsxC/VdFBWz7zXJPTpCsgMABEnkKEa6lQLPfcDGT eI9gkD7SZh31s5qqDPyDE8eeMaRjKWwP7N2YexUhO2SQn0/JzV2ZZjsYL0WVpQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1771897492; a=rsa-sha256; cv=none; b=K3E3KnOZpWSw/Lt5lPlMYs9OE8yjUC3zUVkHhfcNXdXC2nGVOBg3uqTJYW1tAQZ283ItL9 J7zZj/A4JJoQ/OmoWwmSAzEZPnMVz2Jva1/S87hJygPTKWaIA9aYEOZA/X6h9E88tADI+R amCLecZUPX71e4QixBUdB6C6GYi5WTeVilt7ss3isYyDvhyUiQarpzvjbLx6xI/u2OX/Lv Gqqsv2b2gwLhoaXNzryK47CL2pWHheWyX55t7FxZLHpkIiO5OYp/6NwvY7MWdJB/3S4RiP B4ntijoOBnUrVrhARZXUofc54HXtv0itr2kbMWbpECoNs6dzRFlK4ZMbrec95g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1771897492; 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=4spjuUXCNlii6lM4pGt1fPUUe+t7EMtVmAU8TPlg69I=; b=uFZWerxLwa4k2hQPeO1/B4dwqIYQhhIqGLVU8sfP4tyDZE1bJaISmAIoxio1mAzP3ol55Z 1XwpfVbxiA+w4LwzS3cvUO6AcxSuCiO7DUul/A1w9rlKNmEAoQwX0q7cDjq46JGOEdzR+O fHatIa3dLH3u/x7ccQmJPh2ksMdYAx9RlAW/8/BwhTxVDABQPvATOb3m/tTXrfEqQC7LZq 1kCNoeNznHgYIogcOQvUL4Lh9hI70o8YZCBz84gj8GIIlcloGHRcqw+nGUbownjNlqIgHU DvC+7DOeKwx2ozzli9/xXNI2ttMUp5lUCNJ5sliRGgK9cuy8lghl0kAG0EZp6w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fKgWl6qBRzvRw for ; Tue, 24 Feb 2026 01:44:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d910 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 24 Feb 2026 01:44:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: 7ae432e6fbb2 - stable/15 - vfs_mount.c: Don't call VFS_MOUNT() if only exports are being updated List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 7ae432e6fbb2350fbb6a805dd0e14b73f8e0c9ef Auto-Submitted: auto-generated Date: Tue, 24 Feb 2026 01:44:51 +0000 Message-Id: <699d0293.1d910.5ae75a70@gitrepo.freebsd.org> The branch stable/15 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=7ae432e6fbb2350fbb6a805dd0e14b73f8e0c9ef commit 7ae432e6fbb2350fbb6a805dd0e14b73f8e0c9ef Author: Rick Macklem AuthorDate: 2026-02-17 22:57:42 +0000 Commit: Rick Macklem CommitDate: 2026-02-24 01:41:58 +0000 vfs_mount.c: Don't call VFS_MOUNT() if only exports are being updated PR#293198 reports a hang within ZFS when exports are being updated concurrently with a VOP_SETEXTATTR(). The hang appears to be caused by mishandling of the z_teardown_lock, but fixing handling of this lock appears to be a major effort. Since the hang occurs when VFS_MOUNT() acquires a write/exclusive z_teardown_lock, which rarely occurs, except when exports are being updated, this patch avoids the VFS_MOUNT() call for this case. Avoiding a VFS_MOUNT() call fixes the hang for the case reported by PR#293198 and is also an optimization. As such, this patch avoids the VFS_MOUNT() call when only exports are being updated similar to what was already being done within vnet prisons. PR: 293198 (cherry picked from commit 935cf3284f520c90a63baaadb762caaa30084f5c) --- sys/kern/vfs_mount.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 2237fcc6b423..383ccf98c10e 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -74,7 +74,7 @@ #define VFS_MOUNTARG_SIZE_MAX (1024 * 64) static int vfs_domount(struct thread *td, const char *fstype, char *fspath, - uint64_t fsflags, bool jail_export, + uint64_t fsflags, bool only_export, bool jail_export, struct vfsoptlist **optlist); static void free_mntarg(struct mntarg *ma); @@ -806,7 +806,7 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) struct vfsopt *opt, *tmp_opt; char *fstype, *fspath, *errmsg; int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; - bool autoro, has_nonexport, jail_export; + bool autoro, has_nonexport, only_export, jail_export; errmsg = fspath = NULL; errmsg_len = fspathlen = 0; @@ -861,12 +861,11 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) * when we want to update the root filesystem. */ has_nonexport = false; - jail_export = false; + only_export = false; TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) { int do_freeopt = 0; - if (jailed(td->td_ucred) && - strcmp(opt->name, "export") != 0 && + if (strcmp(opt->name, "export") != 0 && strcmp(opt->name, "update") != 0 && strcmp(opt->name, "fstype") != 0 && strcmp(opt->name, "fspath") != 0 && @@ -957,7 +956,7 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) fsflags |= MNT_UNION; else if (strcmp(opt->name, "export") == 0) { fsflags |= MNT_EXPORTED; - jail_export = true; + only_export = true; } else if (strcmp(opt->name, "automounted") == 0) { fsflags |= MNT_AUTOMOUNTED; do_freeopt = 1; @@ -989,14 +988,22 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) } /* - * If has_nonexport is true or the caller is not running within a - * vnet prison that can run mountd(8), set jail_export false. + * only_export is set to true only if exports are being + * updated and nothing else is being updated. + */ + if (has_nonexport) + only_export = false; + /* + * If only_export is true and the caller is running within a + * vnet prison that can run mountd(8), set jail_export true. */ - if (has_nonexport || !jailed(td->td_ucred) || - !prison_check_nfsd(td->td_ucred)) - jail_export = false; + jail_export = false; + if (only_export && jailed(td->td_ucred) && + prison_check_nfsd(td->td_ucred)) + jail_export = true; - error = vfs_domount(td, fstype, fspath, fsflags, jail_export, &optlist); + error = vfs_domount(td, fstype, fspath, fsflags, only_export, + jail_export, &optlist); if (error == ENODEV) { error = EINVAL; if (errmsg != NULL) @@ -1014,8 +1021,8 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) printf("%s: R/W mount failed, possibly R/O media," " trying R/O mount\n", __func__); fsflags |= MNT_RDONLY; - error = vfs_domount(td, fstype, fspath, fsflags, jail_export, - &optlist); + error = vfs_domount(td, fstype, fspath, fsflags, only_export, + jail_export, &optlist); } bail: /* copyout the errmsg */ @@ -1307,6 +1314,7 @@ vfs_domount_update( struct thread *td, /* Calling thread. */ struct vnode *vp, /* Mount point vnode. */ uint64_t fsflags, /* Flags common to all filesystems. */ + bool only_export, /* Got export option. */ bool jail_export, /* Got export option in vnet prison. */ struct vfsoptlist **optlist /* Options local to the filesystem. */ ) @@ -1442,15 +1450,16 @@ vfs_domount_update( * get. No freeing of cn_pnbuf. */ /* + * When only updating mount exports, VFS_MOUNT() does not need to + * be called, as indicated by only_export being set true. * For the case of mountd(8) doing exports from within a vnet jail, * "from" is typically not set correctly such that VFS_MOUNT() will - * return ENOENT. It is not obvious that VFS_MOUNT() ever needs to be - * called when mountd is doing exports, but this check only applies to - * the specific case where it is running inside a vnet jail, to - * avoid any POLA violation. + * return ENOENT. For ZFS, there is a locking bug which can result in + * deadlock if VFS_MOUNT() is called when extended attributes are + * being updated. */ error = 0; - if (!jail_export) + if (!only_export) error = VFS_MOUNT(mp); export_error = 0; @@ -1590,6 +1599,7 @@ vfs_domount( const char *fstype, /* Filesystem type. */ char *fspath, /* Mount path. */ uint64_t fsflags, /* Flags common to all filesystems. */ + bool only_export, /* Got export option. */ bool jail_export, /* Got export option in vnet prison. */ struct vfsoptlist **optlist /* Options local to the filesystem. */ ) @@ -1693,8 +1703,8 @@ vfs_domount( } free(pathbuf, M_TEMP); } else - error = vfs_domount_update(td, vp, fsflags, jail_export, - optlist); + error = vfs_domount_update(td, vp, fsflags, only_export, + jail_export, optlist); out: NDFREE_PNBUF(&nd);