Windows: AFSProcessOverwriteSupersede CcSetFileSizes
authorPeter Scott <pscott@kerneldrivers.com>
Mon, 16 Apr 2012 16:25:01 +0000 (12:25 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 17 Apr 2012 01:36:40 +0000 (18:36 -0700)
Instead of calling CcPurgeCacheSection() in AFSProcessOverwriteSupersede()
as part of the file length truncation to zero, call CcSetFileSizes().

Wait to call CcSetFileSizes() until after the Fcb->Resource has been
dropped but while the Fcb->Header.PagingIoResource is still held.
Make sure that file sizes are restored in the Fcb->Header if the
afsd_service rejects the file update.

Change-Id: I7574e80781ac1dbbe69814c69644bb3825de9b6a
Reviewed-on: http://gerrit.openafs.org/7220
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/AFSCreate.cpp

index def89e9..388495c 100644 (file)
@@ -3035,11 +3035,15 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
     AFSObjectInfoCB *pParentObjectInfo = NULL;
     AFSObjectInfoCB *pObjectInfo = NULL;
     LONG lCount;
+    LARGE_INTEGER liSaveSize;
+    LARGE_INTEGER liSaveVDL;
+    LARGE_INTEGER liSaveAlloc;
 
     __Enter
     {
 
         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
+
         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
 
         pFileObject = pIrpSp->FileObject;
@@ -3216,13 +3220,17 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
         (*Ccb)->GrantedAccess = *pDesiredAccess;
 
         //
-        // Need to purge any data currently in the cache
+        // Set the file length to zero
         //
 
-        CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                             NULL,
-                             0,
-                             FALSE);
+        AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
+                        TRUE);
+
+        bReleasePaging = TRUE;
+
+        liSaveSize = pObjectInfo->Fcb->Header.FileSize;
+        liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
+        liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
 
         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
@@ -3246,6 +3254,16 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
 
         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
 
+        //
+        // Set the update flag accordingly
+        //
+
+        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
+                                          AFS_FCB_FLAG_UPDATE_CREATE_TIME |
+                                          AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
+                                          AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
+                                          AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
+
         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
                                              pObjectInfo,
                                              AuthGroup);
@@ -3253,6 +3271,12 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
         if( !NT_SUCCESS( ntStatus))
         {
 
+            pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
+            pObjectInfo->Fcb->Header.FileSize = liSaveSize;
+            pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
+            pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
+            pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
+
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
@@ -3263,34 +3287,6 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
             try_return( ntStatus);
         }
 
-        AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
-                        TRUE);
-
-        bReleasePaging = TRUE;
-
-        pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
-
-        pFileObject->FsContext = (void *)pObjectInfo->Fcb;
-
-        pFileObject->FsContext2 = (void *)*Ccb;
-
-        //
-        // Set the update flag accordingly
-        //
-
-        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
-                                          AFS_FCB_FLAG_UPDATE_CREATE_TIME |
-                                          AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
-                                          AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
-                                          AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
-
-        CcSetFileSizes( pFileObject,
-                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
-
-        AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
-
-        bReleasePaging = FALSE;
-
         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
 
         if( ulCreateDisposition == FILE_SUPERSEDE)
@@ -3371,8 +3367,27 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
                       pObjectInfo->ParentObjectInformation,
                       lCount);
 
+        AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
+
+        bReleaseFcb = FALSE;
+
         *Fcb = pObjectInfo->Fcb;
 
+        //
+        // Now that the Fcb->Resource has been dropped
+        // we can call CcSetFileSizes.  We are still holding
+        // the PagingIoResource
+        //
+
+        pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
+
+        pFileObject->FsContext = (void *)pObjectInfo->Fcb;
+
+        pFileObject->FsContext2 = (void *)*Ccb;
+
+        CcSetFileSizes( pFileObject,
+                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+
 try_exit:
 
         if( bReleasePaging)