Windows: AFSClose File FCB/CCB cleanup before DirCB
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 26 Nov 2012 16:16:56 +0000 (11:16 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 29 Nov 2012 23:51:15 +0000 (15:51 -0800)
Move the processing of FCB and CCB cleanup ahead of the
DirectoryCB cleanup.  It is not safe to dereference the
Ccb->DirectoryCB until after the CCB has been destroyed.

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

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

index ce3046f..983e6d3 100644 (file)
@@ -305,9 +305,83 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
 
                 KeQueryTickCount( &pFcb->ObjectInformation->LastAccessCount);
 
+                if( pFcb->OpenReferenceCount == 1 &&
+                    pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
+                {
+
+                    SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
+
+                    //
+                    // Attempt to tear down our extent list for the file
+                    // If there are remaining dirty extents then attempt to
+                    // flush them as well
+                    //
+
+                    if( pFcb->Specific.File.ExtentsDirtyCount)
+                    {
+
+                        AFSFlushExtents( pFcb,
+                                         &pCcb->AuthGroup);
+                    }
+
+                    //
+                    // Wait for any outstanding queued flushes to complete
+                    //
+
+                    AFSWaitOnQueuedFlushes( pFcb);
+
+                    ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 &&
+                            pFcb->Specific.File.QueuedFlushCount == 0);
+
+                    AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+                    //
+                    // Tear 'em down, we'll not be needing them again
+                    //
+
+                    AFSTearDownFcbExtents( pFcb,
+                                           &pCcb->AuthGroup);
+                }
+                else
+                {
+
+                    if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB &&
+                        pFcb->Specific.File.ExtentsDirtyCount &&
+                        (pCcb->GrantedAccess & FILE_WRITE_DATA))
+                    {
+
+                        AFSFlushExtents( pFcb,
+                                         &pCcb->AuthGroup);
+                    }
+
+                    AFSReleaseResource( &pFcb->NPFcb->Resource);
+                }
+
                 pDirCB = pCcb->DirectoryCB;
 
                 //
+                // Remove the Ccb and de-allocate it
+                //
+
+                ntStatus = AFSRemoveCcb( pFcb,
+                                         pCcb);
+
+                if( !NT_SUCCESS( ntStatus))
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_WARNING,
+                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n",
+                                  ntStatus);
+
+                    //
+                    // We can't actually fail a close operation so reset the status
+                    //
+
+                    ntStatus = STATUS_SUCCESS;
+                }
+
+                //
                 // If this entry is deleted then remove the object from the volume tree
                 //
 
@@ -457,80 +531,6 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
                                   pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
                 }
 
-                if( pFcb->OpenReferenceCount == 1 &&
-                    pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
-                {
-
-                    SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
-
-                    //
-                    // Attempt to tear down our extent list for the file
-                    // If there are remaining dirty extents then attempt to
-                    // flush them as well
-                    //
-
-                    if( pFcb->Specific.File.ExtentsDirtyCount)
-                    {
-
-                        AFSFlushExtents( pFcb,
-                                         &pCcb->AuthGroup);
-                    }
-
-                    //
-                    // Wait for any outstanding queued flushes to complete
-                    //
-
-                    AFSWaitOnQueuedFlushes( pFcb);
-
-                    ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 &&
-                            pFcb->Specific.File.QueuedFlushCount == 0);
-
-                    AFSReleaseResource( &pFcb->NPFcb->Resource);
-
-                    //
-                    // Tear 'em down, we'll not be needing them again
-                    //
-
-                    AFSTearDownFcbExtents( pFcb,
-                                           &pCcb->AuthGroup);
-                }
-                else
-                {
-
-                    if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB &&
-                        pFcb->Specific.File.ExtentsDirtyCount &&
-                        (pCcb->GrantedAccess & FILE_WRITE_DATA))
-                    {
-
-                        AFSFlushExtents( pFcb,
-                                         &pCcb->AuthGroup);
-                    }
-
-                    AFSReleaseResource( &pFcb->NPFcb->Resource);
-                }
-
-                //
-                // Remove the Ccb and de-allocate it
-                //
-
-                ntStatus = AFSRemoveCcb( pFcb,
-                                         pCcb);
-
-                if( !NT_SUCCESS( ntStatus))
-                {
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_WARNING,
-                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n",
-                                  ntStatus);
-
-                    //
-                    // We can't actually fail a close operation so reset the status
-                    //
-
-                    ntStatus = STATUS_SUCCESS;
-                }
-
                 //
                 // Decrement the reference count on the Fcb. this is protecting it from teardown.
                 //