if (cp == NULL)
return NULL;
+ lock_ObtainMutex(&cp->mx);
if ((cp->vlServersp == NULL
#ifdef AFS_FREELANCE_CLIENT
&& !(cp->flags & CM_CELLFLAG_FREELANCE)
cp->timeout = time(0) + 7200;
}
}
+ lock_ReleaseMutex(&cp->mx);
return cp;
}
cm_scache_t * scp;
osi_Log4(afsd_logp, "cm_Analyze passed VNOVNODE cell %u vol %u vn %u uniq %u.",
fidp->cell, fidp->volume, fidp->vnode, fidp->unique);
- if (!cm_GetSCache(fidp, &scp, userp, reqp)) {
- cm_FlushParent(scp, userp, reqp);
- cm_FlushFile(scp, userp, reqp);
- cm_ReleaseSCache(scp);
+ scp = cm_FindSCache(fidp);
+ if (scp) {
+ cm_scache_t *pscp = cm_FindSCacheParent(scp);
+ cm_CleanFile(scp, userp, reqp);
+ cm_ReleaseSCache(scp);
+ if (pscp) {
+ if (pscp->cbExpires > 0 && pscp->cbServerp != NULL) {
+ lock_ObtainMutex(&pscp->mx);
+ cm_DiscardSCache(pscp);
+ lock_ReleaseMutex(&pscp->mx);
+ }
+ cm_ReleaseSCache(pscp);
+ }
}
} else {
osi_Log0(afsd_logp, "cm_Analyze passed VNOVNODE unknown fid.");
lock_ReleaseMutex(&scp->mx);
}
+/* Called with scp locked */
void cm_ClearPrefetchFlag(long code, cm_scache_t *scp, osi_hyper_t *base)
{
osi_hyper_t thyper;
lscpp = &tscp->nextp, tscp = tscp->nextp) {
if (tscp == scp) {
*lscpp = scp->nextp;
+ lock_ObtainMutex(&scp->mx);
scp->flags &= ~CM_SCACHEFLAG_INHASH;
+ lock_ReleaseMutex(&scp->mx);
break;
}
}
lock_InitializeMutex(&cm_Afsdsbmt_Lock, "AFSDSBMT.INI Access Lock");
}
+long cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+{
+ long code;
+
+ lock_ObtainWrite(&scp->bufCreateLock);
+ code = buf_CleanVnode(scp, userp, reqp);
+
+ lock_ObtainMutex(&scp->mx);
+ cm_DiscardSCache(scp);
+ lock_ReleaseMutex(&scp->mx);
+
+ lock_ReleaseWrite(&scp->bufCreateLock);
+ osi_Log2(afsd_logp,"cm_CleanFile scp 0x%x returns error: [%x]",scp, code);
+ return code;
+}
+
long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
long code;
code = buf_FlushCleanPages(scp, userp, reqp);
lock_ObtainMutex(&scp->mx);
- scp->cbServerp = NULL;
- scp->cbExpires = 0;
- cm_dnlcPurgedp(scp);
- cm_dnlcPurgevp(scp);
- cm_FreeAllACLEnts(scp);
-
- /* Force mount points and symlinks to be re-evaluated */
- scp->mountPointStringp[0] = '\0';
+ cm_DiscardSCache(scp);
lock_ReleaseMutex(&scp->mx);
long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
long code = 0;
- int i;
- cm_fid_t parent_fid;
-
- lock_ObtainWrite(&cm_scacheLock);
- cm_HoldSCacheNoLock(scp);
- parent_fid = scp->fid;
- parent_fid.vnode = scp->parentVnode;
- parent_fid.unique = scp->parentUnique;
- cm_ReleaseSCacheNoLock(scp);
-
- for (i=0; i<cm_data.hashTableSize; i++) {
- for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
- if (!cm_FidCmp(&scp->fid, &parent_fid)) {
- cm_HoldSCacheNoLock(scp);
- lock_ReleaseWrite(&cm_scacheLock);
-
- /* now flush the file */
- code = cm_FlushFile(scp, userp, reqp);
- lock_ObtainWrite(&cm_scacheLock);
- cm_ReleaseSCacheNoLock(scp);
- }
- }
- }
- lock_ReleaseWrite(&cm_scacheLock);
+ cm_scache_t * pscp;
+
+ pscp = cm_FindSCacheParent(scp);
+
+ /* now flush the file */
+ code = cm_FlushFile(pscp, userp, reqp);
+ cm_ReleaseSCache(scp);
return code;
}
for (cp = cm_data.allCellsp; cp; cp=cp->nextp)
{
long code;
+ lock_ObtainMutex(&cp->mx);
/* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
cm_FreeServerList(&cp->vlServersp);
cp->vlServersp = NULL;
cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
cm_RandomizeServer(&cp->vlServersp);
}
+ lock_ReleaseMutex(&cp->mx);
}
lock_ReleaseWrite(&cm_cellLock);
extern long cm_IoctlCreateMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern long cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+
extern long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
extern long cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
mp = "";
}
scp = cm_GetNewSCache();
-
+
+ lock_ObtainMutex(&scp->mx);
scp->fid = *fidp;
scp->volp = cm_data.rootSCachep->volp;
scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID;
scp->group=0;
scp->dataVersion=cm_data.fakeDirVersion;
scp->lockDataVersion=-1; /* no lock yet */
+ lock_ReleaseMutex(&scp->mx);
*outScpp = scp;
lock_ReleaseWrite(&cm_scacheLock);
- /*afsi_log(" getscache done");*/
return 0;
}
// end of yj code
/* now, if we don't have the fid, recycle something */
scp = cm_GetNewSCache();
osi_assert(!(scp->flags & CM_SCACHEFLAG_INHASH));
+ lock_ObtainMutex(&scp->mx);
scp->fid = *fidp;
scp->volp = volp; /* a held reference */
cm_data.hashTablep[hash] = scp;
scp->flags |= CM_SCACHEFLAG_INHASH;
scp->refCount = 1;
+ lock_ReleaseMutex(&scp->mx);
/* XXX - The following fields in the cm_scache are
* uninitialized:
return 0;
}
+/* Returns a held reference to the scache's parent
+ * if it exists */
+cm_scache_t * cm_FindSCacheParent(cm_scache_t * scp)
+{
+ long code = 0;
+ int i;
+ cm_fid_t parent_fid;
+ cm_scache_t * pscp = NULL;
+
+ lock_ObtainWrite(&cm_scacheLock);
+ parent_fid = scp->fid;
+ parent_fid.vnode = scp->parentVnode;
+ parent_fid.unique = scp->parentUnique;
+
+ if (cm_FidCmp(&scp->fid, &parent_fid)) {
+ for (i=0; i<cm_data.hashTableSize; i++) {
+ for (pscp = cm_data.hashTablep[i]; pscp; pscp = pscp->nextp) {
+ if (!cm_FidCmp(&pscp->fid, &parent_fid)) {
+ cm_HoldSCacheNoLock(pscp);
+ break;
+ }
+ }
+ }
+ }
+ lock_ReleaseWrite(&cm_scacheLock);
+
+ return pscp;
+}
+
/* synchronize a fetch, store, read, write, fetch status or store status.
* Called with scache mutex held, and returns with it held, but temporarily
* drops it during the fetch.
scp->cbServerp = NULL;
}
scp->cbExpires = 0;
+ scp->flags &= ~CM_SCACHEFLAG_CALLBACK;
cm_dnlcPurgedp(scp);
cm_dnlcPurgevp(scp);
cm_FreeAllACLEnts(scp);
+
+ /* Force mount points and symlinks to be re-evaluated */
+ scp->mountPointStringp[0] = '\0';
}
void cm_AFSFidFromFid(AFSFid *afsFidp, cm_fid_t *fidp)
extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp);
+extern cm_scache_t *cm_FindSCacheParent(cm_scache_t *);
+
extern osi_rwlock_t cm_scacheLock;
extern osi_queue_t *cm_allFileLocks;
if ( !dnlcHit && !(flags & CM_FLAG_NOMOUNTCHASE) && rock.ExactFound ) {
/* lock the directory entry to prevent racing callback revokes */
lock_ObtainMutex(&dscp->mx);
- if ( dscp->cbServerp && dscp->cbExpires )
+ if ( dscp->cbServerp != NULL && dscp->cbExpires > 0 )
cm_dnlcEnter(dscp, namep, tscp);
lock_ReleaseMutex(&dscp->mx);
}
static char *illegalChars = "\\/:*?\"<>|";
BOOL isWindows2000 = FALSE;
-smb_vc_t *dead_vcp = NULL;
smb_vc_t *active_vcp = NULL;
int smbShutdownFlag = 0;
if (fid == fidp->fid) {
if (newFid) {
fid++;
- if (fid == 0) {
+ if (fid == 0xFFFF) {
osi_Log1(smb_logp,
"New FID number wraps on vcp 0x%x", vcp);
fid = 1;
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
thrd_CloseHandle(event);
fid++;
- if (fid == 0) {
+ if (fid == 0xFFFF) {
osi_Log1(smb_logp, "New FID wraps around for vcp 0x%x", vcp);
fid = 1;
}
*/
if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) {
/* hold and delete */
+ lock_ObtainMutex(&tp->mx);
tp->flags |= SMB_DIRSEARCH_DELETE;
+ lock_ReleaseMutex(&tp->mx);
victimsp[victimCount++] = tp;
tp->refCount++;
}
LogEvent(EVENTLOG_WARNING_TYPE, MSG_SMB_SEND_PACKET_FAILURE, s);
#endif /* !DJGPP */
- 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);
+ osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
+ vcp, vcp->usersp);
lock_ObtainWrite(&smb_globalLock);
- if (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);
- }
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseMutex(&vcp->mx);
+ lock_ReleaseWrite(&smb_globalLock);
+ smb_CleanupDeadVC(vcp);
}
if (localNCB)
tcounter++; /* which proto entry we're looking at */
}
+ lock_ObtainMutex(&vcp->mx);
if (NTProtoIndex != -1) {
protoIndex = NTProtoIndex;
vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
vcp->flags |= SMB_VCFLAG_USECORE;
}
else protoIndex = -1;
+ lock_ReleaseMutex(&vcp->mx);
if (protoIndex == -1)
return CM_ERROR_INVAL;
truncAttr.length.HighPart = 0;
lock_ObtainMutex(&fidp->mx);
code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req);
+ fidp->flags |= SMB_FID_LENGTHSETDONE;
lock_ReleaseMutex(&fidp->mx);
smb_SetSMBParm(outp, 0, /* count */ 0);
smb_SetSMBDataLength(outp, 0);
- fidp->flags |= SMB_FID_LENGTHSETDONE;
goto done;
}
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
if (vcp) {
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",
+ if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
vcp, vcp->usersp);
- if (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_sessions[vcp->session] = TRUE;
lock_ReleaseMutex(&vcp->mx);
+ lock_ReleaseWrite(&smb_globalLock);
+ smb_CleanupDeadVC(vcp);
+ smb_ReleaseVC(vcp);
vcp = NULL;
}
}
if (vcp && vcp->errorCount++ > 3) {
osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount);
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",
+ if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ osi_Log2(smb_logp, "marking 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);
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ dead_sessions[vcp->session] = TRUE;
+ lock_ReleaseMutex(&vcp->mx);
+ lock_ReleaseWrite(&smb_globalLock);
+ smb_CleanupDeadVC(vcp);
+ smb_ReleaseVC(vcp);
vcp = NULL;
}
goto doneWithNCB;