git: 0ef861e6f4dd - main - nullfs: adopt VV_CROSSLOCK
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 11 Dec 2022 03:48:56 UTC
The branch main has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=0ef861e6f4dd37047e6fdb1ae18736434c2c957c commit 0ef861e6f4dd37047e6fdb1ae18736434c2c957c Author: Jason A. Harmening <jah@FreeBSD.org> AuthorDate: 2022-11-20 18:33:34 +0000 Commit: Jason A. Harmening <jah@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;