git: 5cec725cd32a - main - unionfs: allow recursion on covered vnode lock during mount/unmount

From: Jason A. Harmening <jah_at_FreeBSD.org>
Date: Sun, 11 Dec 2022 03:48:55 UTC
The branch main has been updated by jah:

URL: https://cgit.FreeBSD.org/src/commit/?id=5cec725cd32a7a2fbe3e4b55d0e25850164b9b0c

commit 5cec725cd32a7a2fbe3e4b55d0e25850164b9b0c
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2022-11-20 18:25:46 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2022-12-11 04:02:38 +0000

    unionfs: allow recursion on covered vnode lock during mount/unmount
    
    When taking the covered vnode lock during mount and unmount operations,
    specify LK_CANRECURSE as the existing lock state of the covered vnode
    is not guaranteed (AFAIK) either by assertion or documentation for
    these code paths.
    
    For the mount path, this is done only for completeness as the covered
    vnode lock is not currently held when VFS_MOUNT() is called.
    For the unmount path, the covered vnode is currently held across
    VFS_UNMOUNT(), and the existing code only happens to work when unionfs
    is mounted atop FFS because FFS sets LO_RECURSABLE on its vnode locks.
    
    This of course doesn't cover a hypothetical case in which the covered
    vnode may be held shared, but for the mount and unmount paths such a
    scenario seems unlikely to materialize.
    
    Reviewed by:    kib
    Tested by:      pho
    Differential Revision:  https://reviews.freebsd.org/D37458
---
 sys/fs/unionfs/union_vfsops.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index c6d668606ec9..8831397c8c5b 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -329,7 +329,7 @@ unionfs_domount(struct mount *mp)
 	 * order unionfs currently requires.
 	 */
 	if (!below) {
-		vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY);
+		vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
 		mp->mnt_vnodecovered->v_vflag |= VV_CROSSLOCK;
 		VOP_UNLOCK(mp->mnt_vnodecovered);
 	}
@@ -386,7 +386,7 @@ unionfs_unmount(struct mount *mp, int mntflags)
 	if (error)
 		return (error);
 
-	vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY);
+	vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
 	mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK;
 	VOP_UNLOCK(mp->mnt_vnodecovered);
 	vfs_unregister_upper(ump->um_lowervp->v_mount, &ump->um_lower_link);