diff options
-rw-r--r-- | sys/kern/vfs_export.c | 75 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 20 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 8 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 75 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 20 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 4 |
6 files changed, 194 insertions, 8 deletions
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 4f3bc04..92a9edf 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.80 1997/03/05 04:54:54 davidg Exp $ + * $Id: vfs_subr.c,v 1.81 1997/04/01 13:05:34 bde Exp $ */ /* @@ -871,6 +871,73 @@ vget(vp, flags, p) * count is maintained in an auxillary vnode lock structure. */ int +vop_sharedlock(ap) + struct vop_lock_args /* { + struct vnode *a_vp; + int a_flags; + struct proc *a_p; + } */ *ap; +{ + /* + * This code cannot be used until all the non-locking filesystems + * (notably NFS) are converted to properly lock and release nodes. + * Also, certain vnode operations change the locking state within + * the operation (create, mknod, remove, link, rename, mkdir, rmdir, + * and symlink). Ideally these operations should not change the + * lock state, but should be changed to let the caller of the + * function unlock them. Otherwise all intermediate vnode layers + * (such as union, umapfs, etc) must catch these functions to do + * the necessary locking at their layer. Note that the inactive + * and lookup operations also change their lock state, but this + * cannot be avoided, so these two operations will always need + * to be handled in intermediate layers. + */ + struct vnode *vp = ap->a_vp; + int vnflags, flags = ap->a_flags; + + if (vp->v_vnlock == NULL) { + if ((flags & LK_TYPE_MASK) == LK_DRAIN) + return (0); + MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock), + M_VNODE, M_WAITOK); + lockinit(vp->v_vnlock, PVFS, "vnlock", 0, 0); + } + switch (flags & LK_TYPE_MASK) { + case LK_DRAIN: + vnflags = LK_DRAIN; + break; + case LK_EXCLUSIVE: +#ifdef DEBUG_VFS_LOCKS + /* + * Normally, we use shared locks here, but that confuses + * the locking assertions. + */ + vnflags = LK_EXCLUSIVE; + break; +#endif + case LK_SHARED: + vnflags = LK_SHARED; + break; + case LK_UPGRADE: + case LK_EXCLUPGRADE: + case LK_DOWNGRADE: + return (0); + case LK_RELEASE: + default: + panic("vop_nolock: bad operation %d", flags & LK_TYPE_MASK); + } + if (flags & LK_INTERLOCK) + vnflags |= LK_INTERLOCK; + return(lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p)); +} + +/* + * 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 + * is not revoked while an operation is in progress. So, an active shared + * count is maintained in an auxillary vnode lock structure. + */ +int vop_nolock(ap) struct vop_lock_args /* { struct vnode *a_vp; @@ -1291,8 +1358,10 @@ vclean(struct vnode *vp, int flags, struct proc *p) vrele(vp); cache_purge(vp); if (vp->v_vnlock) { +#ifdef DIAGNOSTIC if ((vp->v_vnlock->lk_flags & LK_DRAINED) == 0) vprint("vclean: lock not drained", vp); +#endif FREE(vp->v_vnlock, M_VNODE); vp->v_vnlock = NULL; } @@ -1581,7 +1650,9 @@ vprint(label, vp) char buf[64]; if (label != NULL) - printf("%s: ", label); + printf("%s: %x: ", label, vp); + else + printf("%x: ", vp); printf("type %s, usecount %d, writecount %d, refcount %ld,", typename[vp->v_type], vp->v_usecount, vp->v_writecount, vp->v_holdcnt); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index d97f1ca..6c27097 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.62 1997/03/31 12:02:42 peter Exp $ + * $Id: vfs_syscalls.c,v 1.63 1997/03/31 12:21:37 peter Exp $ */ /* @@ -1028,6 +1028,8 @@ mknod(p, uap, retval) if (vp) vrele(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); return (error); } @@ -1124,6 +1126,8 @@ link(p, uap, retval) } } vrele(vp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); return (error); } @@ -1171,6 +1175,8 @@ symlink(p, uap, retval) vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); out: FREE(path, M_NAMEI); return (error); @@ -1212,6 +1218,8 @@ undelete(p, uap, retval) if (error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); vput(nd.ni_dvp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); return (error); } @@ -1269,6 +1277,8 @@ unlink(p, uap, retval) if (vp != NULLVP) vput(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); return (error); } @@ -2272,6 +2282,10 @@ out: vrele(fvp); } vrele(tond.ni_startdir); + ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); + ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI); out1: if (fromnd.ni_startdir) @@ -2327,6 +2341,8 @@ mkdir(p, uap, retval) error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (!error) vput(nd.ni_vp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); return (error); } @@ -2385,6 +2401,8 @@ out: vput(nd.ni_dvp); vput(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); return (error); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 0c04b01..72da093 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94 - * $Id$ + * $Id: vfs_lookup.c,v 1.16 1997/02/22 09:39:33 peter Exp $ */ #include "opt_ktrace.h" @@ -409,6 +409,7 @@ dirloop: unionlookup: ndp->ni_dvp = dp; ndp->ni_vp = NULL; + ASSERT_VOP_LOCKED(dp, "lookup"); if (error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) { #ifdef DIAGNOSTIC if (ndp->ni_vp != NULL) @@ -458,6 +459,8 @@ unionlookup: printf("found\n"); #endif + ASSERT_VOP_LOCKED(ndp->ni_vp, "lookup"); + /* * Take into account any additional components consumed by * the underlying filesystem. @@ -516,6 +519,9 @@ nextname: cnp->cn_nameptr++; ndp->ni_pathlen--; } + if (ndp->ni_dvp != ndp->ni_vp) { + ASSERT_VOP_UNLOCKED(ndp->ni_dvp, "lookup"); + } vrele(ndp->ni_dvp); goto dirloop; } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 4f3bc04..92a9edf 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.80 1997/03/05 04:54:54 davidg Exp $ + * $Id: vfs_subr.c,v 1.81 1997/04/01 13:05:34 bde Exp $ */ /* @@ -871,6 +871,73 @@ vget(vp, flags, p) * count is maintained in an auxillary vnode lock structure. */ int +vop_sharedlock(ap) + struct vop_lock_args /* { + struct vnode *a_vp; + int a_flags; + struct proc *a_p; + } */ *ap; +{ + /* + * This code cannot be used until all the non-locking filesystems + * (notably NFS) are converted to properly lock and release nodes. + * Also, certain vnode operations change the locking state within + * the operation (create, mknod, remove, link, rename, mkdir, rmdir, + * and symlink). Ideally these operations should not change the + * lock state, but should be changed to let the caller of the + * function unlock them. Otherwise all intermediate vnode layers + * (such as union, umapfs, etc) must catch these functions to do + * the necessary locking at their layer. Note that the inactive + * and lookup operations also change their lock state, but this + * cannot be avoided, so these two operations will always need + * to be handled in intermediate layers. + */ + struct vnode *vp = ap->a_vp; + int vnflags, flags = ap->a_flags; + + if (vp->v_vnlock == NULL) { + if ((flags & LK_TYPE_MASK) == LK_DRAIN) + return (0); + MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock), + M_VNODE, M_WAITOK); + lockinit(vp->v_vnlock, PVFS, "vnlock", 0, 0); + } + switch (flags & LK_TYPE_MASK) { + case LK_DRAIN: + vnflags = LK_DRAIN; + break; + case LK_EXCLUSIVE: +#ifdef DEBUG_VFS_LOCKS + /* + * Normally, we use shared locks here, but that confuses + * the locking assertions. + */ + vnflags = LK_EXCLUSIVE; + break; +#endif + case LK_SHARED: + vnflags = LK_SHARED; + break; + case LK_UPGRADE: + case LK_EXCLUPGRADE: + case LK_DOWNGRADE: + return (0); + case LK_RELEASE: + default: + panic("vop_nolock: bad operation %d", flags & LK_TYPE_MASK); + } + if (flags & LK_INTERLOCK) + vnflags |= LK_INTERLOCK; + return(lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p)); +} + +/* + * 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 + * is not revoked while an operation is in progress. So, an active shared + * count is maintained in an auxillary vnode lock structure. + */ +int vop_nolock(ap) struct vop_lock_args /* { struct vnode *a_vp; @@ -1291,8 +1358,10 @@ vclean(struct vnode *vp, int flags, struct proc *p) vrele(vp); cache_purge(vp); if (vp->v_vnlock) { +#ifdef DIAGNOSTIC if ((vp->v_vnlock->lk_flags & LK_DRAINED) == 0) vprint("vclean: lock not drained", vp); +#endif FREE(vp->v_vnlock, M_VNODE); vp->v_vnlock = NULL; } @@ -1581,7 +1650,9 @@ vprint(label, vp) char buf[64]; if (label != NULL) - printf("%s: ", label); + printf("%s: %x: ", label, vp); + else + printf("%x: ", vp); printf("type %s, usecount %d, writecount %d, refcount %ld,", typename[vp->v_type], vp->v_usecount, vp->v_writecount, vp->v_holdcnt); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index d97f1ca..6c27097 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.62 1997/03/31 12:02:42 peter Exp $ + * $Id: vfs_syscalls.c,v 1.63 1997/03/31 12:21:37 peter Exp $ */ /* @@ -1028,6 +1028,8 @@ mknod(p, uap, retval) if (vp) vrele(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); return (error); } @@ -1124,6 +1126,8 @@ link(p, uap, retval) } } vrele(vp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); return (error); } @@ -1171,6 +1175,8 @@ symlink(p, uap, retval) vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); out: FREE(path, M_NAMEI); return (error); @@ -1212,6 +1218,8 @@ undelete(p, uap, retval) if (error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); vput(nd.ni_dvp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); return (error); } @@ -1269,6 +1277,8 @@ unlink(p, uap, retval) if (vp != NULLVP) vput(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); return (error); } @@ -2272,6 +2282,10 @@ out: vrele(fvp); } vrele(tond.ni_startdir); + ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); + ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI); out1: if (fromnd.ni_startdir) @@ -2327,6 +2341,8 @@ mkdir(p, uap, retval) error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (!error) vput(nd.ni_vp); + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); return (error); } @@ -2385,6 +2401,8 @@ out: vput(nd.ni_dvp); vput(vp); } + ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); + ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); return (error); } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index cb6c932..6a3fca6 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 - * $Id: vfs_vnops.c,v 1.33 1997/03/23 03:36:38 bde Exp $ + * $Id: vfs_vnops.c,v 1.34 1997/03/24 11:52:27 bde Exp $ */ #include <sys/param.h> @@ -104,6 +104,8 @@ vn_open(ndp, fmode, cmode) if (error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, vap)) return (error); + ASSERT_VOP_UNLOCKED(ndp->ni_dvp, "create"); + ASSERT_VOP_LOCKED(ndp->ni_vp, "create"); fmode &= ~O_TRUNC; vp = ndp->ni_vp; } else { |