summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-08-06 19:35:18 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-08-06 19:35:18 +0000
commit89fedd1a8d2624bae7d2310a83d39156079353b6 (patch)
tree85d9d00a998016639251d59ff97e2a4df0bfa685 /sys/kern
parent67f0f9ef8777688f212974c7fd984398c1827902 (diff)
Rename vop_revoke, vn_bwrite, vop_noislocked, vop_nolock, vop_nounlock
to be vop_generic_revoke, vop_generic_bwrite, vop_generic_islocked, vop_generic_lock and vop_generic_unlock. Create vop_generic_abortop and propogate change to all file systems. Fix PR/371. Get rid of locking in NULLFS (should be mostly unnecessary now except for forced unmounts).
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_default.c36
-rw-r--r--sys/kern/vfs_subr.c147
-rw-r--r--sys/kern/vfs_sync.c8
-rw-r--r--sys/kern/vfs_vnops.c4
4 files changed, 111 insertions, 84 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 66811990ef2..26c9e49a5a2 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_default.c,v 1.2 1998/01/11 02:10:44 csapuntz Exp $ */
+/* $OpenBSD: vfs_default.c,v 1.3 1998/08/06 19:34:24 csapuntz Exp $ */
/*
@@ -47,7 +47,8 @@
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/vnode.h>
-
+#include <sys/namei.h>
+#include <sys/malloc.h>
#include <miscfs/specfs/specdev.h>
@@ -58,7 +59,7 @@ extern struct simplelock spechash_slock;
* and with all vnodes aliased to the requested vnode.
*/
int
-vop_revoke(v)
+vop_generic_revoke(v)
void *v;
{
struct vop_revoke_args /* {
@@ -70,7 +71,7 @@ vop_revoke(v)
#ifdef DIAGNOSTIC
if ((ap->a_flags & REVOKEALL) == 0)
- panic("vop_revoke");
+ panic("vop_generic_revoke");
#endif
vp = ap->a_vp;
@@ -84,7 +85,7 @@ vop_revoke(v)
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
- tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
+ tsleep((caddr_t)vp, PINOD, "vop_generic_revokeall", 0);
return(0);
}
/*
@@ -118,7 +119,7 @@ vop_revoke(v)
int
-vn_bwrite(v)
+vop_generic_bwrite(v)
void *v;
{
struct vop_bwrite_args *ap = v;
@@ -126,6 +127,21 @@ vn_bwrite(v)
return (bwrite(ap->a_bp));
}
+
+int
+vop_generic_abortop(v)
+ void *v;
+{
+ struct vop_abortop_args /* {
+ struct vnode *a_dvp;
+ struct componentname *a_cnp;
+ } */ *ap = v;
+
+ if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
+ FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
+ return (0);
+}
+
/*
* Stubs to use when there is no locking to be done on the underlying object.
* A minimal shared lock is necessary to ensure that the underlying object
@@ -133,7 +149,7 @@ vn_bwrite(v)
* count is maintained in an auxillary vnode lock structure.
*/
int
-vop_nolock(v)
+vop_generic_lock(v)
void *v;
{
struct vop_lock_args /* {
@@ -181,7 +197,7 @@ vop_nolock(v)
return (0);
case LK_RELEASE:
default:
- panic("vop_nolock: bad operation %d", flags & LK_TYPE_MASK);
+ panic("vop_generic_lock: bad operation %d", flags & LK_TYPE_MASK);
}
if (flags & LK_INTERLOCK)
vnflags |= LK_INTERLOCK;
@@ -202,7 +218,7 @@ vop_nolock(v)
*/
int
-vop_nounlock(v)
+vop_generic_unlock(v)
void *v;
{
struct vop_unlock_args /* {
@@ -222,7 +238,7 @@ vop_nounlock(v)
* Return whether or not the node is in use.
*/
int
-vop_noislocked(v)
+vop_generic_islocked(v)
void *v;
{
struct vop_islocked_args /* {
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index cf94b1cb114..f991eb6f0ea 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.20 1998/04/25 07:04:11 niklas Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.21 1998/08/06 19:34:26 csapuntz Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -103,12 +103,12 @@ struct simplelock spechash_slock;
void insmntque __P((struct vnode *, struct mount *));
int getdevvp __P((dev_t, struct vnode **, enum vtype));
-int vunref __P((struct vnode *));
int vfs_hang_addrlist __P((struct mount *, struct netexport *,
struct export_args *));
int vfs_free_netcred __P((struct radix_node *, void *));
void vfs_free_addrlist __P((struct netexport *));
+static __inline__ void vputonfreelist __P((struct vnode *));
#ifdef DEBUG
void printlockedvnodes __P((void));
@@ -419,9 +419,10 @@ getnewvnode(tag, mp, vops, vpp)
vprint("free vnode", vp);
panic("free vnode isn't");
}
+
TAILQ_REMOVE(listhd, vp, v_freelist);
- /* see comment on why 0xdeadb is set at end of vgone (below) */
- vp->v_flag |= VGONEHACK;
+ vp->v_flag &= ~VONFREELIST;
+
simple_unlock(&vnode_free_list_slock);
vp->v_lease = NULL;
if (vp->v_type != VBAD)
@@ -643,18 +644,22 @@ vget(vp, flags, p)
tsleep((caddr_t)vp, PINOD, "vget", 0);
return (ENOENT);
}
- if (vp->v_usecount == 0) {
+ if ((vp->v_flag & VONFREELIST) && (vp->v_usecount == 0)) {
simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
else
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
simple_unlock(&vnode_free_list_slock);
+ vp->v_flag &= ~VONFREELIST;
}
vp->v_usecount++;
if (flags & LK_TYPE_MASK) {
if ((error = vn_lock(vp, flags | LK_INTERLOCK, p)) != 0) {
- vunref(vp);
+ vp->v_usecount--;
+ if (vp->v_usecount == 0)
+ vputonfreelist(vp);
+
simple_unlock(&vp->v_interlock);
}
return (error);
@@ -680,37 +685,34 @@ vref(vp)
}
#endif /* DIAGNOSTIC */
-int
-vunref(vp)
- struct vnode *vp;
+static __inline__ void
+vputonfreelist(vp)
+ struct vnode *vp;
+
{
-#ifdef DIAGNOSTIC
- if (vp == NULL)
- panic("vrele: null vp");
-#endif
- simple_lock (&vp->v_interlock);
- vp->v_usecount--;
- if (vp->v_usecount > 0) {
- simple_unlock(&vp->v_interlock);
- return (vp->v_usecount);
- }
-#ifdef DIAGNOSTIC
- if (vp->v_usecount < 0 || vp->v_writecount != 0) {
- vprint("vrele: bad ref count", vp);
- panic("vrele: ref cnt");
- }
-#endif
+ struct freelst *lst;
+
/*
* insert at tail of LRU list
*/
+
+ vp->v_flag |= VONFREELIST;
+
simple_lock(&vnode_free_list_slock);
- if (vp->v_holdcnt > 0)
- TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
+
+ if (vp->v_holdcnt > 0)
+ lst = &vnode_hold_list;
else
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
+ lst = &vnode_free_list;
+
+
+ if (vp->v_type == VBAD)
+ TAILQ_INSERT_HEAD(lst, vp, v_freelist);
+ else
+ TAILQ_INSERT_TAIL(lst, vp, v_freelist);
+
simple_unlock(&vnode_free_list_slock);
- return (0);
}
/*
@@ -722,7 +724,7 @@ vput(vp)
{
struct proc *p = curproc; /* XXX */
-#ifdef DIGANOSTIC
+#ifdef DIAGNOSTIC
if (vp == NULL)
panic("vput: null vp");
#endif
@@ -739,17 +741,12 @@ vput(vp)
panic("vput: ref cnt");
}
#endif
- /*
- * insert at tail of LRU list
- */
- simple_lock(&vnode_free_list_slock);
- if (vp->v_holdcnt > 0)
- TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
- else
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
- simple_unlock(&vp->v_interlock);
VOP_INACTIVE(vp, p);
+
+ if (vp->v_usecount == 0)
+ vputonfreelist(vp);
+
+ simple_unlock(&vp->v_interlock);
}
/*
@@ -760,11 +757,31 @@ void
vrele(vp)
register struct vnode *vp;
{
- struct proc *p = curproc;
+ struct proc *p = curproc; /* XXX */
- if (vunref(vp) == 0 &&
- vn_lock(vp, LK_EXCLUSIVE |LK_INTERLOCK, p) == 0)
+#ifdef DIAGNOSTIC
+ if (vp == NULL)
+ panic("vrele: null vp");
+#endif
+ simple_lock(&vp->v_interlock);
+ vp->v_usecount--;
+ if (vp->v_usecount > 0) {
+ simple_unlock(&vp->v_interlock);
+ return;
+ }
+#ifdef DIAGNOSTIC
+ if (vp->v_usecount < 0 || vp->v_writecount != 0) {
+ vprint("vrele: bad ref count", vp);
+ panic("vrele: ref cnt");
+ }
+#endif
+ if (vn_lock(vp, LK_EXCLUSIVE |LK_INTERLOCK, p) == 0)
VOP_INACTIVE(vp, p);
+
+ if (vp->v_usecount == 0)
+ vputonfreelist(vp);
+
+ simple_unlock(&vp->v_interlock);
}
#ifdef DIAGNOSTIC
@@ -779,16 +796,9 @@ vhold(vp)
/*
* If it is on the freelist and the hold count is currently
* zero, move it to the hold list.
- *
- * The VGONEHACK flag reflects a call from getnewvnode,
- * which will remove the vnode from the free list, but
- * will not increment the ref count until after it calls vgone
- * If the ref count we're incremented first, vgone would
- * (incorrectly) try to close the previous instance of the
- * underlying object.
*/
simple_lock(&vp->v_interlock);
- if (!(vp->v_flag & VGONEHACK) &&
+ if ((vp->v_flag & VONFREELIST) &&
vp->v_holdcnt == 0 && vp->v_usecount == 0) {
simple_lock(&vnode_free_list_slock);
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
@@ -814,10 +824,8 @@ holdrele(vp)
/*
* If it is on the holdlist and the hold count drops to
* zero, move it to the free list.
- *
- * See above for VGONEHACK
*/
- if (!(vp->v_flag & VGONEHACK) &&
+ if ((vp->v_flag & VONFREELIST) &&
vp->v_holdcnt == 0 && vp->v_usecount == 0) {
simple_lock(&vnode_free_list_slock);
TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
@@ -987,9 +995,13 @@ vclean(vp, flags, p)
if (VOP_RECLAIM(vp, p))
panic("vclean: cannot reclaim");
if (active) {
- if (vunref(vp) == 0 &&
- vp->v_holdcnt > 0)
- panic("vclean: not clean");
+ vp->v_usecount--;
+ if (vp->v_usecount == 0) {
+ if (vp->v_holdcnt > 0)
+ panic("vclean: not clean");
+ vputonfreelist(vp);
+ }
+
simple_unlock(&vp->v_interlock);
}
cache_purge(vp);
@@ -1121,21 +1133,20 @@ vgonel(vp, p)
/*
* If it is on the freelist and not already at the head,
* move it to the head of the list.
- *
- * See above about the VGONEHACK
*/
- if (vp->v_usecount == 0) {
- simple_lock(&vnode_free_list_slock);
+ vp->v_type = VBAD;
+
+ if ((vp->v_flag & VONFREELIST) &&
+ vp->v_usecount == 0) {
+ simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
panic("vgonel: not clean");
- if (!(vp->v_flag & VGONEHACK) &&
- TAILQ_FIRST(&vnode_free_list) != vp) {
- TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
- TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
- }
- simple_unlock(&vnode_free_list_slock);
+ if (TAILQ_FIRST(&vnode_free_list) != vp) {
+ TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
+ TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
+ }
+ simple_unlock(&vnode_free_list_slock);
}
- vp->v_type = VBAD;
}
/*
diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c
index f3eb30f0b4a..6225232e57a 100644
--- a/sys/kern/vfs_sync.c
+++ b/sys/kern/vfs_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_sync.c,v 1.3 1998/03/14 19:32:59 millert Exp $ */
+/* $OpenBSD: vfs_sync.c,v 1.4 1998/08/06 19:34:27 csapuntz Exp $ */
/*
@@ -208,10 +208,10 @@ sched_sync(p)
int sync_fsync __P((void *));
int sync_inactive __P((void *));
#define sync_reclaim nullop
-#define sync_lock vop_nolock
-#define sync_unlock vop_nounlock
+#define sync_lock vop_generic_lock
+#define sync_unlock vop_generic_unlock
int sync_print __P((void *));
-#define sync_islocked vop_noislocked
+#define sync_islocked vop_generic_islocked
int (**sync_vnodeop_p) __P((void *));
struct vnodeopv_entry_desc sync_vnodeop_entries[] = {
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index f900d77fc24..b0eb7368432 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_vnops.c,v 1.16 1998/07/28 00:13:04 millert Exp $ */
+/* $OpenBSD: vfs_vnops.c,v 1.17 1998/08/06 19:34:29 csapuntz Exp $ */
/* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */
/*
@@ -465,7 +465,7 @@ vn_lock(vp, flags, p)
tsleep((caddr_t)vp, PINOD, "vn_lock", 0);
error = ENOENT;
} else {
- error = VOP_LOCK(vp, flags | LK_INTERLOCK, p);
+ error = VOP_LOCK(vp, flags | LK_INTERLOCK | LK_CANRECURSE, p);
if (error == 0)
return (error);
}