if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
memset(vcp, 0, sizeof(*vcp));
- vcp->vcID = numVCs++;
+ lock_ObtainWrite(&smb_globalLock);
+ vcp->vcID = ++numVCs;
+ lock_ReleaseWrite(&smb_globalLock);
vcp->refCount = 2; /* smb_allVCsp and caller */
vcp->tidCounter = 1;
vcp->fidCounter = 1;
memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
if (numVCs >= CM_SESSION_RESERVED) {
+ lock_ObtainWrite(&smb_globalLock);
numVCs = 0;
+ lock_ReleaseWrite(&smb_globalLock);
osi_Log0(smb_logp, "WARNING: numVCs wrapping around");
}
}
{
smb_fid_t *fidpIter;
smb_fid_t *fidpNext;
- smb_fid_t *fidp;
unsigned short fid;
smb_tid_t *tidpIter;
smb_tid_t *tidpNext;
- smb_tid_t *tidp;
unsigned short tid;
smb_user_t *uidpIter;
smb_user_t *uidpNext;
- smb_user_t *uidp;
unsigned short uid;
smb_vc_t **vcpp;
fid = fidpIter->fid;
osi_Log2(smb_logp, " Cleanup FID %d (fidp=0x%x)", fid, fidpIter);
- lock_ReleaseRead(&smb_rctLock);
- fidp = smb_FindFID(vcp, fid, 0);
- osi_assert(fidp);
- smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
+ smb_HoldFIDNoLock(fidpIter);
+ lock_ReleaseWrite(&smb_rctLock);
- lock_ObtainRead(&smb_rctLock);
+ /* smb_CloseFID sets SMB_FID_DELETE */
+ if (smb_CloseFID(vcp, fidpIter, NULL, 0) == 0)
+ smb_ReleaseFID(fidpIter);
+
+ lock_ObtainWrite(&smb_rctLock);
+ fidpNext = vcp->fidsp;
}
for (tidpIter = vcp->tidsp; tidpIter; tidpIter = tidpNext) {
tid = tidpIter->tid;
osi_Log2(smb_logp, " Cleanup TID %d (tidp=0x%x)", tid, tidpIter);
+
+ smb_HoldTIDNoLock(tidpIter);
lock_ReleaseWrite(&smb_rctLock);
- tidp = smb_FindTID(vcp, tid, 0);
- osi_assert(tidp);
+ lock_ObtainMutex(&tidpIter->mx);
+ tidpIter->flags |= SMB_TIDFLAG_DELETE;
+ lock_ReleaseMutex(&tidpIter->mx);
- lock_ObtainMutex(&tidp->mx);
- tidp->flags |= SMB_TIDFLAG_DELETE;
- lock_ReleaseMutex(&tidp->mx);
-
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidpIter);
lock_ObtainWrite(&smb_rctLock);
+ tidpNext = vcp->tidsp;
}
for (uidpIter = vcp->usersp; uidpIter; uidpIter = uidpNext) {
if (uidpIter->flags & SMB_USERFLAG_DELETE)
continue;
- uid = uidpIter->userID;
- osi_Log2(smb_logp, " Cleanup UID %d (uidp=0x%x)", uid, uidpIter);
+ /* do not add an additional reference count for the smb_user_t
+ * as the smb_vc_t already is holding a reference */
lock_ReleaseWrite(&smb_rctLock);
- uidp = smb_FindUID(vcp, uid, 0);
- osi_assert(uidp);
-
- lock_ObtainMutex(&uidp->mx);
- uidp->flags |= SMB_USERFLAG_DELETE;
- lock_ReleaseMutex(&uidp->mx);
+ lock_ObtainMutex(&uidpIter->mx);
+ uidpIter->flags |= SMB_USERFLAG_DELETE;
+ lock_ReleaseMutex(&uidpIter->mx);
- smb_ReleaseUID(uidp);
+ smb_ReleaseUID(uidpIter);
lock_ObtainWrite(&smb_rctLock);
+ uidpNext = vcp->usersp;
}
/* remove VCP from smb_allVCsp */
return tidp;
}
+void smb_HoldTIDNoLock(smb_tid_t *tidp)
+{
+ tidp->refCount++;
+}
+
void smb_ReleaseTID(smb_tid_t *tidp)
{
smb_tid_t *tp;
lock_ObtainWrite(&smb_rctLock);
osi_assert(unp->refCount-- > 0);
if (unp->refCount == 0 && !(unp->flags & SMB_USERNAMEFLAG_AFSLOGON) &&
- !((unp->flags & SMB_USERNAMEFLAG_LOGOFF) && smb_LogoffTokenTransfer)) {
+ (unp->flags & SMB_USERNAMEFLAG_LOGOFF)) {
lupp = &usernamesp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
if (up == unp)
}
}
+void smb_HoldUIDNoLock(smb_user_t *uidp)
+{
+ uidp->refCount++;
+}
+
void smb_ReleaseUID(smb_user_t *uidp)
{
smb_user_t *up;
osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
vcp);
vcp->fidCounter = 1;
- }
- }
+ }
+ }
}
lock_ReleaseWrite(&smb_rctLock);
return fidp;
}
+void smb_HoldFIDNoLock(smb_fid_t *fidp)
+{
+ fidp->refCount++;
+}
+
void smb_ReleaseFID(smb_fid_t *fidp)
{
cm_scache_t *scp = NULL;
osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
vcp, vcp->usersp);
smb_HoldVC(vcp);
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
+
+ lock_ObtainWrite(&smb_globalLock);
if (dead_vcp) {
- osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp);
- smb_CleanupDeadVC(dead_vcp);
- smb_ReleaseVC(dead_vcp);
+ smb_vc_t * dvcp = dead_vcp;
+ dead_vcp = vcp;
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseWrite(&smb_globalLock);
+ osi_Log1(smb_logp,"Previous dead_vcp %x", dvcp);
+ smb_CleanupDeadVC(dvcp);
+ smb_ReleaseVC(dvcp);
+ } else {
+ dead_vcp = vcp;
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseWrite(&smb_globalLock);
}
- dead_vcp = vcp;
- vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- dead_sessions[vcp->session] = TRUE;
}
if (localNCB)
afs_uint32 dosTime) {
long code = 0;
cm_req_t req;
+ cm_scache_t *dscp = fidp->NTopen_dscp;
+ char *pathp = fidp->NTopen_pathp;
osi_Log3(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d vcp=0x%x)",
fidp, fidp->fid, vcp);
if (!userp) {
- if (!fidp->userp) {
+ if (!fidp->userp && !(fidp->flags & SMB_FID_IOCTL)) {
osi_Log0(smb_logp, " No user specified. Not closing fid");
- return CM_ERROR_BADFD;
- }
+ return CM_ERROR_BADFD;
+ }
userp = fidp->userp; /* no hold required since fidp is held
throughout the function */
lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_DELETE) {
+ osi_Log0(smb_logp, " Fid already closed.");
+ lock_ReleaseMutex(&fidp->mx);
+ return CM_ERROR_BADFD;
+ }
+
+ fidp->flags |= SMB_FID_DELETE;
+
/* Don't jump the gun on an async raw write */
while (fidp->raw_writers) {
lock_ReleaseMutex(&fidp->mx);
lock_ObtainMutex(&fidp->mx);
}
- fidp->flags |= SMB_FID_DELETE;
-
/* watch for ioctl closes, and read-only opens */
if (fidp->scp != NULL &&
(fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE))
}
if (fidp->flags & SMB_FID_DELONCLOSE) {
- cm_scache_t *dscp = fidp->NTopen_dscp;
- char *pathp = fidp->NTopen_pathp;
char *fullPathp;
smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req);
dscp, fullPathp, NULL, TRUE);
}
free(fullPathp);
+ fidp->flags &= ~SMB_FID_DELONCLOSE;
}
- lock_ReleaseMutex(&fidp->mx);
if (fidp->flags & SMB_FID_NTOPEN) {
- cm_ReleaseSCache(fidp->NTopen_dscp);
- free(fidp->NTopen_pathp);
+ fidp->NTopen_dscp = NULL;
fidp->NTopen_pathp = NULL;
+ fidp->flags &= ~SMB_FID_NTOPEN;
}
if (fidp->NTopen_wholepathp) {
free(fidp->NTopen_wholepathp);
fidp->NTopen_wholepathp = NULL;
}
+ lock_ReleaseMutex(&fidp->mx);
+
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+
+ if (pathp)
+ free(pathp);
return code;
}
smb_ReleaseVC(active_vcp);
}
smb_HoldVC(vcp);
+ lock_ObtainWrite(&smb_globalLock);
active_vcp = vcp;
+ lock_ReleaseWrite(&smb_globalLock);
}
last_msg_time = GetTickCount();
} else if (active_vcp == vcp) { /* the vcp is dead */
smb_ReleaseVC(active_vcp);
+ lock_ObtainWrite(&smb_globalLock);
active_vcp = NULL;
+ lock_ReleaseWrite(&smb_globalLock);
}
return;
}
#endif /* !DJGPP */
case NRC_SCLOSED:
/* Client closed session */
- dead_sessions[idx_session] = TRUE;
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
if (vcp) {
- if (dead_vcp == vcp)
+ lock_ObtainWrite(&smb_globalLock);
+ if (dead_vcp == vcp) {
osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp);
- else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ lock_ReleaseWrite(&smb_globalLock);
+ } else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
vcp, vcp->usersp);
if (dead_vcp) {
- osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp);
- smb_CleanupDeadVC(dead_vcp);
- smb_ReleaseVC(dead_vcp);
- }
+ smb_vc_t * dvcp = dead_vcp;
+ dead_vcp = vcp; /* transfer the reference */
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseWrite(&smb_globalLock);
+ osi_Log1(smb_logp,"Previous dead_vcp %x", dvcp);
+ smb_CleanupDeadVC(dvcp);
+ smb_ReleaseVC(dvcp);
+ } else {
+ dead_vcp = vcp; /* transfer the reference */
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseWrite(&smb_globalLock);
+ }
+ lock_ObtainMutex(&vcp->mx);
vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- dead_vcp = vcp;
+ lock_ReleaseMutex(&vcp->mx);
vcp = NULL;
}
}
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
if (vcp && vcp->errorCount++ > 3) {
osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount);
- dead_sessions[idx_session] = TRUE;
- if (dead_vcp == vcp)
- osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp);
- else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
- osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
- vcp, vcp->usersp);
- if (dead_vcp) {
- osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp);
- smb_CleanupDeadVC(dead_vcp);
- smb_ReleaseVC(dead_vcp);
- }
- vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- dead_vcp = vcp;
- vcp = NULL;
- }
+ lock_ObtainWrite(&smb_globalLock);
+ if (dead_vcp == vcp) {
+ osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp);
+ lock_ReleaseWrite(&smb_globalLock);
+ } else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
+ vcp, vcp->usersp);
+ if (dead_vcp) {
+ smb_vc_t * dvcp = dead_vcp;
+ dead_vcp = vcp; /* transfer reference */
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseWrite(&smb_globalLock);
+
+ osi_Log1(smb_logp,"Previous dead_vcp %x", dvcp);
+ smb_CleanupDeadVC(dvcp);
+ smb_ReleaseVC(dvcp);
+ }
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
+ vcp = NULL;
+ }
goto doneWithNCB;
}
else {
/* Allocate slot in session arrays */
/* Re-use dead session if possible, otherwise add one more */
/* But don't look at session[0], it is reserved */
+ lock_ObtainWrite(&smb_globalLock);
for (session = 1; session < numSessions; session++) {
if (dead_sessions[session]) {
osi_Log1(smb_logp, "connecting to dead session [ %d ]", session);
break;
}
}
+ lock_ReleaseWrite(&smb_globalLock);
} else {
/* We are re-using an existing VC because the lsn and lana
* were re-used */
smb_SendPacket(vcp, outp);
smb_FreePacket(outp);
+ lock_ObtainMutex(&vcp->mx);
vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
smb_CleanupDeadVC(vcp);
smb_ReleaseVC(vcp);
} else {
osi_assert(session < SESSION_MAX - 1);
osi_assert(numNCBs < NCB_MAX - 1); /* if we pass this test we can allocate one more */
+ lock_ObtainMutex(&vcp->mx);
vcp->session = session;
+ lock_ReleaseMutex(&vcp->mx);
+ lock_ObtainWrite(&smb_globalLock);
LSNs[session] = ncbp->ncb_lsn;
lanas[session] = ncbp->ncb_lana_num;
+ lock_ReleaseWrite(&smb_globalLock);
if (session == numSessions) {
/* Add new NCB for new session */
osi_Log1(smb_logp, "smb_Listener creating new session %d", i);
InitNCBslot(numNCBs);
+ lock_ObtainWrite(&smb_globalLock);
numNCBs++;
+ lock_ReleaseWrite(&smb_globalLock);
thrd_SetEvent(NCBavails[0]);
thrd_SetEvent(NCBevents[0]);
for (thread = 0; thread < smb_NumServerThreads; thread++)
SessionEvents[session] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS )
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
+ lock_ObtainWrite(&smb_globalLock);
numSessions++;
+ lock_ReleaseWrite(&smb_globalLock);
osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions);
thrd_SetEvent(SessionEvents[0]);
} else {
sprintf(output, "done dumping DEAD smb_vc_t\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ sprintf(output, "begin dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp)
+ {
+ smb_fid_t *fidp;
+
+ sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\n",
+ cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ sprintf(output, "begin dumping smb_fid_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
+ {
+ sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\n",
+ cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp,
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL",
+ fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping smb_fid_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
if (lock)
lock_ReleaseRead(&smb_rctLock);
return 0;