From: Jeffrey Altman Date: Sun, 10 Jul 2011 23:19:17 +0000 (+0100) Subject: Windows: Move file server lock releases to daemon X-Git-Tag: openafs-devel-1_7_1~313 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=52fee7140325d905f01798d7c5724744b606ac06 Windows: Move file server lock releases to daemon Create a new lock daemon thread which performs regular cm_LockCheck() calls. If a lock is deleted check the cm_scache_t to see if the matching file server lock should be dropped. If yes, drop it. This effectively caches file server locks for two seconds after they are released to provide a chance for subsequent local lock requests on the same file to avoid a file server RPC. It also ensures that windows processes do not thrash the file server and force callback breaks. Change-Id: I1c452e231ff282d9b45026aed1b02ab0c5932a77 Reviewed-on: http://gerrit.openafs.org/4964 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/cm_daemon.c b/src/WINNT/afsd/cm_daemon.c index aadfc90..97cddd6 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -35,7 +35,7 @@ long cm_daemonCheckUpInterval = 240; long cm_daemonCheckVolInterval = 3600; long cm_daemonCheckCBInterval = 60; long cm_daemonCheckVolCBInterval = 0; -long cm_daemonCheckLockInterval = 60; +long cm_daemonCheckLockInterval = 2; long cm_daemonTokenCheckInterval = 180; long cm_daemonCheckOfflineVolInterval = 600; long cm_daemonPerformanceTuningInterval = 0; @@ -56,6 +56,7 @@ static int cm_nDaemons = 0; static time_t lastIPAddrChange = 0; static EVENT_HANDLE cm_Daemon_ShutdownEvent = NULL; +static EVENT_HANDLE cm_LockDaemon_ShutdownEvent = NULL; static EVENT_HANDLE cm_IPAddrDaemon_ShutdownEvent = NULL; static EVENT_HANDLE cm_BkgDaemon_ShutdownEvent[CM_MAX_DAEMONS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; @@ -360,11 +361,46 @@ cm_DaemonCheckInit(void) cm_PerformanceTuningInit(); } +/* periodic lock check daemon */ +void cm_LockDaemon(long parm) +{ + time_t now; + time_t lastLockCheck; + char * name = "cm_LockDaemon_ShutdownEvent"; + + cm_LockDaemon_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + afsi_log("Event Object Already Exists: %s", name); + + now = osi_Time(); + lastLockCheck = now - cm_daemonCheckLockInterval/2 + (rand() % cm_daemonCheckLockInterval); + + while (daemon_ShutdownFlag == 0) { + if (powerStateSuspended) { + Sleep(1000); + continue; + } + + now = osi_Time(); + + if (now > lastLockCheck + cm_daemonCheckLockInterval && + daemon_ShutdownFlag == 0 && + powerStateSuspended == 0) { + lastLockCheck = now; + cm_CheckLocks(); + if (daemon_ShutdownFlag == 1) + break; + } + + thrd_Sleep(1000); /* sleep 1 second */ + } + thrd_SetEvent(cm_LockDaemon_ShutdownEvent); +} + /* periodic check daemon */ void cm_Daemon(long parm) { time_t now; - time_t lastLockCheck; time_t lastVolCheck; time_t lastCBExpirationCheck; time_t lastVolCBRenewalCheck; @@ -420,7 +456,6 @@ void cm_Daemon(long parm) lastCBExpirationCheck = now - cm_daemonCheckCBInterval/2 + (rand() % cm_daemonCheckCBInterval); if (cm_daemonCheckVolCBInterval) 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); lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval); @@ -568,16 +603,6 @@ void cm_Daemon(long parm) now = osi_Time(); } - if (now > lastLockCheck + cm_daemonCheckLockInterval && - daemon_ShutdownFlag == 0 && - powerStateSuspended == 0) { - lastLockCheck = now; - cm_CheckLocks(); - if (daemon_ShutdownFlag == 1) - break; - now = osi_Time(); - } - if (now > lastTokenCacheCheck + cm_daemonTokenCheckInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { @@ -640,6 +665,9 @@ void cm_DaemonShutdown(void) if (cm_Daemon_ShutdownEvent) code = thrd_WaitForSingleObject_Event(cm_Daemon_ShutdownEvent, INFINITE); + if (cm_LockDaemon_ShutdownEvent) + code = thrd_WaitForSingleObject_Event(cm_LockDaemon_ShutdownEvent, INFINITE); + for ( i=0; iflags |= CM_FILELOCK_FLAG_DELETED; - cm_ReleaseUser(fileLock->userp); - cm_ReleaseSCacheNoLock(scp); - - fileLock->userp = NULL; - fileLock->scp = NULL; - n_unlocks++; } } @@ -5104,8 +5098,6 @@ long cm_UnlockByKey(cm_scache_t * scp, osi_Log1(afsd_logp, "cm_UnlockByKey done with %d locks", n_unlocks); - code = cm_IntUnlock(scp, userp, reqp); - osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code); osi_Log4(afsd_logp, " Leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]", scp->exclusiveLocks, scp->sharedLocks, scp->clientLocks, @@ -5218,19 +5210,8 @@ long cm_Unlock(cm_scache_t *scp, } fileLock->flags |= CM_FILELOCK_FLAG_DELETED; - if (userp != NULL) { - cm_ReleaseUser(fileLock->userp); - } else { - userp = fileLock->userp; - release_userp = TRUE; - } - fileLock->userp = NULL; - cm_ReleaseSCacheNoLock(scp); - fileLock->scp = NULL; lock_ReleaseWrite(&cm_scacheLock); - code = cm_IntUnlock(scp, userp, reqp); - if (release_userp) { cm_ReleaseUser(userp); release_userp = FALSE; @@ -5311,6 +5292,19 @@ void cm_CheckLocks() code = -1; if (IS_LOCK_DELETED(fileLock)) { + cm_user_t *userp = fileLock->userp; + cm_scache_t *scp = fileLock->scp; + fileLock->userp = NULL; + fileLock->scp = NULL; + + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainWrite(&scp->rw); + code = cm_IntUnlock(scp, userp, &req); + lock_ReleaseWrite(&scp->rw); + + cm_ReleaseUser(fileLock->userp); + lock_ObtainWrite(&cm_scacheLock); + cm_ReleaseSCacheNoLock(scp); osi_QRemove(&cm_allFileLocks, q); cm_PutFileLock(fileLock);