clarify locking requirements for smb_{share,vc,co}_{rele,put}() - the lock

must be held on entry
drain the lock in smb_co_gone(), so that it's done always
turn some SMBERROR()s to #ifdef DIAGNOSTIC/DEBUG panics
This commit is contained in:
jdolecek 2003-02-24 09:55:37 +00:00
parent da9a088d46
commit 31a056fdaf
2 changed files with 31 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: smb_conn.c,v 1.5 2003/02/18 10:16:49 jdolecek Exp $ */
/* $NetBSD: smb_conn.c,v 1.6 2003/02/24 09:55:37 jdolecek Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: smb_conn.c,v 1.5 2003/02/18 10:16:49 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: smb_conn.c,v 1.6 2003/02/24 09:55:37 jdolecek Exp $");
/*
* Connection engine.
@ -67,7 +67,7 @@ SYSCTL_NODE(_net, OID_AUTO, smb, CTLFLAG_RW, NULL, "SMB protocol");
MALLOC_DEFINE(M_SMBCONN, "SMB conn", "SMB connection");
static void smb_co_init(struct smb_connobj *cp, int level, char *objname);
static void smb_co_init(struct smb_connobj *cp, int level, const char *objname);
static void smb_co_done(struct smb_connobj *cp);
static int smb_co_lockstatus(struct smb_connobj *cp);
@ -98,10 +98,10 @@ smb_sm_done(void)
{
/* XXX: hold the mutex */
if (smb_vclist.co_usecount > 1) {
SMBERROR("%d connections still active\n", smb_vclist.co_usecount - 1);
return EBUSY;
}
#ifdef DIAGNOSTIC
if (smb_vclist.co_usecount > 1)
panic("%d connections still active\n", smb_vclist.co_usecount - 1);
#endif
smb_co_done(&smb_vclist);
return 0;
}
@ -226,7 +226,7 @@ out:
* Common code for connection object
*/
static void
smb_co_init(struct smb_connobj *cp, int level, char *objname)
smb_co_init(struct smb_connobj *cp, int level, const char *objname)
{
SLIST_INIT(&cp->co_children);
smb_sl_init(&cp->co_interlock, objname);
@ -240,7 +240,9 @@ static void
smb_co_done(struct smb_connobj *cp)
{
smb_sl_destroy(&cp->co_interlock);
#ifndef __NetBSD__
#ifdef __NetBSD__
lockmgr(&cp->co_lock, LK_DRAIN, NULL);
#else
lockdestroy(&cp->co_lock);
#endif
}
@ -275,20 +277,19 @@ void
smb_co_rele(struct smb_connobj *cp, struct smb_cred *scred)
{
SMB_CO_LOCK(cp);
lockmgr(&cp->co_lock, LK_RELEASE | LK_INTERLOCK, &cp->co_interlock);
if (cp->co_usecount > 1) {
cp->co_usecount--;
SMB_CO_UNLOCK(cp);
return;
}
if (cp->co_usecount == 0) {
SMBERROR("negative use_count for object %d", cp->co_level);
SMB_CO_UNLOCK(cp);
return;
}
#ifdef DIAGNOSTIC
if (cp->co_usecount == 0)
panic("negative use_count for object %d", cp->co_level);
#endif
cp->co_usecount--;
cp->co_flags |= SMBO_GONE;
lockmgr(&cp->co_lock, LK_DRAIN | LK_INTERLOCK, &cp->co_interlock);
smb_co_gone(cp, scred);
}
@ -313,23 +314,21 @@ smb_co_get(struct smb_connobj *cp, int flags, struct smb_cred *scred)
void
smb_co_put(struct smb_connobj *cp, struct smb_cred *scred)
{
int flags;
flags = LK_RELEASE;
SMB_CO_LOCK(cp);
if (cp->co_usecount > 1) {
cp->co_usecount--;
} else if (cp->co_usecount == 1) {
cp->co_usecount--;
cp->co_flags |= SMBO_GONE;
flags = LK_DRAIN;
} else {
SMBERROR("negative usecount");
}
#ifdef DIAGNOSTIC
else
panic("smb_co_put: negative usecount");
#endif
lockmgr(&cp->co_lock, LK_RELEASE | LK_INTERLOCK, &cp->co_interlock);
if ((cp->co_flags & SMBO_GONE) == 0)
return;
lockmgr(&cp->co_lock, LK_DRAIN, NULL);
smb_co_gone(cp, scred);
}
@ -347,11 +346,11 @@ smb_co_lock(struct smb_connobj *cp, int flags)
return EINVAL;
if ((flags & LK_TYPE_MASK) == 0)
flags |= LK_EXCLUSIVE;
#ifdef DEBUG
if (smb_co_lockstatus(cp) == LK_EXCLUSIVE &&
(flags & LK_CANRECURSE) == 0) {
SMBERROR("recursive lock for object %d\n", cp->co_level);
return 0;
}
(flags & LK_CANRECURSE) == 0)
panic("recursive lock for object %d\n", cp->co_level);
#endif
return lockmgr(&cp->co_lock, flags, &cp->co_interlock);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: smb_dev.c,v 1.11 2003/02/18 12:18:29 jdolecek Exp $ */
/* $NetBSD: smb_dev.c,v 1.12 2003/02/24 09:55:38 jdolecek Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@ -231,11 +231,15 @@ nsmb_dev_close(dev_t dev, int flag, int fmt, struct proc *p)
}
smb_makescred(&scred, p, NULL);
ssp = sdp->sd_share;
if (ssp != NULL)
if (ssp != NULL) {
smb_share_lock(ssp, 0);
smb_share_rele(ssp, &scred);
}
vcp = sdp->sd_vc;
if (vcp != NULL)
if (vcp != NULL) {
smb_vc_lock(vcp, 0);
smb_vc_rele(vcp, &scred);
}
/*
smb_flushq(&sdp->sd_rqlist);
smb_flushq(&sdp->sd_rplist);