From: Jeffrey Altman Date: Thu, 28 Feb 2008 18:21:53 +0000 (+0000) Subject: windows-buf-deadlock-20080228 X-Git-Tag: BP-openafs-windows-kdfs-ifs~67 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=0546641c0da59289d03a9417984fe5f7e5636a75 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. --- diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index eecbb10..b2fc84a 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -1498,19 +1498,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. @@ -1528,7 +1530,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); }