From 7e6a650ce5a5b0df18ab2d77e59a95c048660470 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 28 Feb 2008 18:22:58 +0000 Subject: [PATCH] DEVEL15-windows-buf-deadlock-20080228 LICENSE MIT avoid deadlock in buf_FlushCleanPages(). cannot obtain buffer mutex after a successful Stabilize call because the scp will be be locked and obtaining buffer mutex after scache mutex is a lock order violation. (cherry picked from commit 0546641c0da59289d03a9417984fe5f7e5636a75) --- src/WINNT/afsd/cm_buf.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 3b0d35b88e..434558500c 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -1548,19 +1548,21 @@ long buf_FlushCleanPages(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) if (code && code != CM_ERROR_BADFD) goto skip; - /* if the scp's FID is bad its because we received VNOVNODE - * when attempting to FetchStatus before the write. This - * page therefore contains data that can no longer be stored. - */ - lock_ObtainMutex(&bp->mx); - bp->flags &= ~CM_BUF_DIRTY; - bp->flags |= CM_BUF_ERROR; - bp->error = code; - bp->dirty_offset = 0; - bp->dirty_length = 0; - bp->dataVersion = -1; /* known bad */ - bp->dirtyCounter++; - lock_ReleaseMutex(&bp->mx); + if (code == CM_ERROR_BADFD) { + /* if the scp's FID is bad its because we received VNOVNODE + * when attempting to FetchStatus before the write. This + * page therefore contains data that can no longer be stored. + */ + lock_ObtainMutex(&bp->mx); + bp->flags &= ~CM_BUF_DIRTY; + bp->flags |= CM_BUF_ERROR; + bp->error = CM_ERROR_BADFD; + bp->dirty_offset = 0; + bp->dirty_length = 0; + bp->dataVersion = -1; /* known bad */ + bp->dirtyCounter++; + lock_ReleaseMutex(&bp->mx); + } /* actually, we only know that buffer is clean if ref * count is 1, since we don't have buffer itself locked. @@ -1578,7 +1580,7 @@ long buf_FlushCleanPages(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) lock_ReleaseWrite(&buf_globalLock); } - if (code != CM_ERROR_BADFD) + if (code == 0) (*cm_buf_opsp->Unstabilizep)(scp, userp); }