Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/genfs Restructure genfs_deadlock() and genfs_lock...
details: https://anonhg.NetBSD.org/src/rev/e2e3bd8f805a
branches: trunk
changeset: 327593:e2e3bd8f805a
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Mar 12 09:38:51 2014 +0000
description:
Restructure genfs_deadlock() and genfs_lock() to always lock before
testing for dead node. Use ISSET() to test flags, add assertions.
Save the mount for fstrans_done() before genfs_unlock() unlocks the node.
diffstat:
sys/miscfs/genfs/genfs_vnops.c | 94 ++++++++++++++++++++++++-----------------
1 files changed, 55 insertions(+), 39 deletions(-)
diffs (155 lines):
diff -r 5722ed3f3327 -r e2e3bd8f805a sys/miscfs/genfs/genfs_vnops.c
--- a/sys/miscfs/genfs/genfs_vnops.c Wed Mar 12 08:36:59 2014 +0000
+++ b/sys/miscfs/genfs/genfs_vnops.c Wed Mar 12 09:38:51 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_vnops.c,v 1.190 2014/02/27 16:51:38 hannken Exp $ */
+/* $NetBSD: genfs_vnops.c,v 1.191 2014/03/12 09:38:51 hannken Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.190 2014/02/27 16:51:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.191 2014/03/12 09:38:51 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -290,33 +290,42 @@
struct vnode *vp = ap->a_vp;
int flags = ap->a_flags;
krw_t op;
-
- if ((flags & LK_NOWAIT) != 0) {
- if (!mutex_tryenter(vp->v_interlock))
- return EBUSY;
- if ((vp->v_iflag & VI_XLOCK)) {
- mutex_exit(vp->v_interlock);
- return EBUSY;
- }
- }
+ int error;
- mutex_enter(vp->v_interlock);
- if ((vp->v_iflag & VI_XLOCK))
- vwait(vp, VI_XLOCK);
- mutex_exit(vp->v_interlock);
-
- if ((flags & LK_RETRY) == 0)
- return ENOENT;
-
- op = ((flags & LK_EXCLUSIVE) != 0 ? RW_WRITER : RW_READER);
- if ((flags & LK_NOWAIT) != 0) {
+ op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER);
+ if (ISSET(flags, LK_NOWAIT)) {
if (! rw_tryenter(&vp->v_lock, op))
return EBUSY;
- return 0;
+ if (mutex_tryenter(vp->v_interlock)) {
+ if (ISSET(vp->v_iflag, VI_XLOCK))
+ error = EBUSY;
+ else {
+ KASSERT(ISSET(vp->v_iflag, VI_CLEAN));
+ error = (ISSET(flags, LK_RETRY) ? 0 : ENOENT);
+ }
+ mutex_exit(vp->v_interlock);
+ } else
+ error = EBUSY;
+ if (error)
+ rw_exit(&vp->v_lock);
+ return error;
}
rw_enter(&vp->v_lock, op);
-
+ mutex_enter(vp->v_interlock);
+ if (ISSET(vp->v_iflag, VI_XLOCK)) {
+ rw_exit(&vp->v_lock);
+ vwait(vp, VI_XLOCK);
+ mutex_exit(vp->v_interlock);
+ rw_enter(&vp->v_lock, op);
+ mutex_enter(vp->v_interlock);
+ }
+ KASSERT(ISSET(vp->v_iflag, VI_CLEAN));
+ mutex_exit(vp->v_interlock);
+ if (! ISSET(flags, LK_RETRY)) {
+ rw_exit(&vp->v_lock);
+ return ENOENT;
+ }
return 0;
}
@@ -350,39 +359,45 @@
struct mount *mp = vp->v_mount;
int flags = ap->a_flags;
krw_t op;
+ int error;
- op = ((flags & LK_EXCLUSIVE) != 0 ? RW_WRITER : RW_READER);
- if ((flags & LK_NOWAIT) != 0) {
- if (!mutex_tryenter(vp->v_interlock))
- return EBUSY;
- if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
- mutex_exit(vp->v_interlock);
- return EBUSY;
- }
- mutex_exit(vp->v_interlock);
+ op = (ISSET(flags, LK_EXCLUSIVE) ? RW_WRITER : RW_READER);
+ if (ISSET(flags, LK_NOWAIT)) {
if (fstrans_start_nowait(mp, FSTRANS_SHARED))
return EBUSY;
if (! rw_tryenter(&vp->v_lock, op)) {
fstrans_done(mp);
return EBUSY;
}
- return 0;
+ 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);
+ } else
+ error = EBUSY;
+ if (error) {
+ rw_exit(&vp->v_lock);
+ fstrans_done(mp);
+ }
+ return error;
}
fstrans_start(mp, FSTRANS_SHARED);
rw_enter(&vp->v_lock, op);
-
mutex_enter(vp->v_interlock);
- if ((vp->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0) {
+ if (ISSET(vp->v_iflag, VI_XLOCK) || ISSET(vp->v_iflag, VI_CLEAN)) {
rw_exit(&vp->v_lock);
fstrans_done(mp);
- if ((vp->v_iflag & VI_XLOCK))
- vwait(vp, VI_XLOCK);
+ vwait(vp, VI_XLOCK);
+ KASSERT(ISSET(vp->v_iflag, VI_CLEAN));
mutex_exit(vp->v_interlock);
return ENOENT;
}
mutex_exit(vp->v_interlock);
-
return 0;
}
@@ -396,9 +411,10 @@
struct vnode *a_vp;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
+ struct mount *mp = vp->v_mount;
rw_exit(&vp->v_lock);
- fstrans_done(vp->v_mount);
+ fstrans_done(mp);
return 0;
}
Home |
Main Index |
Thread Index |
Old Index