Page MenuHomeFreeBSD

D34109.id102171.diff
No OneTemporary

D34109.id102171.diff

Index: sys/fs/unionfs/union_subr.c
===================================================================
--- sys/fs/unionfs/union_subr.c
+++ sys/fs/unionfs/union_subr.c
@@ -442,7 +442,16 @@
int count;
int writerefs;
- KASSERT(vp->v_vnlock->lk_recurse == 0,
+ /*
+ * The root vnode lock may be recursed during forcible, because
+ * it may share the same lock as the unionfs mount's covered vnode,
+ * which is locked across VFS_UNMOUNT(). This lock will then be
+ * recursively taken during the vflush() issued by unionfs_unmount().
+ * But we still only need to lock the unionfs lock once, because only
+ * one of those lock operations was taken against a unionfs vnode and
+ * will be undone against a unionfs vnode.
+ */
+ KASSERT(vp->v_vnlock->lk_recurse == 0 || (vp->v_vflag & VV_ROOT) != 0,
("%s: vnode %p locked recursively", __func__, vp));
if (lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL) != 0)
panic("%s: failed to acquire lock for vnode lock", __func__);
@@ -821,7 +830,7 @@
VNASSERT(vp->v_writecount == 0, vp,
("%s: non-zero writecount", __func__));
/*
- * Uppdate the upper vnode's lock state to match the lower vnode,
+ * Update the upper vnode's lock state to match the lower vnode,
* and then switch the unionfs vnode's lock to the upper vnode.
*/
lockrec = lvp->v_vnlock->lk_recurse;
Index: sys/fs/unionfs/union_vnops.c
===================================================================
--- sys/fs/unionfs/union_vnops.c
+++ sys/fs/unionfs/union_vnops.c
@@ -76,8 +76,8 @@
#endif
#define KASSERT_UNIONFS_VNODE(vp) \
- KASSERT(((vp)->v_op == &unionfs_vnodeops), \
- ("unionfs: it is not unionfs-vnode"))
+ VNASSERT(((vp)->v_op == &unionfs_vnodeops), vp, \
+ ("%s: non-unionfs vnode", __func__))
static int
unionfs_lookup(struct vop_cachedlookup_args *ap)
@@ -1918,8 +1918,6 @@
int interlock;
int uhold;
- KASSERT_UNIONFS_VNODE(ap->a_vp);
-
/*
* TODO: rework the unionfs locking scheme.
* It's not guaranteed to be safe to blindly lock two vnodes on
@@ -1945,19 +1943,21 @@
unp = VTOUNIONFS(vp);
if (unp == NULL)
goto unionfs_lock_null_vnode;
+
+ KASSERT_UNIONFS_VNODE(ap->a_vp);
+
lvp = unp->un_lowervp;
uvp = unp->un_uppervp;
if ((revlock = unionfs_get_llt_revlock(vp, flags)) == 0)
panic("unknown lock type: 0x%x", flags & LK_TYPE_MASK);
- if ((flags & LK_TYPE_MASK) != LK_DOWNGRADE &&
- (vp->v_iflag & VI_OWEINACT) != 0)
- flags |= LK_NOWAIT;
-
/*
- * Sometimes, lower or upper is already exclusive locked.
- * (ex. vfs_domount: mounted vnode is already locked.)
+ * During unmount, the root vnode lock may be taken recursively,
+ * because it may share the same v_vnlock field as the vnode covered by
+ * the unionfs mount. The covered vnode is locked across VFS_UNMOUNT(),
+ * and the same lock may be taken recursively here during vflush()
+ * issued by unionfs_unmount().
*/
if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE &&
(vp->v_vflag & VV_ROOT) != 0)

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 22, 8:28 PM (7 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27862066
Default Alt Text
D34109.id102171.diff (2 KB)

Event Timeline