smb_username_t *usernamesp = NULL;
-smb_waitingLock_t *smb_allWaitingLocks;
+smb_waitingLockRequest_t *smb_allWaitingLocks;
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
}
else
memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
+
+ if (numVCs >= CM_SESSION_RESERVED) {
+ numVCs = 0;
+ osi_Log0(smb_logp, "WARNING: numVCs wrapping around");
+ }
}
lock_ReleaseWrite(&smb_rctLock);
return vcp;
return 1;
}
-/* find a file ID. If we pass in 0 we select an used File ID.
+/* find a file ID. If we pass in 0 we select an unused File ID.
* If the SMB_FLAG_CREATE flag is set, we allocate a new
* smb_fid_t data structure if desired File ID cannot be found.
*/
break;
}
}
+
if (!fidp && (flags & SMB_FLAG_CREATE)) {
char eventName[MAX_PATH];
EVENT_HANDLE event;
vcp->fidCounter = 1;
}
}
+
lock_ReleaseWrite(&smb_rctLock);
return fidp;
}
}
else if (code == CM_ERROR_READONLY) {
NTStatus = 0xC00000A2L; /* Write protected */
- }
+ }
else if (code == CM_ERROR_NOSUCHFILE) {
NTStatus = 0xC000000FL; /* No such file */
}
else if (code == CM_ERROR_WOULDBLOCK) {
NTStatus = 0xC0000055L; /* Lock not granted */
}
+ else if (code == CM_ERROR_SHARING_VIOLATION) {
+ NTStatus = 0xC0000043L; /* Sharing violation */
+ }
+ else if (code == CM_ERROR_LOCK_CONFLICT) {
+ NTStatus = 0xC0000054L; /* Lock conflict */
+ }
else if (code == CM_ERROR_PARTIALWRITE) {
NTStatus = 0xC000007FL; /* Disk full */
}
class = 1;
error = 33; /* lock conflict */
}
+ else if (code == CM_ERROR_LOCK_CONFLICT) {
+ class = 1;
+ error = 33; /* lock conflict */
+ }
+ else if (code == CM_ERROR_SHARING_VIOLATION) {
+ class = 1;
+ error = 33; /* lock conflict */
+ }
else if (code == CM_ERROR_NOFILES) {
class = 1;
error = 18; /* no files in search */
osi_hyper_t offset;
long count, minCount, finalCount;
unsigned short fd;
+ unsigned pid;
smb_fid_t *fidp;
long code = 0;
cm_user_t *userp = NULL;
if (!fidp)
goto send1;
+ pid = ((smb_t *) inp)->pid;
+ {
+ LARGE_INTEGER LOffset, LLength;
+ cm_key_t key;
+
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+ LOffset.HighPart = 0;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+ }
+ if (code) {
+ goto send1a;
+ }
+
lock_ObtainMutex(&smb_RawBufLock);
if (smb_RawBufs) {
/* Get a raw buf, from head of list */
void smb_WaitingLocksDaemon()
{
- smb_waitingLock_t *wL, *nwL;
+ smb_waitingLockRequest_t *wlRequest, *nwlRequest;
+ smb_waitingLock_t *wl, *wlNext;
int first;
smb_vc_t *vcp;
smb_packet_t *inp, *outp;
while (smbShutdownFlag == 0) {
lock_ObtainWrite(&smb_globalLock);
- nwL = smb_allWaitingLocks;
- if (nwL == NULL) {
+ nwlRequest = smb_allWaitingLocks;
+ if (nwlRequest == NULL) {
osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock);
thrd_Sleep(1000);
continue;
first = 0;
else
lock_ObtainWrite(&smb_globalLock);
- wL = nwL;
- nwL = (smb_waitingLock_t *) osi_QNext(&wL->q);
+
+ wlRequest = nwlRequest;
+ nwlRequest = (smb_waitingLockRequest_t *) osi_QNext(&wlRequest->q);
lock_ReleaseWrite(&smb_globalLock);
- code = cm_RetryLock((cm_file_lock_t *) wL->lockp,
- wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD);
+
+ code = 0;
+
+ for (wl = wlRequest->locks; wl; wl = (smb_waitingLock_t *) osi_QNext(&wl->q)) {
+ if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
+ continue;
+
+ /* wl->state is either _DONE or _WAITING. _ERROR
+ would no longer be on the queue. */
+ code = cm_RetryLock( wl->lockp,
+ !!(wlRequest->vcp->flags & SMB_VCFLAG_ALREADYDEAD) );
+
+ if (code == 0) {
+ wl->state = SMB_WAITINGLOCKSTATE_DONE;
+ } else if (code != CM_ERROR_WOULDBLOCK) {
+ wl->state = SMB_WAITINGLOCKSTATE_ERROR;
+ break;
+ }
+ }
+
if (code == CM_ERROR_WOULDBLOCK) {
+
/* no progress */
- if (wL->timeRemaining != 0xffffffff
- && (wL->timeRemaining -= 1000) < 0)
+ if (wlRequest->timeRemaining != 0xffffffff
+ && (wlRequest->timeRemaining -= 1000) < 0)
goto endWait;
+
continue;
}
endWait:
- vcp = wL->vcp;
- inp = wL->inp;
- outp = wL->outp;
+
+ if (code != 0) {
+ cm_scache_t * scp;
+ cm_req_t req;
+
+ scp = wlRequest->scp;
+
+ cm_InitReq(&req);
+
+ lock_ObtainMutex(&scp->mx);
+
+ for (wl = wlRequest->locks; wl; wl = wlNext) {
+ wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
+
+ cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
+ wl->LLength, wl->key, NULL, &req);
+
+ osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
+
+ free(wl);
+ }
+
+ lock_ReleaseMutex(&scp->mx);
+
+ } else {
+ for (wl = wlRequest->locks; wl; wl = wlNext) {
+ wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
+ osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
+ free(wl);
+ }
+ }
+
+ vcp = wlRequest->vcp;
+ inp = wlRequest->inp;
+ outp = wlRequest->outp;
ncbp = GetNCB();
ncbp->ncb_length = inp->ncb_length;
inp->spacep = cm_GetSpace();
/* Remove waitingLock from list */
lock_ObtainWrite(&smb_globalLock);
osi_QRemove((osi_queue_t **)&smb_allWaitingLocks,
- &wL->q);
+ &wlRequest->q);
lock_ReleaseWrite(&smb_globalLock);
/* Resume packet processing */
smb_FreePacket(inp);
smb_FreePacket(outp);
smb_ReleaseVC(vcp);
+ cm_ReleaseSCache(wlRequest->scp);
FreeNCB(ncbp);
- free(wL);
- } while (nwL && smbShutdownFlag == 0);
+ free(wlRequest);
+ } while (nwlRequest && smbShutdownFlag == 0);
thrd_Sleep(1000);
}
}
else
code = 0;
+ /* unlock any pending locks */
+ if (!(fidp->flags & SMB_FID_IOCTL) && fidp->scp &&
+ fidp->scp->fileType == CM_SCACHETYPE_FILE) {
+ cm_key_t key;
+ unsigned pid;
+ cm_scache_t * scp;
+ long tcode;
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fid);
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ObtainMutex(&scp->mx);
+
+ tcode = cm_SyncOp(scp, NULL, userp, &req, 0,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_GETSTATUS
+ | CM_SCACHESYNC_LOCK);
+
+ if (tcode) {
+ osi_Log1(smb_logp, "smb CoreClose SyncOp failure code 0x%x", tcode);
+ goto post_syncopdone;
+ }
+
+ cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req);
+
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+
+ post_syncopdone:
+
+ lock_ReleaseMutex(&scp->mx);
+ cm_ReleaseSCache(scp);
+ }
+
if (fidp->flags & SMB_FID_DELONCLOSE) {
cm_scache_t *dscp = fidp->NTopen_dscp;
char *pathp = fidp->NTopen_pathp;
}
if (fidp->curr_chunk == fidp->prev_chunk + 1)
sequential = 1;
- }
+ }
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
osi_hyper_t offset;
long count, written = 0, total_written = 0;
unsigned short fd;
+ unsigned pid;
smb_fid_t *fidp;
long code = 0;
cm_user_t *userp;
userp = smb_GetUser(vcp, inp);
- /* special case: 0 bytes transferred means truncate to this position */
+ /* special case: 0 bytes transferred means truncate to this position */
if (count == 0) {
cm_req_t req;
goto done;
}
+ {
+ cm_key_t key;
+ LARGE_INTEGER LOffset;
+ LARGE_INTEGER LLength;
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+ LOffset.HighPart = offset.HighPart;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+
+ if (code)
+ goto done;
+ }
+
/*
* Work around bug in NT client
*
if (!fidp) {
return CM_ERROR_BADFD;
}
+
+ {
+ unsigned pid;
+ cm_key_t key;
+ LARGE_INTEGER LOffset;
+ LARGE_INTEGER LLength;
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+ LOffset.HighPart = offset.HighPart;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+
+ if (code) {
+ smb_ReleaseFID(fidp);
+ return code;
+ }
+ }
userp = smb_GetUser(vcp, inp);
osi_hyper_t offset;
long count, finalCount;
unsigned short fd;
+ unsigned pid;
smb_fid_t *fidp;
long code = 0;
cm_user_t *userp;
if (fidp->flags & SMB_FID_IOCTL) {
return smb_IoctlRead(fidp, vcp, inp, outp);
}
+
+ {
+ LARGE_INTEGER LOffset, LLength;
+ cm_key_t key;
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+ LOffset.HighPart = 0;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+ }
+ if (code) {
+ smb_ReleaseFID(fidp);
+ return code;
+ }
userp = smb_GetUser(vcp, inp);