Windows: RDR_InvalidateObject do not hold locks
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 22 Nov 2011 02:47:38 +0000 (21:47 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 22 Nov 2011 21:48:59 +0000 (13:48 -0800)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsd/cm_aclent.c
src/WINNT/afsd/cm_buf.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_vnodeops.c

index 88f8829..326383f 100644 (file)
@@ -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);
 }
 
 /*
index 2377df2..88e4eb2 100644 (file)
@@ -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;
 }
index 4384342..a70d95b 100644 (file)
@@ -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;
 }
 
index c177fc5..20ee837 100644 (file)
@@ -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);