From nobody Thu Aug 13 00:35:53 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 4hL5xk2jDGzGmnt for ; Thu, 13 Aug 2026 00:35:54 +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 4hL5xj3YRXz3SqQ for ; Thu, 13 Aug 2026 00:35:53 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786581353; 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=Xfvydm32KavzEP1wg0O+QQEi9lKN3U1V3Kju6nus034=; b=K3MLhPBdTU4B8aQl/pbdoNZ/tfENcz35uQO40S7KquUzBuHgAsSAIj6UZMaCdBEmlq6qDL NSoheZYguZkOMeu1eJMx6rt6q/5XW1yb+zcSc0+R7D4mCPaRYTM0rg9ReP7wLEnKqZBljc 9dhMv9/RJ+3S4UEqErkYSeINSolTNUdahYvcPR3w6fzMALE2mvsl1rv/XjqHzpxagxdmsi Y//45sITTYc0aU0q4nBqtZnD5zriSbFqaQDwjLw1p8bR3PmtN2ncVo9XjuHXZnVa0g+x76 c5EgxbzDGygwxS5ed/3wl3YET9H/FwOXGbWCRW/WKJQCpq/ca4NCe9YjpFW9zA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786581353; a=rsa-sha256; cv=none; b=UbVVeCj1xXN5F0CHzP08bW0rO9j28nFhgGkUh/rkae7eL4jcuxVSutwcz6VQAir8kTxXig AN6qKigZn3oXxXjWlN6D7teAT6yCcav+j2F9aZ4mfKVIgxpuuTnjKZw3on28LgeHFGilkG 7UsfizuHCmhTBS336AzUVaYEyoQTc2DrAeY0s6L3FrYOrG3WV/QkhhzouKhriWshdzG6Td uwb/dkb1XevxIvFKLvuKx1mpzjt9L4YOztxTHILhHzmpJBi6mtHeX0+cmc9YOvY1Qt4ByO b2HInQcRW0NF1dmzKGgudlMVOkzM8QWxQusOuNi94ktVNFsCnQLy5wbDN0LKrg== 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=1786581353; 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=Xfvydm32KavzEP1wg0O+QQEi9lKN3U1V3Kju6nus034=; b=S/4HE3gkBN9qfuwB80xzh08yBKCszv50veAZyzNNuaqGuvKrGGwmsTVFnpkVnSyG5Y4Ccl q2TVp+moapyaLBsreGvQKkJ6GAQpMV2FWmwnA05TRl9oPiE5LcH8HapD2f6/5iU3km0q/5 LPmV/DfscjQ4w/Ga+YCEmRyUdyX5A0mJOdNYJI6ZogRHg5NKkcY0mvkIZYLsJ1CB3iF0QV oNa3NKZfTwiFS7xoSxwzMgV96B15dKt10rfW5B/kbbwQQmDbdRDTzkFOitweiwKt25NvTV zpx2soGmbI+KJUBtd9KJakgOqUvHCokB6YYJ7uD05ie/P3JJxTVxOSytWNCWPQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hL5xj0KFFzpbr for ; Thu, 13 Aug 2026 00:35:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 20645 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 13 Aug 2026 00:35:53 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 42dbbaf748ea - stable/15 - 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/stable/15 X-Git-Reftype: branch X-Git-Commit: 42dbbaf748ea18195174854dae0831180af3e256 Auto-Submitted: auto-generated Date: Thu, 13 Aug 2026 00:35:53 +0000 Message-Id: <6a7d1169.20645.45b31036@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=42dbbaf748ea18195174854dae0831180af3e256 commit 42dbbaf748ea18195174854dae0831180af3e256 Author: Konstantin Belousov AuthorDate: 2026-07-31 04:12:17 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-13 00:34:41 +0000 dounmount(9): temporarily enable recursion for the covered vnode lock PR: 297174 (cherry picked from commit 9f5c4ef32812afb4573a278e6eafe5040f839d13) --- 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 0a3cce26ee48..82bba3f2ee61 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1852,7 +1852,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); @@ -1864,6 +1865,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); } @@ -2165,6 +2168,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), @@ -2273,6 +2277,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); @@ -2289,6 +2294,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); @@ -2298,7 +2316,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; @@ -2311,7 +2329,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); @@ -2393,6 +2412,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); } @@ -2413,6 +2434,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); }