From 77cb2308719ad453742a14e094674ab38d104f96 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 10 Nov 2007 00:15:55 +0000 Subject: [PATCH] DEVEL15-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. (cherry picked from commit b43d778e9342dd19c010354cf6db854fdf1f7d22) --- 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 00cd50502..ee45a2c34 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -267,6 +267,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 */ @@ -484,6 +489,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 */ @@ -741,7 +750,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; @@ -852,7 +864,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; @@ -1529,7 +1544,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); } @@ -1547,7 +1562,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) { @@ -1576,6 +1591,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; @@ -1613,6 +1630,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); @@ -1824,6 +1845,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 01f52a667..7b2df639c 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -34,6 +34,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; @@ -274,6 +275,13 @@ cm_DaemonCheckInit(void) cm_daemonCheckCBInterval = dummy; 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); @@ -305,6 +313,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; @@ -344,6 +353,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); @@ -402,6 +412,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 0ae96a995..6a43d8275 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -498,8 +498,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 79f61d402..a4a2b6f3e 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -77,7 +77,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); } @@ -118,6 +118,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); @@ -768,6 +769,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); } @@ -1498,3 +1500,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 d6f149772..26269709f 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__ */ -- 2.39.5