* without network, the stat cache item will still be
* considered valid.
*/
- now = osi_Time();
+ now = time(NULL);
lock_ObtainWrite(&cm_scacheLock);
for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) {
long code;
cm_volume_t *volp = NULL;
cm_cell_t *cellp;
- char* mp = NULL;
int special; // yj: boolean variable to test if file is on root.afs
int isRoot;
extern cm_fid_t cm_rootFid;
}
if (cm_freelanceEnabled && special) {
+ char mp[MOUNTPOINTLEN] = "";
+ afs_uint32 fileType;
+
osi_Log0(afsd_logp,"cm_GetSCache Freelance and special");
- if (fidp->vnode > 1 && fidp->vnode <= cm_noLocalMountPoints + 2) {
- lock_ObtainMutex(&cm_Freelance_Lock);
- mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp;
- lock_ReleaseMutex(&cm_Freelance_Lock);
+ lock_ObtainMutex(&cm_Freelance_Lock);
+ if (fidp->vnode >= 2 && fidp->vnode - 2 < cm_noLocalMountPoints) {
+ strncpy(mp,(cm_localMountPoints+fidp->vnode-2)->mountPointStringp, MOUNTPOINTLEN);
+ mp[MOUNTPOINTLEN-1] = '\0';
+ if ( !strnicmp(mp, "msdfs:", strlen("msdfs:")) )
+ fileType = CM_SCACHETYPE_DFSLINK;
+ else
+ fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
} else {
- mp = "";
+ fileType = CM_SCACHETYPE_INVALID;
+
}
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
scp = cm_GetNewSCache();
if (scp == NULL) {
osi_Log0(afsd_logp,"cm_GetSCache unable to obtain *new* scache entry");
scp->flags |= CM_SCACHEFLAG_INHASH;
scp->refCount = 1;
osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp);
- if (fidp->vnode > 1 && fidp->vnode <= cm_noLocalMountPoints + 2)
- scp->fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
- else
- scp->fileType = CM_SCACHETYPE_INVALID;
-
- lock_ObtainMutex(&cm_Freelance_Lock);
+ scp->fileType = fileType;
scp->length.LowPart = (DWORD)strlen(mp)+4;
scp->length.HighPart = 0;
strncpy(scp->mountPointStringp,mp,MOUNTPOINTLEN);
- scp->mountPointStringp[MOUNTPOINTLEN-1] = '\0';
- lock_ReleaseMutex(&cm_Freelance_Lock);
-
scp->owner=0x0;
scp->unixModeBits=0777;
scp->clientModTime=FakeFreelanceModTime;
/* otherwise, we need to find the volume */
if (!cm_freelanceEnabled || !isRoot) {
lock_ReleaseWrite(&cm_scacheLock); /* for perf. reasons */
- cellp = cm_FindCellByID(fidp->cell);
+ cellp = cm_FindCellByID(fidp->cell, 0);
if (!cellp)
return CM_ERROR_NOSUCHCELL;
cm_fid_t parent_fid;
cm_scache_t * pscp = NULL;
- lock_ObtainRead(&cm_scacheLock);
+ lock_ObtainWrite(&cm_scacheLock);
parent_fid = scp->fid;
parent_fid.vnode = scp->parentVnode;
parent_fid.unique = scp->parentUnique;
}
}
- lock_ReleaseRead(&cm_scacheLock);
+ lock_ReleaseWrite(&cm_scacheLock);
return pscp;
}
scp->waitCount = scp->waitRequests = 1;
}
- if (bufLocked)
- lock_ReleaseMutex(&bufp->mx);
-
cm_SyncOpAddToWaitQueue(scp, flags, bufp);
wakeupCycle = 0;
do {
- if (wakeupCycle++ != 0)
- lock_ObtainMutex(&scp->mx);
+ if (bufLocked)
+ lock_ReleaseMutex(&bufp->mx);
osi_SleepM((LONG_PTR) &scp->flags, &scp->mx);
+ if (bufLocked)
+ lock_ObtainMutex(&bufp->mx);
+ lock_ObtainMutex(&scp->mx);
} while (!cm_SyncOpCheckContinue(scp, flags, bufp));
smb_UpdateServerPriority();
- if (bufLocked)
- lock_ObtainMutex(&bufp->mx);
- lock_ObtainMutex(&scp->mx);
scp->waitCount--;
osi_Log3(afsd_logp, "CM SyncOp woke! scp 0x%p; still waiting %d threads of %d requests",
scp, scp->waitCount, scp->waitRequests);
statusp->Group = 0;
statusp->SyncCounter = 0;
statusp->dataVersionHigh = (afs_uint32)(cm_data.fakeDirVersion >> 32);
- statusp->errorCode = 0;
+ statusp->errorCode = 0;
+
+ buf_ForceDataVersion(scp, scp->dataVersion, cm_data.fakeDirVersion);
}
#endif /* AFS_FREELANCE_CLIENT */
if (!(flags & CM_MERGEFLAG_FORCE) && dataVersion < scp->dataVersion) {
struct cm_cell *cellp;
- cellp = cm_FindCellByID(scp->fid.cell);
+ cellp = cm_FindCellByID(scp->fid.cell, 0);
if (scp->cbServerp) {
struct cm_volume *volp = NULL;
}
if ((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion == 1) {
- cm_buf_t *bp;
-
- for (bp = cm_data.buf_fileHashTablepp[BUF_FILEHASH(&scp->fid)]; bp; bp=bp->fileHashp)
+ buf_ForceDataVersion(scp, scp->dataVersion, dataVersion);
+ } else if (scp->dataVersion != 0 &&
+ (!(flags & CM_MERGEFLAG_DIROP) && dataVersion != scp->dataVersion ||
+ (flags & CM_MERGEFLAG_DIROP) && dataVersion - scp->dataVersion > 1)) {
+ /*
+ * We now know that all of the data buffers that we have associated
+ * with this scp are invalid. Subsequent operations will go faster
+ * if the buffers are removed from the hash tables.
+ *
+ * We do not remove directory buffers if the dataVersion delta is 1 because
+ * those version numbers will be updated as part of the directory operation.
+ */
+ int i, j;
+ cm_buf_t **lbpp;
+ cm_buf_t *tbp;
+ cm_buf_t *bp, *prevBp, *nextBp;
+
+ lock_ObtainWrite(&buf_globalLock);
+ i = BUF_FILEHASH(&scp->fid);
+ for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp=nextBp)
{
- if (cm_FidCmp(&scp->fid, &bp->fid) == 0 &&
- bp->dataVersion == scp->dataVersion)
- bp->dataVersion = dataVersion;
+ nextBp = bp->fileHashp;
+
+ if (cm_FidCmp(&scp->fid, &bp->fid) == 0) {
+ prevBp = bp->fileHashBackp;
+ bp->fileHashBackp = bp->fileHashp = NULL;
+ if (prevBp)
+ prevBp->fileHashp = nextBp;
+ else
+ cm_data.buf_fileHashTablepp[i] = nextBp;
+ if (nextBp)
+ nextBp->fileHashBackp = prevBp;
+
+ j = BUF_HASH(&bp->fid, &bp->offset);
+ lbpp = &(cm_data.buf_scacheHashTablepp[j]);
+ for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) {
+ if (tbp == bp)
+ break;
+ }
+
+ *lbpp = bp->hashp; /* hash out */
+ bp->hashp = NULL;
+
+ bp->flags &= ~CM_BUF_INHASH;
+ }
}
+ lock_ReleaseWrite(&buf_globalLock);
}
scp->dataVersion = dataVersion;
}
cm_dnlcPurgevp(scp);
cm_FreeAllACLEnts(scp);
+ if (scp->fileType == CM_SCACHETYPE_DFSLINK)
+ cm_VolStatus_Invalidate_DFS_Mapping(scp);
+
/* Force mount points and symlinks to be re-evaluated */
scp->mountPointStringp[0] = '\0';
}
#endif
{
osi_assertx(scp != NULL, "null cm_scache_t");
+ lock_AssertWrite(&cm_scacheLock);
scp->refCount++;
#ifdef DEBUG_REFCOUNT
osi_Log2(afsd_logp,"cm_HoldSCacheNoLock scp 0x%p ref %d",scp, scp->refCount);
#endif
{
osi_assertx(scp != NULL, "null cm_scache_t");
+ lock_AssertWrite(&cm_scacheLock);
if (scp->refCount == 0)
osi_Log1(afsd_logp,"cm_ReleaseSCacheNoLock about to panic scp 0x%x",scp);
osi_assertx(scp->refCount-- >= 0, "cm_scache_t refCount 0");
for (scp = cm_data.allSCachesp; scp; scp = scp->allNextp)
{
- sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) volp=0x%p type=%d dv=%d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n",
+ sprintf(output, "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) volp=0x%p type=%d dv=%I64d len=0x%I64x mp='%s' flags=0x%x cb=0x%x refCount=%u\r\n",
cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
scp->volp, scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp, scp->flags,
(unsigned long)scp->cbExpires, scp->refCount);