summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreivind <eivind@FreeBSD.org>1999-12-11 16:13:02 +0000
committereivind <eivind@FreeBSD.org>1999-12-11 16:13:02 +0000
commit287836faea1ff2f002f4c9ea357e87cb7f2b4cd6 (patch)
tree9524fb381c1cbe8aed4ee0af7b1a693057985617
parentff090abf5121f6bf2199248b70a4896d25f49550 (diff)
downloadFreeBSD-src-287836faea1ff2f002f4c9ea357e87cb7f2b4cd6.zip
FreeBSD-src-287836faea1ff2f002f4c9ea357e87cb7f2b4cd6.tar.gz
Lock reporting and assertion changes.
* lockstatus() and VOP_ISLOCKED() gets a new process argument and a new return value: LK_EXCLOTHER, when the lock is held exclusively by another process. * The ASSERT_VOP_(UN)LOCKED family is extended to use what this gives them * Extend the vnode_if.src format to allow more exact specification than locked/unlocked. This commit should not do any semantic changes unless you are using DEBUG_VFS_LOCKS. Discussed with: grog, mch, peter, phk Reviewed by: peter
-rw-r--r--sys/coda/coda_vnops.c2
-rw-r--r--sys/contrib/softupdates/ffs_softdep.c2
-rw-r--r--sys/dev/vn/vn.c2
-rw-r--r--sys/fs/coda/coda_vnops.c2
-rw-r--r--sys/fs/nullfs/null_vfsops.c6
-rw-r--r--sys/fs/nullfs/null_vnops.c4
-rw-r--r--sys/fs/nwfs/nwfs_vfsops.c2
-rw-r--r--sys/fs/unionfs/union_vfsops.c9
-rw-r--r--sys/fs/unionfs/union_vnops.c8
-rw-r--r--sys/kern/kern_lock.c12
-rw-r--r--sys/kern/vfs_default.c6
-rw-r--r--sys/kern/vfs_export.c6
-rw-r--r--sys/kern/vfs_subr.c6
-rw-r--r--sys/kern/vnode_if.src7
-rw-r--r--sys/miscfs/devfs/devfs_vfsops.c2
-rw-r--r--sys/miscfs/nullfs/null_vfsops.c6
-rw-r--r--sys/miscfs/nullfs/null_vnops.c4
-rw-r--r--sys/miscfs/union/union_vfsops.c9
-rw-r--r--sys/miscfs/union/union_vnops.c8
-rw-r--r--sys/nfs/nfs_node.c1
-rw-r--r--sys/nfs/nfs_vfsops.c2
-rw-r--r--sys/nfsclient/nfs_node.c1
-rw-r--r--sys/nfsclient/nfs_vfsops.c2
-rw-r--r--sys/nwfs/nwfs_vfsops.c2
-rw-r--r--sys/sys/lock.h5
-rw-r--r--sys/sys/lockmgr.h5
-rw-r--r--sys/sys/vnode.h59
-rw-r--r--sys/ufs/ffs/ffs_softdep.c2
-rw-r--r--sys/vm/vm_pageout.c2
-rw-r--r--sys/vm/vm_zone.c2
30 files changed, 126 insertions, 60 deletions
diff --git a/sys/coda/coda_vnops.c b/sys/coda/coda_vnops.c
index 5f86c09..1ef09bc 100644
--- a/sys/coda/coda_vnops.c
+++ b/sys/coda/coda_vnops.c
@@ -1865,7 +1865,7 @@ coda_islocked(v)
struct cnode *cp = VTOC(ap->a_vp);
ENTRY;
- return (lockstatus(&cp->c_lock));
+ return (lockstatus(&cp->c_lock, ap->a_p));
}
/* How one looks up a vnode given a device/inode pair: */
diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c
index 79a1aee..a0252d2 100644
--- a/sys/contrib/softupdates/ffs_softdep.c
+++ b/sys/contrib/softupdates/ffs_softdep.c
@@ -3978,7 +3978,7 @@ loop:
* way to accomplish this is to sync the entire filesystem (luckily
* this happens rarely).
*/
- if (vn_isdisk(vp) && vp->v_specmountpoint && !VOP_ISLOCKED(vp) &&
+ if (vn_isdisk(vp) && vp->v_specmountpoint && !VOP_ISLOCKED(vp, NULL) &&
(error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT, ap->a_cred,
ap->a_p)) != 0)
return (error);
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c
index 0730696..0c16450 100644
--- a/sys/dev/vn/vn.c
+++ b/sys/dev/vn/vn.c
@@ -362,7 +362,7 @@ vnstrategy(struct buf *bp)
auio.uio_rw = UIO_WRITE;
auio.uio_resid = bp->b_bcount;
auio.uio_procp = curproc;
- if (!VOP_ISLOCKED(vn->sc_vp)) {
+ if (!VOP_ISLOCKED(vn->sc_vp, NULL)) {
isvplocked = 1;
vn_lock(vn->sc_vp, LK_EXCLUSIVE | LK_RETRY, curproc);
}
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index 5f86c09..1ef09bc 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -1865,7 +1865,7 @@ coda_islocked(v)
struct cnode *cp = VTOC(ap->a_vp);
ENTRY;
- return (lockstatus(&cp->c_lock));
+ return (lockstatus(&cp->c_lock, ap->a_p));
}
/* How one looks up a vnode given a device/inode pair: */
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index 06e1be0..e48a516 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -119,7 +119,7 @@ nullfs_mount(mp, path, data, ndp, p)
* (XXX) VOP_ISLOCKED is needed?
*/
if ((mp->mnt_vnodecovered->v_op == null_vnodeop_p) &&
- VOP_ISLOCKED(mp->mnt_vnodecovered)) {
+ VOP_ISLOCKED(mp->mnt_vnodecovered, NULL)) {
VOP_UNLOCK(mp->mnt_vnodecovered, 0, p);
isvnunlocked = 1;
}
@@ -132,7 +132,7 @@ nullfs_mount(mp, path, data, ndp, p)
/*
* Re-lock vnode.
*/
- if (isvnunlocked && !VOP_ISLOCKED(mp->mnt_vnodecovered))
+ if (isvnunlocked && !VOP_ISLOCKED(mp->mnt_vnodecovered, NULL))
vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
@@ -296,7 +296,7 @@ nullfs_root(mp, vpp)
*/
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
VREF(vp);
- if (VOP_ISLOCKED(vp)) {
+ if (VOP_ISLOCKED(vp, NULL)) {
/*
* XXX
* Should we check type of node?
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index 225ac09..9600f3c 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -372,13 +372,13 @@ null_lookup(ap)
vp = *ap->a_vpp;
if (dvp == vp)
return (error);
- if (!VOP_ISLOCKED(dvp)) {
+ if (!VOP_ISLOCKED(dvp, NULL)) {
unlockargs.a_vp = dvp;
unlockargs.a_flags = 0;
unlockargs.a_p = p;
vop_nounlock(&unlockargs);
}
- if (vp != NULLVP && VOP_ISLOCKED(vp)) {
+ if (vp != NULLVP && VOP_ISLOCKED(vp, NULL)) {
lockargs.a_vp = vp;
lockargs.a_flags = LK_SHARED;
lockargs.a_p = p;
diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c
index d9e5f57..f99bba7 100644
--- a/sys/fs/nwfs/nwfs_vfsops.c
+++ b/sys/fs/nwfs/nwfs_vfsops.c
@@ -498,7 +498,7 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- if (VOP_ISLOCKED(vp) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
+ if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
waitfor == MNT_LAZY)
continue;
if (vget(vp, LK_EXCLUSIVE, p))
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index 1a53f88..ccd9a13 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -148,7 +148,8 @@ union_mount(mp, path, data, ndp, p)
vrele(ndp->ni_dvp);
ndp->ni_dvp = NULL;
- UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp, VOP_ISLOCKED(upperrootvp)));
+ UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp,
+ VOP_ISLOCKED(upperrootvp, NULL)));
/*
* Check multi union mount to avoid `lock myself again' panic.
@@ -396,7 +397,8 @@ union_root(mp, vpp)
* root union_node being locked. We let union_allocvp() deal with
* it.
*/
- UDEBUG(("union_root UPPERVP %p locked = %d\n", um->um_uppervp, VOP_ISLOCKED(um->um_uppervp)));
+ UDEBUG(("union_root UPPERVP %p locked = %d\n", um->um_uppervp,
+ VOP_ISLOCKED(um->um_uppervp, NULL)));
VREF(um->um_uppervp);
if (um->um_lowervp)
@@ -405,7 +407,8 @@ union_root(mp, vpp)
error = union_allocvp(vpp, mp, NULLVP, NULLVP, NULL,
um->um_uppervp, um->um_lowervp, 1);
UDEBUG(("error %d\n", error));
- UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp, VOP_ISLOCKED(um->um_uppervp)));
+ UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp,
+ VOP_ISLOCKED(um->um_uppervp, NULL)));
return (error);
}
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index 08763ce..5ab1036 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -363,10 +363,10 @@ union_lookup(ap)
uerror,
upperdvp,
upperdvp->v_usecount,
- VOP_ISLOCKED(upperdvp),
+ VOP_ISLOCKED(upperdvp, NULL),
uppervp,
(uppervp ? uppervp->v_usecount : -99),
- (uppervp ? VOP_ISLOCKED(uppervp) : -99)
+ (uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99)
));
/*
@@ -1698,7 +1698,7 @@ union_abortop(ap)
struct componentname *cnp = ap->a_cnp;
struct proc *p = cnp->cn_proc;
struct union_node *un = VTOUNION(ap->a_dvp);
- int islocked = VOP_ISLOCKED(ap->a_dvp);
+ int islocked = VOP_ISLOCKED(ap->a_dvp, NULL);
struct vnode *vp;
int error;
@@ -1850,7 +1850,7 @@ union_unlock(ap)
*/
if ((un->un_flags & UN_ULOCK) &&
- lockstatus(&un->un_lock) != LK_EXCLUSIVE) {
+ lockstatus(&un->un_lock, NULL) != LK_EXCLUSIVE) {
un->un_flags &= ~UN_ULOCK;
VOP_UNLOCK(un->un_uppervp, LK_EXCLUSIVE, p);
}
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index d80561d..b47ca55 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -511,15 +511,19 @@ lockinit(lkp, prio, wmesg, timo, flags)
* Determine the status of a lock.
*/
int
-lockstatus(lkp)
+lockstatus(lkp, p)
struct lock *lkp;
+ struct proc *p;
{
int lock_type = 0;
simple_lock(&lkp->lk_interlock);
- if (lkp->lk_exclusivecount != 0)
- lock_type = LK_EXCLUSIVE;
- else if (lkp->lk_sharecount != 0)
+ if (lkp->lk_exclusivecount != 0) {
+ if (p == NULL || lkp->lk_lockholder == p->p_pid)
+ lock_type = LK_EXCLUSIVE;
+ else
+ lock_type = LK_EXCLOTHER;
+ } else if (lkp->lk_sharecount != 0)
lock_type = LK_SHARED;
simple_unlock(&lkp->lk_interlock);
return (lock_type);
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index fe5d94d..600df41 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -255,6 +255,7 @@ int
vop_stdislocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
struct lock *l;
@@ -262,7 +263,7 @@ vop_stdislocked(ap)
if ((l = (struct lock *)ap->a_vp->v_data) == NULL)
return 0;
- return (lockstatus(l));
+ return (lockstatus(l, ap->a_p));
}
/*
@@ -484,13 +485,14 @@ int
vop_noislocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
if (vp->v_vnlock == NULL)
return (0);
- return (lockstatus(vp->v_vnlock));
+ return (lockstatus(vp->v_vnlock, ap->a_p));
}
/*
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index a19c3d2..1f6b7a4 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -990,7 +990,7 @@ sched_sync(void)
splx(s);
while ((vp = LIST_FIRST(slp)) != NULL) {
- if (VOP_ISLOCKED(vp) == 0) {
+ if (VOP_ISLOCKED(vp, NULL) == 0) {
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
VOP_UNLOCK(vp, 0, p);
@@ -1962,7 +1962,7 @@ DB_SHOW_COMMAND(lockedvnodes, lockedvnodes)
continue;
}
LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
- if (VOP_ISLOCKED(vp))
+ if (VOP_ISLOCKED(vp, NULL))
vprint((char *)0, vp);
}
simple_lock(&mountlist_slock);
@@ -2450,7 +2450,7 @@ loop:
obj = vp->v_object;
if (obj == NULL || (obj->flags & OBJ_MIGHTBEDIRTY) == 0)
continue;
- if (VOP_ISLOCKED(vp))
+ if (VOP_ISLOCKED(vp, NULL))
continue;
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index a19c3d2..1f6b7a4 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -990,7 +990,7 @@ sched_sync(void)
splx(s);
while ((vp = LIST_FIRST(slp)) != NULL) {
- if (VOP_ISLOCKED(vp) == 0) {
+ if (VOP_ISLOCKED(vp, NULL) == 0) {
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
VOP_UNLOCK(vp, 0, p);
@@ -1962,7 +1962,7 @@ DB_SHOW_COMMAND(lockedvnodes, lockedvnodes)
continue;
}
LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
- if (VOP_ISLOCKED(vp))
+ if (VOP_ISLOCKED(vp, NULL))
vprint((char *)0, vp);
}
simple_lock(&mountlist_slock);
@@ -2450,7 +2450,7 @@ loop:
obj = vp->v_object;
if (obj == NULL || (obj->flags & OBJ_MIGHTBEDIRTY) == 0)
continue;
- if (VOP_ISLOCKED(vp))
+ if (VOP_ISLOCKED(vp, NULL))
continue;
}
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 2b16704..c418164 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -43,7 +43,11 @@
# "error" column defines the locking state on error exit.
#
# The locking value can take the following values:
-# L: locked.
+# L: locked; not converted to type of lock.
+# A: any lock type.
+# S: locked with shared lock.
+# E: locked with exclusive lock for this process.
+# O: locked with exclusive lock for other process.
# U: unlocked.
# -: not applicable. vnode does not yet (or no longer) exists.
# =: the same on input and output, may be either L or U.
@@ -55,6 +59,7 @@
#
vop_islocked {
IN struct vnode *vp;
+ IN struct proc *p;
};
#
diff --git a/sys/miscfs/devfs/devfs_vfsops.c b/sys/miscfs/devfs/devfs_vfsops.c
index 287ca99..73f7d70 100644
--- a/sys/miscfs/devfs/devfs_vfsops.c
+++ b/sys/miscfs/devfs/devfs_vfsops.c
@@ -264,7 +264,7 @@ loop:
if (vp->v_mount != mp)
goto loop;
nvp = vp->v_mntvnodes.le_next;
- if (VOP_ISLOCKED(vp))
+ if (VOP_ISLOCKED(vp, NULL))
continue;
if (TAILQ_EMPTY(&vp->v_dirtyblkhd))
continue;
diff --git a/sys/miscfs/nullfs/null_vfsops.c b/sys/miscfs/nullfs/null_vfsops.c
index 06e1be0..e48a516 100644
--- a/sys/miscfs/nullfs/null_vfsops.c
+++ b/sys/miscfs/nullfs/null_vfsops.c
@@ -119,7 +119,7 @@ nullfs_mount(mp, path, data, ndp, p)
* (XXX) VOP_ISLOCKED is needed?
*/
if ((mp->mnt_vnodecovered->v_op == null_vnodeop_p) &&
- VOP_ISLOCKED(mp->mnt_vnodecovered)) {
+ VOP_ISLOCKED(mp->mnt_vnodecovered, NULL)) {
VOP_UNLOCK(mp->mnt_vnodecovered, 0, p);
isvnunlocked = 1;
}
@@ -132,7 +132,7 @@ nullfs_mount(mp, path, data, ndp, p)
/*
* Re-lock vnode.
*/
- if (isvnunlocked && !VOP_ISLOCKED(mp->mnt_vnodecovered))
+ if (isvnunlocked && !VOP_ISLOCKED(mp->mnt_vnodecovered, NULL))
vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
@@ -296,7 +296,7 @@ nullfs_root(mp, vpp)
*/
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
VREF(vp);
- if (VOP_ISLOCKED(vp)) {
+ if (VOP_ISLOCKED(vp, NULL)) {
/*
* XXX
* Should we check type of node?
diff --git a/sys/miscfs/nullfs/null_vnops.c b/sys/miscfs/nullfs/null_vnops.c
index 225ac09..9600f3c 100644
--- a/sys/miscfs/nullfs/null_vnops.c
+++ b/sys/miscfs/nullfs/null_vnops.c
@@ -372,13 +372,13 @@ null_lookup(ap)
vp = *ap->a_vpp;
if (dvp == vp)
return (error);
- if (!VOP_ISLOCKED(dvp)) {
+ if (!VOP_ISLOCKED(dvp, NULL)) {
unlockargs.a_vp = dvp;
unlockargs.a_flags = 0;
unlockargs.a_p = p;
vop_nounlock(&unlockargs);
}
- if (vp != NULLVP && VOP_ISLOCKED(vp)) {
+ if (vp != NULLVP && VOP_ISLOCKED(vp, NULL)) {
lockargs.a_vp = vp;
lockargs.a_flags = LK_SHARED;
lockargs.a_p = p;
diff --git a/sys/miscfs/union/union_vfsops.c b/sys/miscfs/union/union_vfsops.c
index 1a53f88..ccd9a13 100644
--- a/sys/miscfs/union/union_vfsops.c
+++ b/sys/miscfs/union/union_vfsops.c
@@ -148,7 +148,8 @@ union_mount(mp, path, data, ndp, p)
vrele(ndp->ni_dvp);
ndp->ni_dvp = NULL;
- UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp, VOP_ISLOCKED(upperrootvp)));
+ UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp,
+ VOP_ISLOCKED(upperrootvp, NULL)));
/*
* Check multi union mount to avoid `lock myself again' panic.
@@ -396,7 +397,8 @@ union_root(mp, vpp)
* root union_node being locked. We let union_allocvp() deal with
* it.
*/
- UDEBUG(("union_root UPPERVP %p locked = %d\n", um->um_uppervp, VOP_ISLOCKED(um->um_uppervp)));
+ UDEBUG(("union_root UPPERVP %p locked = %d\n", um->um_uppervp,
+ VOP_ISLOCKED(um->um_uppervp, NULL)));
VREF(um->um_uppervp);
if (um->um_lowervp)
@@ -405,7 +407,8 @@ union_root(mp, vpp)
error = union_allocvp(vpp, mp, NULLVP, NULLVP, NULL,
um->um_uppervp, um->um_lowervp, 1);
UDEBUG(("error %d\n", error));
- UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp, VOP_ISLOCKED(um->um_uppervp)));
+ UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp,
+ VOP_ISLOCKED(um->um_uppervp, NULL)));
return (error);
}
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c
index 08763ce..5ab1036 100644
--- a/sys/miscfs/union/union_vnops.c
+++ b/sys/miscfs/union/union_vnops.c
@@ -363,10 +363,10 @@ union_lookup(ap)
uerror,
upperdvp,
upperdvp->v_usecount,
- VOP_ISLOCKED(upperdvp),
+ VOP_ISLOCKED(upperdvp, NULL),
uppervp,
(uppervp ? uppervp->v_usecount : -99),
- (uppervp ? VOP_ISLOCKED(uppervp) : -99)
+ (uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99)
));
/*
@@ -1698,7 +1698,7 @@ union_abortop(ap)
struct componentname *cnp = ap->a_cnp;
struct proc *p = cnp->cn_proc;
struct union_node *un = VTOUNION(ap->a_dvp);
- int islocked = VOP_ISLOCKED(ap->a_dvp);
+ int islocked = VOP_ISLOCKED(ap->a_dvp, NULL);
struct vnode *vp;
int error;
@@ -1850,7 +1850,7 @@ union_unlock(ap)
*/
if ((un->un_flags & UN_ULOCK) &&
- lockstatus(&un->un_lock) != LK_EXCLUSIVE) {
+ lockstatus(&un->un_lock, NULL) != LK_EXCLUSIVE) {
un->un_flags &= ~UN_ULOCK;
VOP_UNLOCK(un->un_uppervp, LK_EXCLUSIVE, p);
}
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c
index 13ff9b2..53c73a1 100644
--- a/sys/nfs/nfs_node.c
+++ b/sys/nfs/nfs_node.c
@@ -380,6 +380,7 @@ int
nfs_islocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
return VTONFS(ap->a_vp)->n_flag & NLOCKED ? 1 : 0;
diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c
index dc9e053..8a0c368 100644
--- a/sys/nfs/nfs_vfsops.c
+++ b/sys/nfs/nfs_vfsops.c
@@ -1062,7 +1062,7 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- if (VOP_ISLOCKED(vp) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
+ if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
waitfor == MNT_LAZY)
continue;
if (vget(vp, LK_EXCLUSIVE, p))
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 13ff9b2..53c73a1 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -380,6 +380,7 @@ int
nfs_islocked(ap)
struct vop_islocked_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
return VTONFS(ap->a_vp)->n_flag & NLOCKED ? 1 : 0;
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index dc9e053..8a0c368 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -1062,7 +1062,7 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- if (VOP_ISLOCKED(vp) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
+ if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
waitfor == MNT_LAZY)
continue;
if (vget(vp, LK_EXCLUSIVE, p))
diff --git a/sys/nwfs/nwfs_vfsops.c b/sys/nwfs/nwfs_vfsops.c
index d9e5f57..f99bba7 100644
--- a/sys/nwfs/nwfs_vfsops.c
+++ b/sys/nwfs/nwfs_vfsops.c
@@ -498,7 +498,7 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- if (VOP_ISLOCKED(vp) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
+ if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
waitfor == MNT_LAZY)
continue;
if (vget(vp, LK_EXCLUSIVE, p))
diff --git a/sys/sys/lock.h b/sys/sys/lock.h
index 04157c0..57b8b05 100644
--- a/sys/sys/lock.h
+++ b/sys/sys/lock.h
@@ -95,6 +95,8 @@ struct lock {
* LK_DRAIN - wait for all activity on the lock to end, then mark it
* decommissioned. This feature is used before freeing a lock that
* is part of a piece of memory that is about to be freed.
+ * LK_EXCLOTHER - return for lockstatus(). Used when another process
+ * holds the lock exclusively.
*
* These are flags that are passed to the lockmgr routine.
*/
@@ -106,6 +108,7 @@ struct lock {
#define LK_DOWNGRADE 0x00000005 /* exclusive-to-shared downgrade */
#define LK_RELEASE 0x00000006 /* release any type of lock */
#define LK_DRAIN 0x00000007 /* wait for all lock activity to end */
+#define LK_EXCLOTHER 0x00000008 /* other process holds lock */
/*
* External lock flags.
*
@@ -187,7 +190,7 @@ int lockmgr __P((struct lock *, u_int flags,
struct simplelock *, struct proc *p));
#endif
void lockmgr_printinfo __P((struct lock *));
-int lockstatus __P((struct lock *));
+int lockstatus __P((struct lock *, struct proc *));
int lockcount __P((struct lock *));
#ifdef SIMPLELOCK_DEBUG
diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h
index 04157c0..57b8b05 100644
--- a/sys/sys/lockmgr.h
+++ b/sys/sys/lockmgr.h
@@ -95,6 +95,8 @@ struct lock {
* LK_DRAIN - wait for all activity on the lock to end, then mark it
* decommissioned. This feature is used before freeing a lock that
* is part of a piece of memory that is about to be freed.
+ * LK_EXCLOTHER - return for lockstatus(). Used when another process
+ * holds the lock exclusively.
*
* These are flags that are passed to the lockmgr routine.
*/
@@ -106,6 +108,7 @@ struct lock {
#define LK_DOWNGRADE 0x00000005 /* exclusive-to-shared downgrade */
#define LK_RELEASE 0x00000006 /* release any type of lock */
#define LK_DRAIN 0x00000007 /* wait for all lock activity to end */
+#define LK_EXCLOTHER 0x00000008 /* other process holds lock */
/*
* External lock flags.
*
@@ -187,7 +190,7 @@ int lockmgr __P((struct lock *, u_int flags,
struct simplelock *, struct proc *p));
#endif
void lockmgr_printinfo __P((struct lock *));
-int lockstatus __P((struct lock *));
+int lockstatus __P((struct lock *, struct proc *));
int lockcount __P((struct lock *));
#ifdef SIMPLELOCK_DEBUG
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 86e8fd5..366c2d5 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -421,15 +421,56 @@ struct vop_generic_args {
|| (vp)->v_tag == VT_MSDOSFS \
|| (vp)->v_tag == VT_DEVFS)
-#define ASSERT_VOP_LOCKED(vp, str) \
- if ((vp) && IS_LOCKING_VFS(vp) && !VOP_ISLOCKED(vp)) { \
- panic("%s: %p is not locked but should be", str, vp); \
- }
-
-#define ASSERT_VOP_UNLOCKED(vp, str) \
- if ((vp) && IS_LOCKING_VFS(vp) && VOP_ISLOCKED(vp)) { \
- panic("%s: %p is locked but shouldn't be", str, vp); \
- }
+#define ASSERT_VOP_LOCKED(vp, str) \
+do { \
+ struct vnode *_vp = (vp); \
+ \
+ if (_vp && IS_LOCKING_VFS(_vp) && !VOP_ISLOCKED(_vp, NULL)) \
+ panic("%s: %p is not locked but should be", str, _vp); \
+} while (0)
+
+#define ASSERT_VOP_UNLOCKED(vp, str) \
+do { \
+ struct vnode *_vp = (vp); \
+ int lockstate; \
+ \
+ if (_vp && IS_LOCKING_VFS(_vp)) { \
+ lockstate = VOP_ISLOCKED(_vp, curproc); \
+ if (lockstate == LK_EXCLUSIVE) \
+ panic("%s: %p is locked but should not be", \
+ str, _vp); \
+ } \
+} while (0)
+
+#define ASSERT_VOP_ELOCKED(vp, str) \
+do { \
+ struct vnode *_vp = (vp); \
+ \
+ if (_vp && IS_LOCKING_VFS(_vp) && \
+ VOP_ISLOCKED(_vp, curproc) != LK_EXCLUSIVE) \
+ panic("%s: %p is not exclusive locked but should be", \
+ str, _vp); \
+} while (0)
+
+#define ASSERT_VOP_ELOCKED_OTHER(vp, str) \
+do { \
+ struct vnode *_vp = (vp); \
+ \
+ if (_vp && IS_LOCKING_VFS(_vp) && \
+ VOP_ISLOCKED(_vp, curproc) != LK_EXCLOTHER) \
+ panic("%s: %p is not exclusive locked by another proc", \
+ str, _vp); \
+} while (0)
+
+#define ASSERT_VOP_SLOCKED(vp, str) \
+do { \
+ struct vnode *_vp = (vp); \
+ \
+ if (_vp && IS_LOCKING_VFS(_vp) && \
+ VOP_ISLOCKED(_vp, NULL) != LK_SHARED) \
+ panic("%s: %p is not locked shared but should be", \
+ str, _vp); \
+} while (0)
#else
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 79a1aee..a0252d2 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -3978,7 +3978,7 @@ loop:
* way to accomplish this is to sync the entire filesystem (luckily
* this happens rarely).
*/
- if (vn_isdisk(vp) && vp->v_specmountpoint && !VOP_ISLOCKED(vp) &&
+ if (vn_isdisk(vp) && vp->v_specmountpoint && !VOP_ISLOCKED(vp, NULL) &&
(error = VFS_SYNC(vp->v_specmountpoint, MNT_WAIT, ap->a_cred,
ap->a_p)) != 0)
return (error);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 8f930af..1adb7e4 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -852,7 +852,7 @@ rescan0:
if (object->type == OBJT_VNODE) {
vp = object->handle;
- if (VOP_ISLOCKED(vp) ||
+ if (VOP_ISLOCKED(vp, NULL) ||
vp->v_data == NULL ||
vget(vp, LK_EXCLUSIVE|LK_NOOBJ, curproc)) {
if ((m->queue == PQ_INACTIVE) &&
diff --git a/sys/vm/vm_zone.c b/sys/vm/vm_zone.c
index e111b83..b53cfa0 100644
--- a/sys/vm/vm_zone.c
+++ b/sys/vm/vm_zone.c
@@ -324,7 +324,7 @@ _zget(vm_zone_t z)
* We can wait, so just do normal map allocation in the appropriate
* map.
*/
- if (lockstatus(&kernel_map->lock)) {
+ if (lockstatus(&kernel_map->lock, NULL)) {
int s;
s = splvm();
#ifdef SMP
OpenPOWER on IntegriCloud