Windows: avoid deadlock during SetRenameInformation
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 18 Dec 2011 23:36:14 +0000 (18:36 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 19 Dec 2011 00:14:11 +0000 (16:14 -0800)
The VolumeLock must be held before the Fcb->NPFcb->Resource.
Obtain the VolumeLock in AFSSetFileInformation only in the
rename case instead of obtaining the VolumeLockin AFSSetRenameInformation.

Change-Id: I84f086e3a8f7d08630266c9e409e1e22c1f92742
Reviewed-on: http://gerrit.openafs.org/6377
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

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

index 92354e4..57c7909 100644 (file)
@@ -482,6 +482,7 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
     PFILE_OBJECT pFileObject = NULL;
     BOOLEAN bReleaseMain = FALSE;
     BOOLEAN bUpdateFileInfo = FALSE;
+    BOOLEAN bReleaseVolumeLock = FALSE;
     AFSFileID stParentFileId;
 
     __try
@@ -506,6 +507,15 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
         bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
         FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
 
+        if( FileInformationClass == FileRenameInformation)
+        {
+
+            AFSAcquireExcl( pFcb->ObjectInformation->VolumeCB->VolumeLock,
+                            TRUE);
+
+            bReleaseVolumeLock = TRUE;
+        }
+
         //
         // Grab the Fcb EXCL
         //
@@ -666,6 +676,11 @@ try_exit:
             AFSReleaseResource( &pFcb->NPFcb->Resource);
         }
 
+        if( bReleaseVolumeLock)
+        {
+            AFSReleaseResource( pFcb->ObjectInformation->VolumeCB->VolumeLock);
+        }
+
         if( NT_SUCCESS( ntStatus) &&
             bUpdateFileInfo)
         {
@@ -2061,7 +2076,6 @@ AFSSetRenameInfo( IN PIRP Irp)
     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
     UNICODE_STRING uniFullTargetPath;
     BOOLEAN bCommonParent = FALSE;
-    BOOLEAN bReleaseVolumeLock = FALSE;
     BOOLEAN bReleaseTargetDirLock = FALSE;
     BOOLEAN bReleaseSourceDirLock = FALSE;
     PERESOURCE  pSourceDirLock = NULL;
@@ -2184,11 +2198,6 @@ AFSSetRenameInfo( IN PIRP Irp)
             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
         }
 
-        AFSAcquireExcl( pTargetParentObject->VolumeCB->VolumeLock,
-                        TRUE);
-
-        bReleaseVolumeLock = TRUE;
-
         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
                                       FALSE);
 
@@ -2635,11 +2644,6 @@ try_exit:
             InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
         }
 
-        if( bReleaseVolumeLock)
-        {
-            AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
-        }
-
         if( bReleaseTargetDirLock)
         {
             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);