Page MenuHomeFreeBSD

D40720.id.diff
No OneTemporary

D40720.id.diff

diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -212,12 +212,6 @@
&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 &
@@ -276,11 +270,6 @@
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;
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -325,28 +325,13 @@
}
/*
- * Specify that the covered vnode lock should remain held while
- * lookup() performs the cross-mount walk. This prevents a lock-order
- * reversal between the covered vnode lock (which is also locked by
- * unionfs_lock()) and the mountpoint's busy count. Without this,
- * unmount will lock the covered vnode lock (directly through the
- * covered vnode) and wait for the busy count to drain, while a
- * concurrent lookup will increment the busy count and then lock
- * the covered vnode lock (indirectly through unionfs_lock()).
- *
- * Note that we can't yet use this facility for the 'below' case
- * in which the upper vnode is the covered vnode, because that would
- * introduce a different LOR in which the cross-mount lookup would
- * effectively hold the upper vnode lock before acquiring the lower
- * vnode lock, while an unrelated lock operation would still acquire
- * the lower vnode lock before the upper vnode lock, which is the
- * order unionfs currently requires.
+ * For the 'below' case in which the upper vnode is the covered vnode,
+ * there is currently a LOR in which the cross-mount lookup effectively
+ * leads to holding the upper vnode lock before acquiring the lower
+ * vnode lock, while an unrelated lock operation would still acquire the
+ * lower vnode lock before the upper vnode lock, which is the order
+ * unionfs currently requires.
*/
- if (!below) {
- vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
- mp->mnt_vnodecovered->v_vflag |= VV_CROSSLOCK;
- VOP_UNLOCK(mp->mnt_vnodecovered);
- }
MNT_ILOCK(mp);
if ((lowermp->mnt_flag & MNT_LOCAL) != 0 &&
@@ -400,9 +385,6 @@
if (error)
return (error);
- 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);
vfs_unregister_upper(ump->um_uppervp->v_mount, &ump->um_upper_link);
free(ump, M_UNIONFSMNT);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -777,7 +777,9 @@
*
* The lookup() process for namei("/var") illustrates the process:
* 1. VOP_LOOKUP() obtains B while A is held
- * 2. vfs_busy() obtains a shared lock on F while A and B are held
+ * 2. vfs_busy(MBF_NOWAIT) tries to obtain a lock on F while A and B are held
+ * 3. If this didn't work, the lock on B is temporary released, vfs_busy()
+ * called again to obtain F, and lock on B reacquired via vn_lock().
* 3. vput() releases lock on B
* 4. vput() releases lock on A
* 5. VFS_ROOT() obtains lock on D while shared lock on F is held
@@ -786,12 +788,10 @@
* Attempt to lock A (instead of vp_crossmp) while D is held would
* violate the global order, causing deadlocks.
*
- * dounmount() locks B while F is drained. Note that for stacked
- * filesystems, D and B in the example above may be the same lock,
- * which introdues potential lock order reversal deadlock between
- * dounmount() and step 5 above. These filesystems may avoid the LOR
- * by setting VV_CROSSLOCK on the covered vnode so that lock B will
- * remain held until after step 5.
+ * dounmount() doesn't lock B anymore while F is drained. Consequently, there
+ * is no more a risk of LOR with stacked filesystems, for which D and B in the
+ * example above may be the same lock (concurrent execution of dounmount() and
+ * step 5 above).
*/
int
vfs_busy(struct mount *mp, int flags)
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -253,7 +253,6 @@
#define VV_FORCEINSMQ 0x1000 /* force the insmntque to succeed */
#define VV_READLINK 0x2000 /* fdescfs linux vnode */
#define VV_UNREF 0x4000 /* vunref, do not drop lock in inactive() */
-#define VV_CROSSLOCK 0x8000 /* vnode lock is shared w/ root mounted here */
#define VMP_LAZYLIST 0x0001 /* Vnode is on mnt's lazy list */

File Metadata

Mime Type
text/plain
Expires
Wed, Jun 17, 9:24 PM (1 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34035003
Default Alt Text
D40720.id.diff (5 KB)

Event Timeline