The branch main has been updated by jah:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0ef861e6f4dd37047e6fdb1ae18736434c2c957c

commit 0ef861e6f4dd37047e6fdb1ae18736434c2c957c
Author:     Jason A. Harmening <j...@freebsd.org>
AuthorDate: 2022-11-20 18:33:34 +0000
Commit:     Jason A. Harmening <j...@freebsd.org>
CommitDate: 2022-12-11 04:02:39 +0000

    nullfs: adopt VV_CROSSLOCK
    
    When the lower filesystem directory hierarchy is the same as the nullfs
    mount point (admittedly not likely to be a useful situation in
    practice), nullfs is subject to the exact deadlock between the busy
    count drain and the covered vnode lock that VV_CROSSLOCK is intended
    to address.
    
    Reviewed by:    kib
    Tested by:      pho
    Differential Revision: https://reviews.freebsd.org/D37458
---
 sys/fs/nullfs/null_vfsops.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index fd119afa7f07..216a8badce56 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -201,6 +201,12 @@ nullfs_mount(struct mount *mp)
                    &xmp->notify_node);
        }
 
+       if (lowerrootvp == mp->mnt_vnodecovered) {
+               vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
+               lowerrootvp->v_vflag |= VV_CROSSLOCK;
+               VOP_UNLOCK(lowerrootvp);
+       }
+
        MNT_ILOCK(mp);
        if ((xmp->nullm_flags & NULLM_CACHE) != 0) {
                mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag &
@@ -261,6 +267,11 @@ nullfs_unmount(mp, mntflags)
                vfs_unregister_for_notification(mntdata->nullm_vfs,
                    &mntdata->notify_node);
        }
+       if (mntdata->nullm_lowerrootvp == mp->mnt_vnodecovered) {
+               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(mntdata->nullm_vfs, &mntdata->upper_node);
        vrele(mntdata->nullm_lowerrootvp);
        mp->mnt_data = NULL;

Reply via email to