Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/union Restructure union_lock() to always lock before ...
details: https://anonhg.NetBSD.org/src/rev/aecf6ff13374
branches: trunk
changeset: 327595:aecf6ff13374
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Mar 12 09:40:05 2014 +0000
description:
Restructure union_lock() to always lock before testing for dead node.
Add two little helpers to lock or unlock a node. Use "vp" for the
union node and "lockvp" for the node to be locked. Use ISSET() to
test flags, add assertions.
diffstat:
sys/fs/union/union_vnops.c | 103 +++++++++++++++++++++++++-------------------
1 files changed, 58 insertions(+), 45 deletions(-)
diffs (162 lines):
diff -r b865335c2abc -r aecf6ff13374 sys/fs/union/union_vnops.c
--- a/sys/fs/union/union_vnops.c Wed Mar 12 09:39:23 2014 +0000
+++ b/sys/fs/union/union_vnops.c Wed Mar 12 09:40:05 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $ */
+/* $NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1590,6 +1590,31 @@
return (0);
}
+static int
+union_lock1(struct vnode *vp, struct vnode *lockvp, int flags)
+{
+ struct vop_lock_args ap;
+
+ if (lockvp == vp) {
+ ap.a_vp = vp;
+ ap.a_flags = flags;
+ return genfs_lock(&ap);
+ } else
+ return VOP_LOCK(lockvp, flags);
+}
+
+static int
+union_unlock1(struct vnode *vp, struct vnode *lockvp)
+{
+ struct vop_unlock_args ap;
+
+ if (lockvp == vp) {
+ ap.a_vp = vp;
+ return genfs_unlock(&ap);
+ } else
+ return VOP_UNLOCK(lockvp);
+}
+
int
union_lock(void *v)
{
@@ -1597,66 +1622,57 @@
struct vnode *a_vp;
int a_flags;
} */ *ap = v;
- struct vnode *vp;
- struct union_node *un = VTOUNION(ap->a_vp);
+ struct vnode *vp = ap->a_vp, *lockvp;
+ struct union_node *un = VTOUNION(vp);
int flags = ap->a_flags;
int error;
if ((flags & LK_NOWAIT) != 0) {
if (!mutex_tryenter(&un->un_lock))
return EBUSY;
- vp = LOCKVP(ap->a_vp);
- if (!mutex_tryenter(vp->v_interlock)) {
- mutex_exit(&un->un_lock);
- return EBUSY;
- }
- if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+ lockvp = LOCKVP(vp);
+ error = union_lock1(vp, lockvp, flags);
+ mutex_exit(&un->un_lock);
+ if (error)
+ return error;
+ if (mutex_tryenter(vp->v_interlock)) {
+ if (ISSET(vp->v_iflag, VI_XLOCK))
+ error = EBUSY;
+ else if (ISSET(vp->v_iflag, VI_CLEAN))
+ error = ENOENT;
+ else
+ error = 0;
mutex_exit(vp->v_interlock);
- mutex_exit(&un->un_lock);
- return EBUSY;
- }
- mutex_exit(vp->v_interlock);
- if (vp == ap->a_vp)
- error = genfs_lock(ap);
- else
- error = VOP_LOCK(vp, flags);
- mutex_exit(&un->un_lock);
+ } else
+ error = EBUSY;
+ if (error)
+ union_unlock1(vp, lockvp);
return error;
}
mutex_enter(&un->un_lock);
for (;;) {
- vp = LOCKVP(ap->a_vp);
+ lockvp = LOCKVP(vp);
mutex_exit(&un->un_lock);
- if (vp == ap->a_vp)
- error = genfs_lock(ap);
- else
- error = VOP_LOCK(vp, ap->a_flags);
+ error = union_lock1(vp, lockvp, flags);
if (error != 0)
return error;
mutex_enter(&un->un_lock);
- if (vp == LOCKVP(ap->a_vp))
+ if (lockvp == LOCKVP(vp))
break;
- if (vp == ap->a_vp)
- genfs_unlock(ap);
- else
- VOP_UNLOCK(vp);
+ union_unlock1(vp, lockvp);
}
+ mutex_exit(&un->un_lock);
+
mutex_enter(vp->v_interlock);
- if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
- if (vp == ap->a_vp)
- genfs_unlock(ap);
- else
- VOP_UNLOCK(vp);
- if ((vp->v_iflag & VI_XLOCK))
- vwait(vp, VI_XLOCK);
+ if (ISSET(vp->v_iflag, VI_XLOCK) || ISSET(vp->v_iflag, VI_CLEAN)) {
+ union_unlock1(vp, lockvp);
+ vwait(vp, VI_XLOCK);
+ KASSERT(ISSET(vp->v_iflag, VI_CLEAN));
mutex_exit(vp->v_interlock);
- mutex_exit(&un->un_lock);
return ENOENT;
}
mutex_exit(vp->v_interlock);
- mutex_exit(&un->un_lock);
-
return 0;
}
@@ -1667,13 +1683,10 @@
struct vnode *a_vp;
int a_flags;
} */ *ap = v;
- struct vnode *vp;
+ struct vnode *vp = ap->a_vp, *lockvp;
- vp = LOCKVP(ap->a_vp);
- if (vp == ap->a_vp)
- genfs_unlock(ap);
- else
- VOP_UNLOCK(vp);
+ lockvp = LOCKVP(vp);
+ union_unlock1(vp, lockvp);
return 0;
}
Home |
Main Index |
Thread Index |
Old Index