/*
* When we lose a callback, may have to send change notification replies.
+ * Do not call with a lock on the scp.
*/
void cm_CallbackNotifyChange(cm_scache_t *scp)
{
osi_Log2(afsd_logp, "CallbackNotifyChange FileType %d Flags %lX",
scp->fileType, scp->flags);
- if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
- if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(0,
- FILE_NOTIFY_GENERIC_DIRECTORY_FILTER,
- scp, NULL, NULL, TRUE);
- } else {
- cm_fid_t tfid;
- cm_scache_t *dscp;
-
- tfid.cell = scp->fid.cell;
- tfid.volume = scp->fid.volume;
- tfid.vnode = scp->parentVnode;
- tfid.unique = scp->parentUnique;
- dscp = cm_FindSCache(&tfid);
- if (dscp &&
- dscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(0,
- FILE_NOTIFY_GENERIC_FILE_FILTER,
- dscp, NULL, NULL, TRUE);
- if (dscp) cm_ReleaseSCache(dscp);
- }
+ if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
+ if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(0,
+ FILE_NOTIFY_GENERIC_DIRECTORY_FILTER,
+ scp, NULL, NULL, TRUE);
+ } else {
+ cm_fid_t tfid;
+ cm_scache_t *dscp;
+
+ tfid.cell = scp->fid.cell;
+ tfid.volume = scp->fid.volume;
+ tfid.vnode = scp->parentVnode;
+ tfid.unique = scp->parentUnique;
+ dscp = cm_FindSCache(&tfid);
+ if (dscp &&
+ dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange( 0,
+ FILE_NOTIFY_GENERIC_FILE_FILTER,
+ dscp, NULL, NULL, TRUE);
+ if (dscp) cm_ReleaseSCache(dscp);
+ }
}
/* called with no locks held for every file ID that is revoked directly by
int fdc, fgc;
if (cm_freelanceEnabled &&
- scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
- scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) { // if it's something on /afs
- if (!(scp->fid.vnode==0x1 && scp->fid.unique==0x1)) // if it's not root.afs
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
+ /* if it's something on /afs */
+ if (!(scp->fid.vnode==0x1 && scp->fid.unique==0x1)) {
+ /* if it's not root.afs */
return 1;
- else {
+ }
+
lock_ObtainMutex(&cm_Freelance_Lock);
fdc = cm_fakeDirCallback;
fgc = cm_fakeGettingCallback;
}
return 0;
}
- }
#endif
if (scp->cbServerp != NULL)
return 1;
- else return 0;
+ else
+ return 0;
}
/* need to detect a broken callback that races with our obtaining a callback.
cm_racingRevokes_t *revp; /* where we are */
cm_racingRevokes_t *nrevp; /* where we'll be next */
int freeFlag;
+ cm_server_t * serverp = 0;
lock_ObtainWrite(&cm_callbackLock);
if (flags & CM_CALLBACK_MAINTAINCOUNT) {
else {
osi_assert(cm_activeCallbackGrantingCalls-- > 0);
}
- if (cm_activeCallbackGrantingCalls == 0) freeFlag = 1;
- else freeFlag = 0;
+ if (cm_activeCallbackGrantingCalls == 0)
+ freeFlag = 1;
+ else
+ freeFlag = 0;
/* record the callback; we'll clear it below if we really lose it */
+ if (cbrp) {
if (scp) {
+ if (scp->cbServerp != cbrp->serverp) {
+ serverp = scp->cbServerp;
+ }
scp->cbServerp = cbrp->serverp;
scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
+ } else {
+ serverp = cbrp->serverp;
+ }
+ cbrp->serverp = NULL;
}
/* a callback was actually revoked during our granting call, so
* callback-granting call, and if this fid is the right fid,
* then clear the callback.
*/
- if (scp && cbrp->callbackCount != cm_callbackCount
+ if (scp && cbrp && cbrp->callbackCount != cm_callbackCount
&& revp->callbackCount > cbrp->callbackCount
&& (( scp->fid.volume == revp->fid.volume &&
scp->fid.vnode == revp->fid.vnode &&
if (freeFlag) cm_racingRevokesp = NULL;
lock_ReleaseWrite(&cm_callbackLock);
+
+ if ( serverp ) {
+ lock_ObtainWrite(&cm_serverLock);
+ cm_FreeServer(serverp);
+ lock_ReleaseWrite(&cm_serverLock);
+ }
}
/* if flags is 1, we want to force the code to make one call, anyway.
scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
scp->fid.unique==0x1 &&
scp->fid.vnode==0x1) {
+
// Start by indicating that we're in the process
// of fetching the callback
-
lock_ObtainMutex(&cm_Freelance_Lock);
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=1");
cm_fakeGettingCallback = 1;
lock_ReleaseMutex(&cm_Freelance_Lock);
// Indicate that the callback is not done
lock_ObtainMutex(&cm_Freelance_Lock);
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeDirCallback=2");
cm_fakeDirCallback = 2;
+
// Indicate that we're no longer fetching the callback
+ osi_Log0(afsd_logp,"cm_getGetCallback fakeGettingCallback=0");
cm_fakeGettingCallback = 0;
lock_ReleaseMutex(&cm_Freelance_Lock);
cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
}
else
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+ cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0);
/* now check to see if we got an error */
if (code) return code;
/* called periodically by cm_daemon to shut down use of expired callbacks */
void cm_CheckCBExpiration(void)
{
- int i;
- cm_scache_t *scp;
- long now;
+ int i;
+ cm_scache_t *scp;
+ long now;
osi_Log0(afsd_logp, "CheckCBExpiration");
- now = osi_Time();
- lock_ObtainWrite(&cm_scacheLock);
- for(i=0; i<cm_hashTableSize; i++) {
- for(scp = cm_hashTablep[i]; scp; scp=scp->nextp) {
- scp->refCount++;
- lock_ReleaseWrite(&cm_scacheLock);
- lock_ObtainMutex(&scp->mx);
- if (scp->cbServerp && now > scp->cbExpires) {
- osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
- cm_DiscardSCache(scp);
- }
- lock_ReleaseMutex(&scp->mx);
- lock_ObtainWrite(&cm_scacheLock);
- osi_assert(scp->refCount-- > 0);
- }
+ now = osi_Time();
+ lock_ObtainWrite(&cm_scacheLock);
+ for(i=0; i<cm_hashTableSize; i++) {
+ for(scp = cm_hashTablep[i]; scp; scp=scp->nextp) {
+ scp->refCount++;
+ lock_ReleaseWrite(&cm_scacheLock);
+ if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) {
+ osi_Log1(afsd_logp, "Callback Expiration Discarding SCache scp %x", scp);
+ cm_CallbackNotifyChange(scp);
+ lock_ObtainMutex(&scp->mx);
+ cm_DiscardSCache(scp);
+ lock_ReleaseMutex(&scp->mx);
+ }
+ lock_ObtainWrite(&cm_scacheLock);
+ osi_assert(scp->refCount-- > 0);
}
- lock_ReleaseWrite(&cm_scacheLock);
+ }
+ lock_ReleaseWrite(&cm_scacheLock);
}
/* debug interface: not implemented */