From nobody Fri Aug 7 09:10:06 2026 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 4hGddp6YHcz6pC0q for ; Fri, 07 Aug 2026 09:10:06 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hGddp3s2mz3gXy for ; Fri, 07 Aug 2026 09:10:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786093806; 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=yIEZKnRMj3ty3+icZiiuqdeHcsAYaGaUEdI41jDtsJM=; b=RE+tbT+2Ucvo8S7QlZ5EDLaUKSoBhuswLZdJTORyXKBERW9G3DXee31iLP+f0Tj8F2ONxi rCHb3vLGeM2eul/79lvwG7WK0KgQ5S+DYb595gmFirc3S1jyPnaSrYl+A0SSjRqKDoEj8i msxQ11FFqOAhNWcJcjTaUGo0/3YwMYDhvkA0Eh2KhlatMEuQ6pgEga/eiprSIGojjy1Iyx 5xxXy87pzuBV+YuaJDtjQeXtchF+eEJkBgN5Axm24ijXh/tZZsxIufTOlUUGTX9RKz5dIC DIFL6WjFV2C/2UJCt5EDIA4Ej+8F80FyeKGpyC+hExvxtheccmgw5/B7uU997A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786093806; a=rsa-sha256; cv=none; b=QZaN2NGkDXba2SntOutdv1nT22yu5FTf7eL1vQ3VOvFoMbcfkFQW4utpg5V5Aa8aGzhJjj 09DZ4dL4T/yrJVm66oS6YwPXPasXmewxkZAgn3VbT8LSWwWK/ArHgaQfAMiYmAJfFiK8dL pxNqJIxpxCUgVGRDACiNeFAE1AGnJgD9UMVlUN9BktV09lkZbZ1+QqBsjhbIlnSlee3WFS UaKF4uwl9C1fj/74KvC0IO6d7JSME5fwhkJFOjpmeqLmWgbKM3/pvb+cBm+5YtOycTo85F xnMhxzvJaUJPQBCPHN0ekzdq8ghmFld/LVwIjTP0rSBHZ5MGw2yzdSy18V9mzg== 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=1786093806; 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=yIEZKnRMj3ty3+icZiiuqdeHcsAYaGaUEdI41jDtsJM=; b=MMEcz31jIVk6yJyMEkEtAtrrjS5qFvlzarHl8qh8FVgmiqeT7Tl7n1s9SPkyMPqw69epZa 6+DbuV8b2uGfj9MZvnNbnbdJCqccfDqHZuTquhVmgPUfqaDRysDFON7uixBvJwSbISr0fI hRVen1p8XdE91GHY8tM0cFPei4xGTfOUrs+DkA/QYQnX43Xz7v8WLT2APaUdLllv7Ge7l4 +SpFVjEkHjY2mzQexGBwUmN5M8k/256GDdj/TvBy83S6vVSf44PxDHJ4Dqyrqb3vAC91KQ BmhsXJA7Yucr19GHC3E5EuATz9IvAIXVYYIpTCnYw9+DGYzh7ZmdPy9tPPnOjQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hGddp2xSTz11SY for ; Fri, 07 Aug 2026 09:10:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c782 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 07 Aug 2026 09:10:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 9f5c4ef32812 - main - dounmount(9): temporarily enable recursion for the covered vnode 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 List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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: 9f5c4ef32812afb4573a278e6eafe5040f839d13 Auto-Submitted: auto-generated Date: Fri, 07 Aug 2026 09:10:06 +0000 Message-Id: <6a75a0ee.1c782.5e203c3e@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=9f5c4ef32812afb4573a278e6eafe5040f839d13 commit 9f5c4ef32812afb4573a278e6eafe5040f839d13 Author: Konstantin Belousov AuthorDate: 2026-07-31 04:12:17 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-07 09:09:50 +0000 dounmount(9): temporarily enable recursion for the covered vnode lock For some complex nullfs mount configurations, it is possible to get the covered vnode lock for the mount shared with some inside-mount vnode lock. Then at unmount time, vflush() would recurse on the covered vnode lock when reclaiming the vnode. Work around it, by temprorarily allowing recursion on the covered vnode lock. Disable recursion after the unmount if it was not enabled before. PR: 297174 Reviewed by: jah Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58567 --- sys/kern/vfs_mount.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index f123c59981c4..90215a64b08b 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1880,7 +1880,8 @@ vfs_check_usecounts(struct mount *mp) } static void -dounmount_cleanup(struct mount *mp, struct vnode *coveredvp, int mntkflags) +dounmount_cleanup(struct mount *mp, struct vnode *coveredvp, int mntkflags, + bool disablerec) { mtx_assert(MNT_MTX(mp), MA_OWNED); @@ -1892,6 +1893,8 @@ dounmount_cleanup(struct mount *mp, struct vnode *coveredvp, int mntkflags) vfs_op_exit_locked(mp); MNT_IUNLOCK(mp); if (coveredvp != NULL) { + if (disablerec) + VN_LOCK_DREC(coveredvp); VOP_UNLOCK(coveredvp); vdrop(coveredvp); } @@ -2193,6 +2196,7 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) uint64_t async_flag; int mnt_gen_r; unsigned int retries; + bool coveredrec; KASSERT((flags & MNT_DEFERRED) == 0 || (flags & (MNT_RECURSE | MNT_FORCE)) == (MNT_RECURSE | MNT_FORCE), @@ -2301,6 +2305,7 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) if ((flags & MNT_DEFERRED) != 0) vfs_ref(mp); + coveredrec = false; if ((coveredvp = mp->mnt_vnodecovered) != NULL) { mnt_gen_r = mp->mnt_gen; VI_LOCK(coveredvp); @@ -2317,6 +2322,19 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) vfs_rel(mp); return (EBUSY); } + + /* + * For some complex nullfs mount configurations, it is + * possible to get the covered vnode lock for the + * mount shared with some inside-mount vnode lock. + * Then at unmount time, vflush() would recurse on the + * covered vnode lock when reclaiming the vnode. + * + * To work around it, temprorarily allow recursion for + * the covered vnode lock. + */ + coveredrec = VN_LOCK_CANREC(coveredvp); + VN_LOCK_AREC(coveredvp); } vfs_op_enter(mp); @@ -2326,7 +2344,7 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 || (mp->mnt_flag & MNT_UPDATE) != 0 || !TAILQ_EMPTY(&mp->mnt_uppers)) { - dounmount_cleanup(mp, coveredvp, 0); + dounmount_cleanup(mp, coveredvp, 0, !coveredrec); return (EBUSY); } mp->mnt_kern_flag |= MNTK_UNMOUNT; @@ -2339,7 +2357,8 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) MNT_ILOCK(mp); if (error != 0) { vn_seqc_write_end(coveredvp); - dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT); + dounmount_cleanup(mp, coveredvp, MNTK_UNMOUNT, + !coveredrec); if (rootvp != NULL) { vn_seqc_write_end(rootvp); vrele(rootvp); @@ -2425,6 +2444,8 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) MNT_IUNLOCK(mp); if (coveredvp) { vn_seqc_write_end(coveredvp); + if (!coveredrec) + VN_LOCK_DREC(coveredvp); VOP_UNLOCK(coveredvp); vdrop(coveredvp); } @@ -2445,6 +2466,8 @@ dounmount(struct mount *mp, uint64_t flags, struct thread *td) coveredvp->v_mountedhere = NULL; vn_seqc_write_end_locked(coveredvp); VI_UNLOCK(coveredvp); + if (!coveredrec) + VN_LOCK_DREC(coveredvp); VOP_UNLOCK(coveredvp); vdrop(coveredvp); }