From b43d778e9342dd19c010354cf6db854fdf1f7d22 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 10 Nov 2007 00:14:26 +0000 Subject: [PATCH] windows-readonly-volume-callbacks-20071109 A .readonly volume callback applies to the entire volume. Track it in the cm_volume_t cbExpiresRO field and apply it to all cm_scache_t objects with valid callbacks that are associated with that volume upon each daemon callback check. This will prevent premature callback expiration. Also, attempt to automatically refresh the callbacks every 30 minutes by obtaining a callback on the volume root. This value is configurable with the "daemonCheckVolCBInterval" registry value. Change from osi_Time() to time() for expiration values in order to permit conversion to human readable values in cmdebug. --- src/WINNT/afsd/cm_callback.c | 34 ++++++++++++++++++++++++++++++---- src/WINNT/afsd/cm_daemon.c | 16 ++++++++++++++++ src/WINNT/afsd/cm_scache.c | 8 +++++++- src/WINNT/afsd/cm_volume.c | 39 ++++++++++++++++++++++++++++++++++++++- src/WINNT/afsd/cm_volume.h | 3 +++ 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index d6d9e83..866f8d2 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -263,6 +263,11 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi cm_CallbackNotifyChange(scp); lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); + + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { + scp->volp->cbExpiresRO = 0; + } + } } /* search one hash bucket */ } /* search all hash buckets */ @@ -480,6 +485,10 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp) cm_CallbackNotifyChange(scp); lock_ObtainWrite(&cm_scacheLock); cm_ReleaseSCacheNoLock(scp); + + if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && scp->volp->cbExpiresRO != 0) + scp->volp->cbExpiresRO = 0; + } /* search one hash bucket */ } /* search all hash buckets */ @@ -737,7 +746,10 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep) cep->Length = scp->length.LowPart; cep->DataVersion = scp->dataVersion; cep->callback = afs_data_pointer_to_int32(scp->cbServerp); - cep->cbExpires = scp->cbExpires; + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) + cep->cbExpires = scp->volp->cbExpiresRO; + else + cep->cbExpires = scp->cbExpires; cep->refCount = scp->refCount; cep->opens = scp->openReads; cep->writers = scp->openWrites; @@ -848,7 +860,10 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep) #endif cep->DataVersion = scp->dataVersion; cep->callback = afs_data_pointer_to_int32(scp->cbServerp); - cep->cbExpires = scp->cbExpires; + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) + cep->cbExpires = scp->volp->cbExpiresRO; + else + cep->cbExpires = scp->cbExpires; cep->refCount = scp->refCount; cep->opens = scp->openReads; cep->writers = scp->openWrites; @@ -1525,7 +1540,7 @@ void cm_StartCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp) lock_ObtainWrite(&cm_callbackLock); cbrp->callbackCount = cm_callbackCount; cm_activeCallbackGrantingCalls++; - cbrp->startTime = osi_Time(); + cbrp->startTime = time(NULL); cbrp->serverp = NULL; lock_ReleaseWrite(&cm_callbackLock); } @@ -1543,7 +1558,7 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, cm_racingRevokes_t *nrevp; /* where we'll be next */ int freeFlag; cm_server_t * serverp = NULL; - int discardScp = 0; + int discardScp = 0, discardVolCB = 0; lock_ObtainWrite(&cm_callbackLock); if (flags & CM_CALLBACK_MAINTAINCOUNT) { @@ -1572,6 +1587,8 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, serverp = cbrp->serverp; } scp->cbExpires = cbrp->startTime + cbp->ExpirationTime; + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) + scp->volp->cbExpiresRO = scp->cbExpires; } else { if (freeFlag) serverp = cbrp->serverp; @@ -1609,6 +1626,10 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, cbrp->callbackCount, revp->callbackCount, cm_callbackCount); discardScp = 1; + + if ((scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && + (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL))) + scp->volp->cbExpiresRO = 0; } if (freeFlag) free(revp); @@ -1820,6 +1841,11 @@ void cm_CheckCBExpiration(void) for (i=0; inextp) { downTime = 0; + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { + if (scp->volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0) + scp->cbExpires = scp->volp->cbExpiresRO; + } + if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) { diff --git a/src/WINNT/afsd/cm_daemon.c b/src/WINNT/afsd/cm_daemon.c index 15aaad1..5e47a7f 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -30,6 +30,7 @@ long cm_daemonCheckDownInterval = 180; long cm_daemonCheckUpInterval = 240; long cm_daemonCheckVolInterval = 3600; long cm_daemonCheckCBInterval = 60; +long cm_daemonCheckVolCBInterval = 1800; long cm_daemonCheckLockInterval = 60; long cm_daemonTokenCheckInterval = 180; long cm_daemonCheckOfflineVolInterval = 600; @@ -269,6 +270,13 @@ cm_DaemonCheckInit(void) afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval); dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "daemonCheckVolCBInterval", NULL, NULL, + (BYTE *) &dummy, &dummyLen); + if (code == ERROR_SUCCESS) + cm_daemonCheckVolCBInterval = dummy; + afsi_log("daemonCheckVolCBInterval is %d", cm_daemonCheckVolCBInterval); + + dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS) @@ -299,6 +307,7 @@ void cm_Daemon(long parm) time_t lastLockCheck; time_t lastVolCheck; time_t lastCBExpirationCheck; + time_t lastVolCBRenewalCheck; time_t lastDownServerCheck; time_t lastUpServerCheck; time_t lastTokenCacheCheck; @@ -338,6 +347,7 @@ void cm_Daemon(long parm) now = osi_Time(); lastVolCheck = now - cm_daemonCheckVolInterval/2 + (rand() % cm_daemonCheckVolInterval); lastCBExpirationCheck = now - cm_daemonCheckCBInterval/2 + (rand() % cm_daemonCheckCBInterval); + lastVolCBRenewalCheck = now - cm_daemonCheckVolCBInterval/2 + (rand() % cm_daemonCheckVolCBInterval); lastLockCheck = now - cm_daemonCheckLockInterval/2 + (rand() % cm_daemonCheckLockInterval); lastDownServerCheck = now - cm_daemonCheckDownInterval/2 + (rand() % cm_daemonCheckDownInterval); lastUpServerCheck = now - cm_daemonCheckUpInterval/2 + (rand() % cm_daemonCheckUpInterval); @@ -396,6 +406,12 @@ void cm_Daemon(long parm) now = osi_Time(); } + if (now > lastVolCBRenewalCheck + cm_daemonCheckVolCBInterval) { + lastVolCBRenewalCheck = now; + cm_VolumeRenewROCallbacks(); + now = osi_Time(); + } + if (now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval) { lastVolCheck = now; cm_CheckOfflineVolumes(); diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 0a19d82..9b6ed5e 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -496,8 +496,14 @@ cm_SuspendSCache(void) lock_ObtainWrite(&cm_scacheLock); for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) { - if (scp->cbServerp) + if (scp->cbServerp) { + if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) { + if (scp->volp->cbExpiresRO == scp->cbExpires) { + scp->volp->cbExpiresRO = now+1; + } + } scp->cbExpires = now+1; + } } lock_ReleaseWrite(&cm_scacheLock); } diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index b3d46f8..3ee4812 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -73,7 +73,7 @@ cm_ShutdownVolume(void) cm_VolumeStatusNotification(volp, volp->ro.ID, volp->ro.state, vl_alldown); if (volp->bk.ID) cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_alldown); - + volp->cbExpiresRO = 0; lock_FinalizeMutex(&volp->mx); } @@ -114,6 +114,7 @@ void cm_InitVolume(int newFile, long maxVols) cm_VolumeStatusNotification(volp, volp->ro.ID, vl_alldown, volp->ro.state); if (volp->bk.ID) cm_VolumeStatusNotification(volp, volp->bk.ID, vl_alldown, volp->bk.state); + volp->cbExpiresRO = 0; } } osi_EndOnce(&once); @@ -764,6 +765,7 @@ long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep, volp->rw.state = volp->ro.state = volp->bk.state = vl_unknown; volp->rw.nextp = volp->ro.nextp = volp->bk.nextp = NULL; volp->rw.flags = volp->ro.flags = volp->bk.flags = 0; + volp->cbExpiresRO = 0; cm_AddVolumeToNameHashTable(volp); lock_ReleaseWrite(&cm_volumeLock); } @@ -1494,3 +1496,38 @@ enum volstatus cm_GetVolumeStatus(cm_volume_t *volp, afs_uint32 volID) } } + +void +cm_VolumeRenewROCallbacks(void) +{ + cm_volume_t * volp; + + + lock_ObtainRead(&cm_volumeLock); + for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) { + if ( volp->cbExpiresRO > 0) { + cm_req_t req; + cm_fid_t fid; + cm_scache_t * scp; + + fid.cell = volp->cellp->cellID; + fid.volume = volp->ro.ID; + fid.vnode = 1; + fid.unique = 1; + + cm_InitReq(&req); + + if (cm_GetSCache(&fid, &scp, cm_rootUserp, &req) == 0) { + lock_ReleaseRead(&cm_volumeLock); + lock_ObtainMutex(&scp->mx); + cm_GetCallback(scp, cm_rootUserp, &req, 1); + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + lock_ObtainRead(&cm_volumeLock); + } + } + } + lock_ReleaseRead(&cm_volumeLock); +} + + diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index d6f1497..2626970 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -39,6 +39,7 @@ typedef struct cm_volume { osi_mutex_t mx; afs_uint32 flags; /* by mx */ afs_uint32 refCount; /* by cm_volumeLock */ + time_t cbExpiresRO; /* latest RO expiration time; by cm_scacheLock */ } cm_volume_t; #define CM_VOLUMEFLAG_RESET 1 /* reload this info on next use */ @@ -119,4 +120,6 @@ extern void cm_UpdateVolumeStatus(cm_volume_t *volp, afs_uint32 volID); extern void cm_VolumeStatusNotification(cm_volume_t * volp, afs_uint32 volID, enum volstatus old, enum volstatus new); extern enum volstatus cm_GetVolumeStatus(cm_volume_t *volp, afs_uint32 volID); + +extern void cm_VolumeRenewROCallbacks(void); #endif /* __CM_VOLUME_H_ENV__ */ -- 1.9.4