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;