From 2033fa9ec62089887f074381ac118a2c60e9c311 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 9 Jun 2009 00:58:10 +0000 Subject: [PATCH] windows-dirty-buffers-20090608 LICENSE MIT In the buf_IncrSync thread, if the volume is known to be unavailable do not attempt to write the buffer. Just skip it. In buf_Sync(), if we are shutting down and a buffer is left dirty, log a message to the Windows Event Log indicating that the dirty buffer was lost. --- src/WINNT/afsd/afsd_eventlog.c | 13 +++++++ src/WINNT/afsd/afsd_eventmessages.mc | 8 +++++ src/WINNT/afsd/cm_buf.c | 52 ++++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/afsd_eventlog.c b/src/WINNT/afsd/afsd_eventlog.c index 756392bd7..58027fb02 100644 --- a/src/WINNT/afsd/afsd_eventlog.c +++ b/src/WINNT/afsd/afsd_eventlog.c @@ -289,6 +289,19 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...) lpArgs[1] = lpStrings[1]; lpArgs[2] = va_arg(listArgs,LPTSTR); break; + case MSG_DIRTY_BUFFER_AT_SHUTDOWN: + wNumArgs = 6; + lpArgs[0] = va_arg(listArgs, LPTSTR); + lpArgs[1] = va_arg(listArgs, LPTSTR); + StringCbPrintf(lpStrings[2],STRLEN,"%u",va_arg(listArgs,int)); + StringCbPrintf(lpStrings[3],STRLEN,"%u",va_arg(listArgs,int)); + StringCbPrintf(lpStrings[4],STRLEN,"%I64u",va_arg(listArgs,afs_int64)); + StringCbPrintf(lpStrings[5],STRLEN,"%I64u",va_arg(listArgs,afs_int64)); + lpArgs[2] = lpStrings[2]; + lpArgs[3] = lpStrings[3]; + lpArgs[4] = lpStrings[4]; + lpArgs[5] = lpStrings[5]; + break; } va_end(listArgs); diff --git a/src/WINNT/afsd/afsd_eventmessages.mc b/src/WINNT/afsd/afsd_eventmessages.mc index 37c76a0be..c2afae452 100644 --- a/src/WINNT/afsd/afsd_eventmessages.mc +++ b/src/WINNT/afsd/afsd_eventmessages.mc @@ -374,4 +374,12 @@ Language=English MaxBufferSize for client is too small (Client=%1, Server=%2). . +MessageId= +Severity=Warning +Facility=System +SymbolicName=MSG_DIRTY_BUFFER_AT_SHUTDOWN +Language=English +A dirty buffer was not written to the file server (Cell=%1, Volume=%2, Vnode=%3, Unique=%4, Offset=%5, Length=%6). +. + ;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */ diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 245e0947c..9e7e7ce04 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -234,15 +234,25 @@ buf_Sync(int quitOnShutdown) if (bp->flags & CM_BUF_DIRTY && !(bp->flags & CM_BUF_REDIR)) { /* 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. - */ + * the log code counts on knowing exactly who is writing + * a log page at any given instant. + * + * only attempt to write the buffer if the volume might + * be online. + */ afs_uint32 dirty; + cm_volume_t * volp; - cm_InitReq(&req); - req.flags |= CM_REQ_NORETRY; - buf_CleanAsyncLocked(bp, &req, &dirty); - wasDirty |= dirty; + volp = cm_GetVolumeByFID(&bp->fid); + switch (cm_GetVolumeStatus(volp, bp->fid.volume)) { + case vl_online: + case vl_unknown: + cm_InitReq(&req); + req.flags |= CM_REQ_NORETRY; + buf_CleanAsyncLocked(bp, &req, &dirty); + wasDirty |= dirty; + } + cm_PutVolume(volp); } /* the buffer may or may not have been dirty @@ -268,6 +278,34 @@ buf_Sync(int quitOnShutdown) buf_ReleaseLocked(bp, TRUE); lock_ConvertWToR(&buf_globalLock); } else { + if (buf_ShutdownFlag) { + cm_cell_t *cellp; + cm_volume_t *volp; + char volstr[VL_MAXNAMELEN+12]=""; + char *ext = ""; + + volp = cm_GetVolumeByFID(&bp->fid); + if (volp) { + cellp = volp->cellp; + if (bp->fid.volume == volp->vol[RWVOL].ID) + ext = ""; + else if (bp->fid.volume == volp->vol[ROVOL].ID) + ext = ".readonly"; + else if (bp->fid.volume == volp->vol[BACKVOL].ID) + ext = ".backup"; + else + ext = ".nomatch"; + snprintf(volstr, sizeof(volstr), "%s%s", volp->namep, ext); + } else { + cellp = cm_FindCellByID(bp->fid.cell, CM_FLAG_NOPROBE); + snprintf(volstr, sizeof(volstr), "%u", bp->fid.volume); + } + + LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_DIRTY_BUFFER_AT_SHUTDOWN, + cellp->name, volstr, bp->fid.vnode, bp->fid.unique, + bp->offset.QuadPart+bp->dirty_offset, bp->dirty_length); + } + /* advance the pointer so we don't loop forever */ lock_ObtainRead(&buf_globalLock); bpp = &bp->dirtyp; -- 2.39.5