From 039ffe2a036217e7d23c7466c77b69df50a603f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 21 Nov 2011 21:47:38 -0500 Subject: [PATCH] Windows: RDR_InvalidateObject do not hold locks Do not hold any locks when calling the afs redirector. Holding a lock can cause a deadlock. Change-Id: I5fb493d68e3cf3a8e58024b3b9f54349928f84c3 Reviewed-on: http://gerrit.openafs.org/6105 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_aclent.c | 10 +++++++--- src/WINNT/afsd/cm_buf.c | 11 +++++++---- src/WINNT/afsd/cm_freelance.c | 6 +++--- src/WINNT/afsd/cm_vnodeops.c | 24 +++++++++++++++--------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/WINNT/afsd/cm_aclent.c b/src/WINNT/afsd/cm_aclent.c index 88f8829..326383f 100644 --- a/src/WINNT/afsd/cm_aclent.c +++ b/src/WINNT/afsd/cm_aclent.c @@ -327,6 +327,7 @@ void cm_InvalidateACLUser(cm_scache_t *scp, cm_user_t *userp) cm_aclent_t *aclp; cm_aclent_t **laclpp; int found = 0; + int callback = 0; lock_ObtainWrite(&scp->rw); lock_ObtainWrite(&cm_aclLock); @@ -338,14 +339,17 @@ void cm_InvalidateACLUser(cm_scache_t *scp, cm_user_t *userp) aclp->userp = NULL; aclp->backp = (struct cm_scache *) 0; found = 1; - if (RDR_Initialized && cm_HaveCallback(scp)) - RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, - scp->fid.hash, scp->fileType, AFS_INVALIDATE_CREDS); break; } } lock_ReleaseWrite(&cm_aclLock); + if (found) + callback = cm_HaveCallback(scp); lock_ReleaseWrite(&scp->rw); + + if (found && callback && RDR_Initialized) + RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, + scp->fid.hash, scp->fileType, AFS_INVALIDATE_CREDS); } /* diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 2377df2..88e4eb2 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -1898,6 +1898,7 @@ long buf_Truncate(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, long code; long bufferPos; afs_uint32 i; + afs_uint32 invalidate = 0; /* assert that cm_bufCreateLock is held in write mode */ lock_AssertWrite(&scp->bufCreateLock); @@ -1968,10 +1969,7 @@ long buf_Truncate(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, lock_ReleaseWrite(&buf_globalLock); } } else { - if (RDR_Initialized) - RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, - scp->fid.unique, scp->fid.hash, - scp->fileType, AFS_INVALIDATE_SMB); + invalidate = 1; } _InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY); bufp->error = 0; @@ -2020,6 +2018,11 @@ long buf_Truncate(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, buf_ValidateBufQueues(); #endif /* TESTING */ + if (invalidate && RDR_Initialized) + RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, + scp->fid.unique, scp->fid.hash, + scp->fileType, AFS_INVALIDATE_SMB); + /* done */ return code; } diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index 4384342..a70d95b 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -398,6 +398,9 @@ int cm_noteLocalMountPointChange(afs_int32 locked) { cm_data.fakeDirVersion++; cm_localMountPointChangeFlag = 1; + if (!locked) + lock_ReleaseMutex(&cm_Freelance_Lock); + if (RDR_Initialized) { cm_fid_t fid; cm_FakeRootFid(&fid); @@ -405,9 +408,6 @@ int cm_noteLocalMountPointChange(afs_int32 locked) { CM_SCACHETYPE_DIRECTORY, AFS_INVALIDATE_DATA_VERSION); } - - if (!locked) - lock_ReleaseMutex(&cm_Freelance_Lock); return 1; } diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index c177fc5..20ee837 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1610,6 +1610,7 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep, cm_dirOp_t dirop; cm_scache_t *scp = NULL; int free_fnamep = FALSE; + int invalidate = 0; memset(&volSync, 0, sizeof(volSync)); @@ -1694,11 +1695,7 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep, cm_dnlcRemove(dscp, cnamep); if (code == 0) { cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP); - if (RDR_Initialized && - scp->fileType != CM_SCACHETYPE_FILE && scp->fileType != CM_SCACHETYPE_DIRECTORY) - RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode, - dscp->fid.unique, dscp->fid.hash, - dscp->fileType, AFS_INVALIDATE_DATA_VERSION); + invalidate = 1; } else { InterlockedDecrement(&scp->activeRPCs); if (code == CM_ERROR_NOSUCHFILE) { @@ -1720,6 +1717,12 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep, } cm_EndDirOp(&dirop); + if (invalidate && RDR_Initialized && + scp->fileType != CM_SCACHETYPE_FILE && scp->fileType != CM_SCACHETYPE_DIRECTORY) + RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode, + dscp->fid.unique, dscp->fid.hash, + dscp->fileType, AFS_INVALIDATE_DATA_VERSION); + if (scp) { cm_ReleaseSCache(scp); if (code == 0) { @@ -3175,6 +3178,7 @@ long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long fl struct rx_connection * rxconnp; cm_dirOp_t dirop; fschar_t * fnamep = NULL; + int invalidate = 0; memset(&volSync, 0, sizeof(volSync)); @@ -3238,10 +3242,7 @@ long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long fl lock_ObtainWrite(&dscp->rw); if (code == 0) { cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP); - if (RDR_Initialized) - RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode, - dscp->fid.unique, dscp->fid.hash, - dscp->fileType, AFS_INVALIDATE_DATA_VERSION); + invalidate = 1; } else { InterlockedDecrement(&dscp->activeRPCs); } @@ -3258,6 +3259,11 @@ long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long fl } cm_EndDirOp(&dirop); + if (invalidate && RDR_Initialized) + RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode, + dscp->fid.unique, dscp->fid.hash, + dscp->fileType, AFS_INVALIDATE_DATA_VERSION); + /* Update the linked object status */ if (code == 0) { lock_ObtainWrite(&sscp->rw); -- 1.9.4