/* save a pointer to the vnode */
osi_Log2(smb_logp,"smb_ReceiveTran2Open fidp 0x%p scp 0x%p", fidp, scp);
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
/* and the user */
fidp->userp = userp;
/* copy out remainder of the parms */
parmSlot = 0;
outp->parmsp[parmSlot++] = fidp->fid;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (extraInfo) {
outp->parmsp[parmSlot++] = smb_Attributes(scp);
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
outp->parmsp[parmSlot++] = 0;
outp->parmsp[parmSlot++] = 0;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
outp->totalData = 0; /* total # of data bytes */
outp->totalParms = parmSlot * 2; /* shorts are two bytes */
}
#endif /* DFS_SUPPORT */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp_mx_held = 1;
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
qpi.u.QPfileStandardInfo.reserved = 0;
if (fidp) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
scp_mx_held = 0;
lock_ObtainMutex(&fidp->mx);
delonclose = fidp->flags & SMB_FID_DELONCLOSE;
/* send and free the packets */
done:
if (scp_mx_held)
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
if (code == 0) {
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = CM_ATTRMASK_LENGTH;
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
cm_scache_t *scp;
smb_tran2QFileInfo_t qfi;
long code = 0;
+ int readlock = 0;
cm_req_t req;
cm_InitReq(&req);
osi_Log2(smb_logp,"smb_ReleaseTran2QFileInfo fidp 0x%p scp 0x%p", fidp, scp);
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+ readlock = 1;
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
unsigned long len;
char *name;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (fidp->NTopen_wholepathp)
name = fidp->NTopen_wholepathp;
else
/* send and free the packets */
done:
- lock_ReleaseMutex(&scp->mx);
+ if (readlock)
+ lock_ReleaseRead(&scp->rw);
+ else
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
/* lock the vnode with a callback; we need the current status
* to determine what the new status is, in some cases.
*/
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
goto done;
}
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
/* prepare for setattr call */
attr.mask = 0;
attr.unixModeBits = scp->unixModeBits | 0222;
}
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
lock_ReleaseMutex(&fidp->mx);
/* call setattr */
if (code == 0 && !(rights & PRSFS_READ))
mustFake = 1;
else if (code == -1) {
- lock_ObtainMutex(&dscp->mx);
+ lock_ObtainWrite(&dscp->rw);
code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- lock_ReleaseMutex(&dscp->mx);
+ lock_ReleaseWrite(&dscp->rw);
if (code == CM_ERROR_NOACCESS) {
mustFake = 1;
code = 0;
if (code)
continue;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (mustFake == 0)
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (mustFake || code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
dptr = patchp->dptr;
/* now watch for a symlink */
code = 0;
while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
reqp->relPathp = path;
reqp->tidPathp = tidPathp;
cm_ReleaseSCache(scp);
scp = targetScp;
}
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
}
+ lock_ConvertWToR(&scp->rw);
+
dptr = patchp->dptr;
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
*dptr++ = (attr >> 8) & 0xff;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
}
* and so we do another hold now.
*/
cm_HoldSCache(scp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 &&
LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
}
}
lock_ReleaseMutex(&dsp->mx);
}
/* get the directory size */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
buf_Release(bufferp);
bufferp = NULL;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
lock_ObtainMutex(&dsp->mx);
if (starPattern) {
code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, infoLevel, userp, &req);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
}
/* release the mutex */
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveV3OpenX fidp 0x%p scp 0x%p", fidp, scp);
/* also the user */
fidp->userp = userp;
/* copy out remainder of the parms */
parmSlot = 2;
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
if (extraInfo) {
smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++;
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++;
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
smb_SetSMBDataLength(outp, 0);
osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid);
userp = smb_GetUserFromVCP(vcp, inp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
doneSync:
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
afs_uint32 searchTime;
cm_user_t *userp;
cm_req_t req;
+ int readlock = 0;
cm_InitReq(&req);
/* otherwise, stat the file */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ConvertWToR(&scp->rw);
+
/* decode times. We need a search time, but the response to this
* call provides the date first, not the time, as returned in the
* searchTime variable. So we take the high-order bits first.
code = 0;
done:
- lock_ReleaseMutex(&scp->mx);
+ if (readlock)
+ lock_ReleaseRead(&scp->rw);
+ else
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
LARGE_INTEGER LLength;
cm_scache_t * scp;
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
LLength.LowPart = count;
scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_LockCheckWrite(scp, LOffset, LLength, key);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code)
goto done;
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
cm_key_t key;
return CM_ERROR_NOSUCHFILE;
}
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
{
LARGE_INTEGER LOffset, LLength;
LLength.LowPart = count;
scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_LockCheckRead(scp, LOffset, LLength, key);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
}
if (code) {
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
- if (desiredAccess & AFS_ACCESS_READ)
+ if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTCreateX fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
/* out parms */
parmSlot = 2;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
osi_LogSaveString(smb_logp, realPathp));
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
- if (desiredAccess & AFS_ACCESS_READ)
+ if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
fidflags |= SMB_FID_OPENREAD_LISTDIR;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (code) {
if (ldp)
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
osi_Log2(smb_logp,"smb_ReceiveNTTranCreate fidp 0x%p scp 0x%p", fidp, scp);
fidp->flags = fidflags;
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 70);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 2; /* is a dir? */
- lock_ReleaseMutex(&scp->mx);
} else {
/* out parms */
parmOffset = 8*4 + 39;
smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
smb_SetSMBDataLength(outp, 105);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainRead(&scp->rw);
outData = smb_GetSMBData(outp, NULL);
outData++; /* round to get to parmOffset */
*outData = 0; outData++; /* oplock */
memset(outData,0,24); outData += 24; /* Volume ID and file ID */
*((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
*((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */
- lock_ReleaseMutex(&scp->mx);
}
- lock_ObtainMutex(&scp->mx);
if ((fidp->flags & SMB_FID_EXECUTABLE) &&
LargeIntegerGreaterThanZero(fidp->scp->length) &&
!(scp->flags & CM_SCACHEFLAG_PREFETCHING)) {
fidp->scp->length.LowPart, fidp->scp->length.HighPart,
userp);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
osi_Log0(smb_logp, " Notify Change Stream Write");
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags |= CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
outp->flags |= SMB_PACKETFLAG_NOSEND;
lastWatch->nextp = nextWatch;
/* Turn off WATCHED flag in dscp */
- lock_ObtainMutex(&dscp->mx);
+ lock_ObtainWrite(&dscp->rw);
if (wtree)
dscp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
dscp->flags &= ~CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&dscp->mx);
+ lock_ReleaseWrite(&dscp->rw);
/* Convert to response packet */
((smb_t *) watch)->reb = SMB_FLAGS_SERVER_TO_CLIENT;
scp = fidp->scp;
osi_Log2(smb_logp,"smb_ReceiveNTCancel fidp 0x%p scp 0x%p", fidp, scp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (watchtree)
scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
else
scp->flags &= ~CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
} else {
osi_Log2(smb_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp);