diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-06 19:35:18 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-06 19:35:18 +0000 |
commit | 89fedd1a8d2624bae7d2310a83d39156079353b6 (patch) | |
tree | 85d9d00a998016639251d59ff97e2a4df0bfa685 /sys/kern | |
parent | 67f0f9ef8777688f212974c7fd984398c1827902 (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.c | 36 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 147 | ||||
-rw-r--r-- | sys/kern/vfs_sync.c | 8 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 4 |
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); } |