Windows: Avoid deadlock during pending delete cleanup
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 8 Apr 2014 07:27:26 +0000 (03:27 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 26 Aug 2014 01:23:04 +0000 (21:23 -0400)
Release the Fcb resource and clear the AFS_DIR_ENTRY_PENDING_DELETE
flag prior to the AFSProcessRequest(AFS_REQUEST_TYPE_CLEANUP_PROCESSING)
if a delete is pending during cleanup of the last FCB open handle.

Failure to do so results in an out of order lock acquisition when
the parent object info tree lock is acquired after the AFSProcessRequest()
call to the service completes.

Change-Id: Id1c770b3dfe669d6804276bbe832af2d215c72dc
Reviewed-on: http://gerrit.openafs.org/11425
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp

index 3361a9b..092a50e 100644 (file)
@@ -447,6 +447,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
+                   //
+                   // Release the Fcb Resource while processing the pending delete
+                   // to avoid an out of order lock acquisition
+                   //
+
+                   ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+
+                   AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                     ntStatus = STATUS_SUCCESS;
 
                     ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED;
@@ -484,8 +493,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                       ntStatus));
 
                         ntStatus = STATUS_SUCCESS;
-
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                     }
                     else
                     {
@@ -537,8 +544,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
 
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
-
                         ASSERT( pParentObjectInfo != NULL);
 
                         if ( pParentObjectInfo != NULL)
@@ -607,6 +612,13 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                             }
                         }
                     }
+
+                   //
+                   // Regain exclusive access to the Fcb
+                   //
+
+                   AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                                   TRUE);
                 }
                 else
                 {
@@ -888,6 +900,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
+                   //
+                   // Release the Fcb Resource while processing the pending delete
+                   // to avoid an out of order lock acquisition
+                   //
+
+                   ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+
+                   AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                     //
                     // Try to notify the service about the delete
                     //
@@ -927,8 +948,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                       ntStatus));
 
                         ntStatus = STATUS_SUCCESS;
-
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                     }
                     else
                     {
@@ -943,8 +962,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
 
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
-
                         ASSERT( pParentObjectInfo != NULL);
 
                         if ( pParentObjectInfo != NULL)
@@ -1007,6 +1024,13 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                             }
                         }
                     }
+
+                   //
+                   // Regain exclusive access to the Fcb
+                   //
+
+                   AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                                   TRUE);
                 }
 
                 //
@@ -1206,6 +1230,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                     BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                 {
 
+                   //
+                   // Release the Fcb Resource while processing the pending delete
+                   // to avoid an out of order lock acquisition
+                   //
+
+                   ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
+
+                   AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                     //
                     // Try to notify the service about the delete
                     //
@@ -1245,8 +1278,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                       ntStatus));
 
                         ntStatus = STATUS_SUCCESS;
-
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                     }
                     else
                     {
@@ -1261,8 +1292,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
 
-                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
-
                         ASSERT( pParentObjectInfo != NULL);
 
                         if ( pParentObjectInfo != NULL)
@@ -1325,7 +1354,14 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                             }
                         }
                     }
-                }
+
+                   //
+                   // Regain exclusive access to the Fcb
+                   //
+
+                   AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                                   TRUE);
+               }
 
                 //
                 // If there have been any updates to the node then push it to