int hash;
lock_ObtainWrite(&cm_scacheLock);
- for (hash=0; hash < cm_data.hashTableSize; hash++) {
- for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) {
+ for (hash=0; hash < cm_hashTableSize; hash++) {
+ for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainMutex(&scp->mx);
shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
if ( shareFound ) {
/* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, sharePath, reqp, &substRootp);
free(sharePath);
shareName[i] = 0; /* terminate string */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, shareName, reqp, &substRootp);
if (code)
return code;
}
} else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, ioctlp->tidPathp, reqp, &substRootp);
if (code)
shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
if ( shareFound ) {
/* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, sharePath, reqp, &substRootp);
free(sharePath);
shareName[i++] = '/'; /* add trailing slash */
shareName[i] = 0; /* terminate string */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, shareName, reqp, &substRootp);
if (code) return code;
if (code) return code;
}
} else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, ioctlp->tidPathp, reqp, &substRootp);
if (code) return code;
{
cellp = cm_FindCellByID(scp->fid.cell);
if (cellp) {
- StringCbCopyA(ioctlp->outDatap, 999999, cellp->name);
+ StringCbCopyA(ioctlp->outDatap, 999999, cellp->namep);
ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
code = 0;
}
cm_ReleaseSCache(scp);
lock_ObtainWrite(&cm_scacheLock);
- for (i=0; i<cm_data.hashTableSize; i++) {
- for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+ for (i=0; i<cm_hashTableSize; i++) {
+ for (scp = cm_hashTablep[i]; scp; scp = scp->nextp) {
if (scp->fid.volume == volume) {
cm_HoldSCacheNoLock(scp);
lock_ReleaseWrite(&cm_scacheLock);
memcpy(&temp, ioctlp->inDatap, sizeof(temp));
if (temp == 0)
- temp = cm_data.buf_nOrigBuffers;
+ temp = buf_nOrigBuffers;
else {
/* temp is in 1K units, convert to # of buffers */
- temp = temp / (cm_data.buf_blockSize / 1024);
+ temp = temp / (buf_bufferSize / 1024);
}
/* now adjust the cache size */
memset(&parms, 0, sizeof(parms));
/* first we get, in 1K units, the cache size */
- parms.parms[0] = cm_data.buf_nbuffers * (cm_data.buf_blockSize / 1024);
+ parms.parms[0] = buf_nbuffers * (buf_bufferSize / 1024);
/* and then the actual # of buffers in use (not in the free list, I guess,
* will be what we do).
*/
- parms.parms[1] = (cm_data.buf_nbuffers - buf_CountFreeList()) * (cm_data.buf_blockSize / 1024);
+ parms.parms[1] = (buf_nbuffers - buf_CountFreeList()) * (buf_bufferSize / 1024);
memcpy(ioctlp->outDatap, &parms, sizeof(parms));
ioctlp->outDatap += sizeof(parms);
}
lock_ObtainRead(&cm_cellLock);
- for (tcellp = cm_data.allCellsp; tcellp; tcellp = tcellp->nextp) {
+ for (tcellp = cm_allCellsp; tcellp; tcellp = tcellp->nextp) {
if (whichCell == 0) break;
whichCell--;
}
}
lock_ReleaseRead(&cm_serverLock);
cp = basep + max * sizeof(afs_int32);
- StringCbCopyA(cp, 999999, tcellp->name);
- cp += strlen(tcellp->name)+1;
+ StringCbCopyA(cp, 999999, tcellp->namep);
+ cp += strlen(tcellp->namep)+1;
ioctlp->outDatap = cp;
}
cm_SkipIoctlPath(ioctlp);
lock_ObtainWrite(&cm_cellLock);
- for (cp = cm_data.allCellsp; cp; cp=cp->nextp)
+ for (cp = cm_allCellsp; cp; cp=cp->nextp)
{
long code;
/* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
cm_FreeServerList(&cp->vlServersp);
cp->vlServersp = NULL;
- code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, cp);
+ code = cm_SearchCellFile(cp->namep, cp->namep, cm_AddCellProc, cp);
#ifdef AFS_AFSDB_ENV
if (code) {
if (cm_dnsEnabled) {
int ttl;
- code = cm_SearchCellByDNS(cp->name, cp->name, &ttl, cm_AddCellProc, cp);
+ code = cm_SearchCellByDNS(cp->namep, cp->namep, &ttl, cm_AddCellProc, cp);
if ( code == 0 ) { /* got cell from DNS */
cp->flags |= CM_CELLFLAG_DNS;
cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
if (cm_freelanceEnabled) {
StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
- } else if (cm_data.rootCellp) {
+ } else if (cm_rootCellp) {
/* return the default cellname to the caller */
- StringCbCopyA(ioctlp->outDatap, 999999, cm_data.rootCellp->name);
+ StringCbCopyA(ioctlp->outDatap, 999999, cm_rootCellp->namep);
ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
} else {
/* if we don't know our default cell, return failure */
}
#ifdef AFS_FREELANCE_CLIENT
- if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
+ if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
/* we are adding the mount point to the root dir., so call
* the freelance code to do the add. */
osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir");
cp = ioctlp->inDatap; /* contents of link */
#ifdef AFS_FREELANCE_CLIENT
- if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
+ if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
/* we are adding the symlink to the root dir., so call
* the freelance code to do the add. */
if (cp[0] == cp[1] && cp[1] == '\\' &&
code = cm_AssembleLink(scp, "", &newRootScp, &spacep, userp, &req);
cm_ReleaseSCache(scp);
- if (code == 0 || code == CM_ERROR_PATH_NOT_COVERED) {
+ if (code == 0) {
cp = ioctlp->outDatap;
if (newRootScp != NULL) {
StringCbCopyA(cp, 999999, cm_mountRoot);
cp = ioctlp->inDatap;
#ifdef AFS_FREELANCE_CLIENT
- if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
+ if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
/* we are adding the mount point to the root dir., so call
* the freelance code to do the add. */
osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
return CM_ERROR_INVAL;
#endif /* !DJGPP */
} else {
- cellp = cm_data.rootCellp;
+ cellp = cm_rootCellp;
osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
}
cp += sizeof(temp);
/* cell name */
- StringCbCopyA(cp, 999999, ucellp->cellp->name);
+ StringCbCopyA(cp, 999999, ucellp->cellp->namep);
cp += strlen(cp) + 1;
/* user name */
cp += sizeof(temp);
/* cell name */
- StringCbCopyA(cp, 999999, ucellp->cellp->name);
+ StringCbCopyA(cp, 999999, ucellp->cellp->namep);
cp += strlen(cp) + 1;
/* user name */
smb_vc_t *vcp;
lock_ObtainWrite(&smb_rctLock);
- for(vcp = smb_allVCsp; vcp; vcp=vcp->nextp) {
+ for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp) {
if (lsn == vcp->lsn && lana == vcp->lana) {
- vcp->refCount++;
+ smb_HoldVCNoLock(vcp);
break;
}
}
return 0;
}
+void smb_ReleaseVCNoLock(smb_vc_t *vcp)
+{
+ osi_assert(vcp->refCount-- > 0);
+}
+
void smb_ReleaseVC(smb_vc_t *vcp)
{
lock_ObtainWrite(&smb_rctLock);
lock_ReleaseWrite(&smb_rctLock);
}
+void smb_HoldVCNoLock(smb_vc_t *vcp)
+{
+ vcp->refCount++;
+}
+
void smb_HoldVC(smb_vc_t *vcp)
{
lock_ObtainWrite(&smb_rctLock);
tidp->nextp = vcp->tidsp;
tidp->refCount = 1;
tidp->vcp = vcp;
- vcp->refCount++;
+ smb_HoldVCNoLock(vcp);
vcp->tidsp = tidp;
lock_InitializeMutex(&tidp->mx, "tid_t mutex");
tidp->tid = tid;
smb_tid_t *tp;
smb_tid_t **ltpp;
cm_user_t *userp;
- smb_vc_t *vcp;
userp = NULL;
- vcp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(tidp->refCount-- > 0);
if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) {
ltpp = &tidp->vcp->tidsp;
- for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
- if (tp == tidp) break;
+ for (tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
+ if (tp == tidp)
+ break;
}
osi_assert(tp != NULL);
*ltpp = tp->nextp;
lock_FinalizeMutex(&tidp->mx);
userp = tidp->userp; /* remember to drop ref later */
- vcp = tidp->vcp;
+ tidp->userp = NULL;
+ smb_ReleaseVCNoLock(tidp->vcp);
+ tidp->vcp = NULL;
}
lock_ReleaseWrite(&smb_rctLock);
- if (userp) {
+ if (userp)
cm_ReleaseUser(userp);
- }
- if (vcp) {
- smb_ReleaseVC(vcp);
- }
}
smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags)
uidp->nextp = vcp->usersp;
uidp->refCount = 1;
uidp->vcp = vcp;
- vcp->refCount++;
+ smb_HoldVCNoLock(vcp);
vcp->usersp = uidp;
lock_InitializeMutex(&uidp->mx, "user_t mutex");
uidp->userID = uid;
smb_user_t *up;
smb_user_t **lupp;
cm_user_t *userp;
- smb_vc_t *vcp;
userp = NULL;
- vcp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(uidp->refCount-- > 0);
if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) {
*lupp = up->nextp;
lock_FinalizeMutex(&uidp->mx);
if (uidp->unp) {
- userp = uidp->unp->userp; /* remember to drop ref later */
- uidp->unp->userp = NULL;
+ userp = uidp->unp->userp; /* avoid deadlock by releasing */
+ uidp->unp->userp = NULL; /* after releasing the lock */
}
- vcp = uidp->vcp;
+ smb_ReleaseVCNoLock(uidp->vcp);
uidp->vcp = NULL;
}
lock_ReleaseWrite(&smb_rctLock);
cm_ReleaseUserVCRef(userp);
cm_ReleaseUser(userp);
}
- if (vcp) {
- smb_ReleaseVC(vcp);
- }
}
/* retrieve a held reference to a user structure corresponding to an incoming
}
retry:
- for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
+ for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
if (fid == fidp->fid) {
if (newFid) {
fid++;
osi_QAdd((osi_queue_t **)&vcp->fidsp, &fidp->q);
fidp->refCount = 1;
fidp->vcp = vcp;
- vcp->refCount++;
+ smb_HoldVCNoLock(vcp);
lock_InitializeMutex(&fidp->mx, "fid_t mutex");
fidp->fid = fid;
fidp->curr_chunk = fidp->prev_chunk = -2;
osi_assert(fidp->refCount-- > 0);
if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) {
vcp = fidp->vcp;
- if (!(fidp->flags & SMB_FID_IOCTL))
+ fidp->vcp = NULL;
+ if (!(fidp->flags & SMB_FID_IOCTL)) {
scp = fidp->scp;
+ fidp->scp = NULL;
+ }
+
osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
thrd_CloseHandle(fidp->raw_write_event);
/* and see if there is ioctl stuff to free */
ioctlp = fidp->ioctlp;
if (ioctlp) {
- if (ioctlp->prefix) cm_FreeSpace(ioctlp->prefix);
- if (ioctlp->inAllocp) free(ioctlp->inAllocp);
- if (ioctlp->outAllocp) free(ioctlp->outAllocp);
+ if (ioctlp->prefix)
+ cm_FreeSpace(ioctlp->prefix);
+ if (ioctlp->inAllocp)
+ free(ioctlp->inAllocp);
+ if (ioctlp->outAllocp)
+ free(ioctlp->outAllocp);
free(ioctlp);
}
free(fidp);
- /* do not call smb_ReleaseVC() because we already have the lock */
- vcp->refCount--;
+ smb_ReleaseVCNoLock(vcp);
}
lock_ReleaseWrite(&smb_rctLock);
void smb_FreePacket(smb_packet_t *tbp)
{
+ smb_vc_t * vcp = NULL;
+
osi_assert(tbp->magic == SMB_PACKETMAGIC);
lock_ObtainWrite(&smb_globalLock);
smb_packetFreeListp = tbp;
tbp->magic = SMB_PACKETMAGIC;
tbp->ncbp = NULL;
+ vcp = tbp->vcp;
tbp->vcp = NULL;
tbp->resumeCode = 0;
tbp->inCount = 0;
tbp->ncb_length = 0;
tbp->flags = 0;
lock_ReleaseWrite(&smb_globalLock);
+
+ if (vcp)
+ smb_ReleaseVC(vcp);
}
static void FreeNCB(NCB *bufferp)
cm_FreeSpace(inp->spacep);
smb_FreePacket(inp);
smb_FreePacket(outp);
+ if (vcp)
+ smb_ReleaseVC(vcp);
FreeNCB(ncbp);
free(wL);
} while (nwL);
memcpy(dsp->mask, mask, 11);
/* track if this is likely to match a lot of entries */
- if (smb_IsStarMask(mask)) starPattern = 1;
- else starPattern = 0;
- }
- else {
+ if (smb_IsStarMask(mask))
+ starPattern = 1;
+ else
+ starPattern = 0;
+ } else {
/* pull the next cookie value out of the search status block */
nextCookie = inCookiep[13] + (inCookiep[14]<<8) + (inCookiep[15]<<16)
+ (inCookiep[16]<<24);
caseFold = CM_FLAG_CASEFOLD;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
- if(code) {
+ if (code) {
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
/* free a tran2 packet; must be called with smb_globalLock held */
void smb_FreeTran2Packet(smb_tran2Packet_t *t2p)
{
- if (t2p->vcp) smb_ReleaseVC(t2p->vcp);
+ if (t2p->vcp)
+ smb_ReleaseVC(t2p->vcp);
if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) {
if (t2p->parmsp)
free(t2p->parmsp);
smb_StripLastComponent(spacep->data, NULL, pathp);
code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
if (code) {
- lock_ReleaseMutex(&dsp->mx);
cm_ReleaseUser(userp);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOFILES);
smb_FreeTran2Packet(outp);
+ lock_ReleaseMutex(&dsp->mx);
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
return 0;
* and truncate the file if we find it, otherwise we create the
* file.
*/
- if (!lastNamep) lastNamep = pathp;
- else lastNamep++;
+ if (!lastNamep)
+ lastNamep = pathp;
+ else
+ lastNamep++;
code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp,
&req, &scp);
if (code && code != CM_ERROR_NOSUCHFILE) {
if (code == 0) {
code = cm_CheckOpen(scp, openMode, trunc, userp, &req);
if (code) {
- if (dscp) cm_ReleaseSCache(dscp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
return code;
if (excl) {
/* oops, file shouldn't be there */
- if (dscp) cm_ReleaseSCache(dscp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
return CM_ERROR_EXISTS;
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_LOCK);
- if (code) goto doneSync;
+ if (code)
+ goto doneSync;
LockType = smb_GetSMBParm(inp, 3) & 0xff;
Timeout = (smb_GetSMBParm(inp, 5) << 16) + smb_GetSMBParm(inp, 4);
/* Put on waiting list */
waitingLock = malloc(sizeof(smb_waitingLock_t));
waitingLock->vcp = vcp;
+ smb_HoldVC(vcp);
waitingLock->inp = smb_CopyPacket(inp);
waitingLock->outp = smb_CopyPacket(outp);
waitingLock->timeRemaining = Timeout;
/* don't send reply immediately */
outp->flags |= SMB_PACKETFLAG_NOSEND;
}
- if (code) break;
+ if (code)
+ break;
}
if (code) {
cm_InitReq(&req);
+ /* This code is very long and has a lot of if-then-else clauses
+ * scp and dscp get reused frequently and we need to ensure that
+ * we don't lose a reference. Start by ensuring that they are NULL.
+ */
+ scp = NULL;
+ dscp = NULL;
treeCreate = FALSE;
foundscp = FALSE;
- scp = NULL;
nameLength = smb_GetSMBOffsetParm(inp, 2, 1);
flags = smb_GetSMBOffsetParm(inp, 3, 1)
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
- dscp = NULL;
code = 0;
+
/* For an exclusive create, we want to do a case sensitive match for the last component. */
if ( createDisp == FILE_CREATE ||
createDisp == FILE_OVERWRITE ||
return CM_ERROR_EXISTS;
}
}
- } else
- dscp = NULL;
+ }
+ /* we have both scp and dscp */
} else {
code = cm_NameI(baseDirp, realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &scp);
+ /* we might have scp but not dscp */
}
- if (code == 0)
- foundscp = TRUE;
+ if (scp)
+ foundscp = TRUE;
+
if (!foundscp || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
/* look up parent directory */
/* If we are trying to create a path (i.e. multiple nested directories), then we don't *need*
* recognize.
*/
- if ( !dscp ) {
- while (1) {
+ /* we might or might not have scp */
+
+ if (dscp == NULL) {
+ do {
char *tp;
code = cm_NameI(baseDirp, spacep->data,
smb_ReleaseFID(baseFidp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (scp)
+ cm_ReleaseSCache(scp);
return CM_ERROR_BADNTFILENAME;
}
+ code = 0;
}
- else
- break;
- }
+ } while (dscp == NULL && code == 0);
} else
- code = 0;
+ code = 0;
+
+ /* we might have scp and we might have dscp */
if (baseFid != 0)
smb_ReleaseFID(baseFidp);
if (code) {
osi_Log0(smb_logp,"NTCreateX parent not found");
+ if (scp)
+ cm_ReleaseSCache(scp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return code;
if (treeCreate && dscp->fileType == CM_SCACHETYPE_FILE) {
/* A file exists where we want a directory. */
+ if (scp)
+ cm_ReleaseSCache(scp);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
lastNamep++;
if (!smb_IsLegalFilename(lastNamep)) {
+ if (scp)
+ cm_ReleaseSCache(scp);
+ if (dscp)
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return code;
}
}
- }
- else {
+ /* we have scp and dscp */
+ } else {
+ /* we have scp but not dscp */
if (baseFid != 0)
smb_ReleaseFID(baseFidp);
- }
+ }
- /* if we get here, if code is 0, the file exists and is represented by
- * scp. Otherwise, we have to create it. The dir may be represented
- * by dscp, or we may have found the file directly. If code is non-zero,
- * scp is NULL.
- */
- if (code == 0 && !treeCreate) {
- if (createDisp == FILE_CREATE) {
- /* oops, file shouldn't be there */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_EXISTS;
- }
+ /* if we get here, if code is 0, the file exists and is represented by
+ * scp. Otherwise, we have to create it. The dir may be represented
+ * by dscp, or we may have found the file directly. If code is non-zero,
+ * scp is NULL.
+ */
+ if (code == 0 && !treeCreate) {
+ if (createDisp == FILE_CREATE) {
+ /* oops, file shouldn't be there */
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_EXISTS;
+ }
- if ( createDisp == FILE_OVERWRITE ||
- createDisp == FILE_OVERWRITE_IF) {
- setAttr.mask = CM_ATTRMASK_LENGTH;
- setAttr.length.LowPart = 0;
- setAttr.length.HighPart = 0;
- /* now watch for a symlink */
- code = 0;
- while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
- targetScp = 0;
- code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
- if (code == 0) {
- /* we have a more accurate file to use (the
- * target of the symbolic link). Otherwise,
- * we'll just use the symlink anyway.
- */
- osi_Log2(smb_logp, "symlink vp %x to vp %x",
- scp, targetScp);
- cm_ReleaseSCache(scp);
- scp = targetScp;
- }
+ if ( createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ osi_assert(dscp != NULL);
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
}
- code = cm_SetAttr(scp, &setAttr, userp, &req);
- openAction = 3; /* truncated existing file */
}
- else
- openAction = 1; /* found existing file */
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ openAction = 3; /* truncated existing file */
+ }
+ else
+ openAction = 1; /* found existing file */
- code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
- &req);
- if (code) {
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
- }
- else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
- /* don't create if not found */
- if (dscp) cm_ReleaseSCache(dscp);
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req);
+ if (code) {
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
- return CM_ERROR_NOSUCHFILE;
- }
- else if (realDirFlag == 0 || realDirFlag == -1) {
- osi_assert(dscp != NULL);
- osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s",
- osi_LogSaveString(smb_logp, lastNamep));
- openAction = 2; /* created file */
- setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
- setAttr.clientModTime = time(NULL);
- code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
- &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ return code;
+ }
+ } else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
+ /* don't create if not found */
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_NOSUCHFILE;
+ } else if (realDirFlag == 0 || realDirFlag == -1) {
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s",
+ osi_LogSaveString(smb_logp, lastNamep));
+ openAction = 2; /* created file */
+ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
+ setAttr.clientModTime = time(NULL);
+ code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req);
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ /* Not an exclusive create, and someone else tried
+ * creating it already, then we open it anyway. We
+ * don't bother retrying after this, since if this next
+ * fails, that means that the file was deleted after we
+ * started this call.
+ */
+ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
+ userp, &req, &scp);
+ if (code == 0) {
+ if (createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
+
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ }
+ } /* lookup succeeded */
+ }
+ } else {
+ char *tp, *pp;
+ char *cp; /* This component */
+ int clen = 0; /* length of component */
+ cm_scache_t *tscp1, *tscp2;
+ int isLast = 0;
+
+ /* create directory */
+ if ( !treeCreate )
+ treeStartp = lastNamep;
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]",
+ osi_LogSaveString(smb_logp, treeStartp));
+ openAction = 2; /* created directory */
+
+ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
+ setAttr.clientModTime = time(NULL);
+
+ pp = treeStartp;
+ cp = spacep->data;
+ tscp1 = dscp;
+ cm_HoldSCache(tscp1);
+ tscp2 = NULL;
+
+ while (pp && *pp) {
+ tp = strchr(pp, '\\');
+ if (!tp) {
+ strcpy(cp,pp);
+ clen = strlen(cp);
+ isLast = 1; /* indicate last component. the supplied path never ends in a slash */
+ } else {
+ clen = tp - pp;
+ strncpy(cp,pp,clen);
+ *(cp + clen) = 0;
+ tp++;
+ }
+ pp = tp;
+
+ if (clen == 0)
+ continue; /* the supplied path can't have consecutive slashes either , but */
+
+ /* cp is the next component to be created. */
+ code = cm_MakeDir(tscp1, cp, 0, &setAttr, userp, &req);
+ if (code == 0 && (tscp1->flags & CM_SCACHEFLAG_ANYWATCH))
smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ FILE_NOTIFY_CHANGE_DIR_NAME,
+ tscp1, cp, NULL, TRUE);
+ if (code == 0 ||
+ (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) {
/* Not an exclusive create, and someone else tried
* creating it already, then we open it anyway. We
* don't bother retrying after this, since if this next
* fails, that means that the file was deleted after we
* started this call.
*/
- code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
- userp, &req, &scp);
- if (code == 0) {
- if (createDisp == FILE_OVERWRITE_IF) {
- setAttr.mask = CM_ATTRMASK_LENGTH;
- setAttr.length.LowPart = 0;
- setAttr.length.HighPart = 0;
-
- /* now watch for a symlink */
- code = 0;
- while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
- targetScp = 0;
- code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
- if (code == 0) {
- /* we have a more accurate file to use (the
- * target of the symbolic link). Otherwise,
- * we'll just use the symlink anyway.
- */
- osi_Log2(smb_logp, "symlink vp %x to vp %x",
- scp, targetScp);
- cm_ReleaseSCache(scp);
- scp = targetScp;
- }
- }
- code = cm_SetAttr(scp, &setAttr, userp, &req);
- }
- } /* lookup succeeded */
- }
- }
- else {
- char *tp, *pp;
- char *cp; /* This component */
- int clen = 0; /* length of component */
- cm_scache_t *tscp;
- int isLast = 0;
-
- /* create directory */
- if ( !treeCreate )
- treeStartp = lastNamep;
- osi_assert(dscp != NULL);
- osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]",
- osi_LogSaveString(smb_logp, treeStartp));
- openAction = 2; /* created directory */
-
- setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
- setAttr.clientModTime = time(NULL);
-
- pp = treeStartp;
- cp = spacep->data;
- tscp = dscp;
-
- while (pp && *pp) {
- tp = strchr(pp, '\\');
- if (!tp) {
- strcpy(cp,pp);
- clen = strlen(cp);
- isLast = 1; /* indicate last component. the supplied path never ends in a slash */
- }
- else {
- clen = tp - pp;
- strncpy(cp,pp,clen);
- *(cp + clen) = 0;
- tp++;
- }
- pp = tp;
-
- if (clen == 0)
- continue; /* the supplied path can't have consecutive slashes either , but */
-
- /* cp is the next component to be created. */
- code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req);
- if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- tscp, cp, NULL, TRUE);
- if (code == 0 ||
- (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) {
- /* Not an exclusive create, and someone else tried
- * creating it already, then we open it anyway. We
- * don't bother retrying after this, since if this next
- * fails, that means that the file was deleted after we
- * started this call.
- */
- code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD,
- userp, &req, &scp);
- }
- if (code) break;
+ code = cm_Lookup(tscp1, cp, CM_FLAG_CASEFOLD,
+ userp, &req, &tscp2);
+ }
+ if (code)
+ break;
- if (!isLast) { /* for anything other than dscp, release it unless it's the last one */
- cm_ReleaseSCache(tscp);
- tscp = scp; /* Newly created directory will be next parent */
- }
+ if (!isLast) { /* for anything other than dscp, release it unless it's the last one */
+ cm_ReleaseSCache(tscp1);
+ tscp1 = tscp2; /* Newly created directory will be next parent */
+ /* the hold is transfered to tscp1 from tscp2 */
}
+ }
- /*
- * if we get here and code == 0, then scp is the last directory created, and tscp is the
- * parent of scp. dscp got released if dscp != tscp. both tscp and scp are held.
- */
- dscp = tscp;
- }
+ cm_ReleaseSCache(dscp);
+ dscp = tscp1;
+ cm_ReleaseSCache(scp);
+ scp = tscp2;
+ /*
+ * if we get here and code == 0, then scp is the last directory created, and dscp is the
+ * parent of scp.
+ */
+ }
if (code) {
/* something went wrong creating or truncating the file */
- if (scp) cm_ReleaseSCache(scp);
- if (dscp) cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return code;
* target of the symbolic link). Otherwise,
* we'll just use the symlink anyway.
*/
- osi_Log2(smb_logp, "symlink vp %x to vp %x",
- scp, targetScp);
+ osi_Log2(smb_logp, "symlink vp %x to vp %x", scp, targetScp);
cm_ReleaseSCache(scp);
scp = targetScp;
}
}
if (scp->fileType != CM_SCACHETYPE_FILE) {
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
/* (only applies to single component case) */
if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
cm_ReleaseSCache(scp);
- if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return CM_ERROR_NOTDIR;
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
/* save a pointer to the vnode */
- fidp->scp = scp;
+ fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
fidp->flags = fidflags;
fidp->NTopen_wholepathp = realPathp;
/* we don't need this any longer */
- if (dscp) cm_ReleaseSCache(dscp);
+ if (dscp) {
+ cm_ReleaseSCache(dscp);
+ dscp = NULL;
+ }
cm_Open(scp, 0, userp);
/* set inp->fid so that later read calls in same msg can find fid */
return 0;
}
+
/*
* A lot of stuff copied verbatim from NT Create&X to NT Tran Create.
* Instead, ultimately, would like to use a subroutine for common code.
}
smb_SendPacket(vcp, watch);
- smb_ReleaseVC(vcp);
smb_FreePacket(watch);
watch = nextWatch;
}
((smb_t *)watch)->errHigh = 0xC0;
((smb_t *)watch)->flg2 |= SMB_FLAGS2_ERR_STATUS;
smb_SendPacket(vcp, watch);
- if (watch->vcp)
- smb_ReleaseVC(watch->vcp);
smb_FreePacket(watch);
return 0;
}
{
char *oldPathp, *newPathp;
long code = 0;
- cm_user_t *userp;
char * tp;
int attrs;
int rename_type;