From: Jeffrey Altman Date: Sat, 30 Aug 2008 03:08:20 +0000 (+0000) Subject: windows-buf-shutdown-20080829 X-Git-Tag: openafs-devel-1_5_61~855 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=ccdf50ade371de595abe20f5a6b0ff149ce9ae79 windows-buf-shutdown-20080829 LICENSE MIT During buf_Shutdown() all dirty buffers should be written to the file server if they can be. --- diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 3a72373..710764a 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -213,73 +213,86 @@ void buf_Release(cm_buf_t *bp) } } -/* incremental sync daemon. Writes all dirty buffers every 5000 ms */ -void buf_IncrSyncer(long parm) +long +buf_Sync(int quitOnShutdown) { cm_buf_t **bpp, *bp, *prevbp; - long i; /* counter */ long wasDirty = 0; cm_req_t req; - while (buf_ShutdownFlag == 0) { - if (!wasDirty) { - i = SleepEx(5000, 1); - if (i != 0) continue; - } - - wasDirty = 0; + /* go through all of the dirty buffers */ + lock_ObtainRead(&buf_globalLock); + for (bpp = &cm_data.buf_dirtyListp, prevbp = NULL; bp = *bpp; ) { + if (quitOnShutdown && buf_ShutdownFlag) + break; - /* go through all of the dirty buffers */ - lock_ObtainRead(&buf_globalLock); - for (bpp = &cm_data.buf_dirtyListp, prevbp = NULL; bp = *bpp; ) { - lock_ReleaseRead(&buf_globalLock); - /* all dirty buffers are held when they are added to the - * dirty list. No need for an additional hold. - */ - lock_ObtainMutex(&bp->mx); + lock_ReleaseRead(&buf_globalLock); + /* all dirty buffers are held when they are added to the + * dirty list. No need for an additional hold. + */ + lock_ObtainMutex(&bp->mx); - if (bp->flags & CM_BUF_DIRTY) { - /* start cleaning the buffer; don't touch log pages since - * the log code counts on knowing exactly who is writing - * a log page at any given instant. - */ - cm_InitReq(&req); - req.flags |= CM_REQ_NORETRY; - wasDirty |= buf_CleanAsyncLocked(bp, &req); - } + if (bp->flags & CM_BUF_DIRTY) { + /* start cleaning the buffer; don't touch log pages since + * the log code counts on knowing exactly who is writing + * a log page at any given instant. + */ + cm_InitReq(&req); + req.flags |= CM_REQ_NORETRY; + wasDirty |= buf_CleanAsyncLocked(bp, &req); + } - /* the buffer may or may not have been dirty - * and if dirty may or may not have been cleaned - * successfully. check the dirty flag again. - */ - if (!(bp->flags & CM_BUF_DIRTY)) { - /* remove the buffer from the dirty list */ - lock_ObtainWrite(&buf_globalLock); + /* the buffer may or may not have been dirty + * and if dirty may or may not have been cleaned + * successfully. check the dirty flag again. + */ + if (!(bp->flags & CM_BUF_DIRTY)) { + /* remove the buffer from the dirty list */ + lock_ObtainWrite(&buf_globalLock); #ifdef DEBUG_REFCOUNT - if (bp->dirtyp == NULL && bp != cm_data.buf_dirtyListEndp) { - osi_Log1(afsd_logp,"buf_IncrSyncer bp 0x%p list corruption",bp); - afsi_log("buf_IncrSyncer bp 0x%p list corruption", bp); - } -#endif - *bpp = bp->dirtyp; - bp->dirtyp = NULL; - bp->flags &= ~CM_BUF_INDL; - if (cm_data.buf_dirtyListp == NULL) - cm_data.buf_dirtyListEndp = NULL; - else if (cm_data.buf_dirtyListEndp == bp) - cm_data.buf_dirtyListEndp = prevbp; - buf_ReleaseLocked(bp, TRUE); - lock_ConvertWToR(&buf_globalLock); - } else { - /* advance the pointer so we don't loop forever */ - lock_ObtainRead(&buf_globalLock); - bpp = &bp->dirtyp; - prevbp = bp; + if (bp->dirtyp == NULL && bp != cm_data.buf_dirtyListEndp) { + osi_Log1(afsd_logp,"buf_IncrSyncer bp 0x%p list corruption",bp); + afsi_log("buf_IncrSyncer bp 0x%p list corruption", bp); } - lock_ReleaseMutex(&bp->mx); - } /* for loop over a bunch of buffers */ - lock_ReleaseRead(&buf_globalLock); - } /* whole daemon's while loop */ +#endif + *bpp = bp->dirtyp; + bp->dirtyp = NULL; + bp->flags &= ~CM_BUF_INDL; + if (cm_data.buf_dirtyListp == NULL) + cm_data.buf_dirtyListEndp = NULL; + else if (cm_data.buf_dirtyListEndp == bp) + cm_data.buf_dirtyListEndp = prevbp; + buf_ReleaseLocked(bp, TRUE); + lock_ConvertWToR(&buf_globalLock); + } else { + /* advance the pointer so we don't loop forever */ + lock_ObtainRead(&buf_globalLock); + bpp = &bp->dirtyp; + prevbp = bp; + } + lock_ReleaseMutex(&bp->mx); + } /* for loop over a bunch of buffers */ + lock_ReleaseRead(&buf_globalLock); + + return wasDirty; +} + +/* incremental sync daemon. Writes all dirty buffers every 5000 ms */ +void buf_IncrSyncer(long parm) +{ + long wasDirty = 0; + long i; + + while (buf_ShutdownFlag == 0) { + + if (!wasDirty) { + i = SleepEx(5000, 1); + if (i != 0) + continue; + } + + wasDirty = buf_Sync(1); + } /* whole daemon's while loop */ } long @@ -359,8 +372,12 @@ buf_ValidateBuffers(void) } void buf_Shutdown(void) -{ +{ + /* disable the buf_IncrSyncer() threads */ buf_ShutdownFlag = 1; + + /* then force all dirty buffers to the file servers */ + buf_Sync(0); } /* initialize the buffer package; called with no locks