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
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;