2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include "AFSCommon.h"
43 AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
45 IN LARGE_INTEGER StartingByte,
47 IN BOOLEAN ForceFlush);
50 AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject,
52 IN LARGE_INTEGER StartingByte,
57 AFSExtendingWrite( IN AFSFcb *Fcb,
58 IN PFILE_OBJECT FileObject,
59 IN LONGLONG NewLength);
66 // This is the dispatch handler for the IRP_MJ_WRITE request
70 // A status is returned for the function
73 AFSWrite( IN PDEVICE_OBJECT LibDeviceObject,
77 UNREFERENCED_PARAMETER(LibDeviceObject);
78 NTSTATUS ntStatus = STATUS_SUCCESS;
83 ntStatus = AFSCommonWrite( AFSRDRDeviceObject, Irp, NULL, FALSE);
85 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
88 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
95 AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
101 NTSTATUS ntStatus = STATUS_SUCCESS;
102 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
103 IO_STACK_LOCATION *pIrpSp;
106 AFSNonPagedFcb *pNPFcb = NULL;
107 ULONG ulByteCount = 0;
108 LARGE_INTEGER liStartingByte;
109 PFILE_OBJECT pFileObject;
110 BOOLEAN bPagingIo = FALSE;
111 BOOLEAN bNonCachedIo = FALSE;
112 BOOLEAN bReleaseMain = FALSE;
113 BOOLEAN bReleaseSectionObject = FALSE;
114 BOOLEAN bReleasePaging = FALSE;
115 BOOLEAN bExtendingWrite = FALSE;
116 BOOLEAN bCompleteIrp = TRUE;
118 HANDLE hCallingUser = OnBehalfOf;
119 ULONGLONG ullProcessId = (ULONGLONG)PsGetCurrentProcessId();
121 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
126 pFileObject = pIrpSp->FileObject;
129 // Extract the fileobject references
132 pFcb = (AFSFcb *)pFileObject->FsContext;
133 pCcb = (AFSCcb *)pFileObject->FsContext2;
135 ObReferenceObject( pFileObject);
140 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
141 AFS_TRACE_LEVEL_ERROR,
142 "AFSCommonWrite Attempted write (%p) when pFcb == NULL\n",
145 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
148 pNPFcb = pFcb->NPFcb;
151 // If we are in shutdown mode then fail the request
154 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
157 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
158 AFS_TRACE_LEVEL_WARNING,
159 "AFSCommonWrite (%p) Open request after shutdown\n",
162 try_return( ntStatus = STATUS_TOO_LATE);
165 liStartingByte = pIrpSp->Parameters.Write.ByteOffset;
166 bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
167 bNonCachedIo = BooleanFlagOn( Irp->Flags, IRP_NOCACHE);
168 ulByteCount = pIrpSp->Parameters.Write.Length;
170 if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
171 pFcb->Header.NodeTypeCode != AFS_FILE_FCB &&
172 pFcb->Header.NodeTypeCode != AFS_SPECIAL_SHARE_FCB)
175 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
176 AFS_TRACE_LEVEL_ERROR,
177 "AFSCommonWrite Attempted write (%p) on an invalid node type %08lX\n",
179 pFcb->Header.NodeTypeCode);
181 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
185 // If this is a write against an IOCtl node then handle it
186 // in a different pathway
189 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
192 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
193 AFS_TRACE_LEVEL_VERBOSE,
194 "AFSCommonWrite (%p) Processing file (PIOCTL) Offset %I64X Length %08lX Irp Flags %08lX\n",
196 liStartingByte.QuadPart,
200 ntStatus = AFSIOCtlWrite( DeviceObject,
203 try_return( ntStatus);
205 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
208 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
209 AFS_TRACE_LEVEL_VERBOSE,
210 "AFSCommonWrite (%p) Processing file (SHARE) Offset %I64X Length %08lX Irp Flags %08lX\n",
212 liStartingByte.QuadPart,
216 ntStatus = AFSShareWrite( DeviceObject,
219 try_return( ntStatus);
223 // Is the Cache not there yet? Exit.
225 if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
226 NULL == pDeviceExt->Specific.RDR.CacheFileObject)
229 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
230 AFS_TRACE_LEVEL_ERROR,
231 "AFSCommonWrite (%p) Request failed due to AFS cache closed\n",
234 try_return( ntStatus = STATUS_TOO_LATE );
237 if( pFcb->ObjectInformation->VolumeCB != NULL &&
238 BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
241 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
242 AFS_TRACE_LEVEL_ERROR,
243 "AFSCommonWrite (%p) Request failed due to read only volume\n",
246 try_return( ntStatus = STATUS_ACCESS_DENIED);
250 // We need to know on whose behalf we have been called (which
251 // we will eventually tell to the server - for non paging
252 // writes). If we were posted then we were told. If this is
253 // the first time we saw the irp then we grab it now.
255 if( NULL == OnBehalfOf )
258 hCallingUser = PsGetCurrentProcessId();
263 hCallingUser = OnBehalfOf;
267 // Check for zero length write
270 if( ulByteCount == 0)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
274 AFS_TRACE_LEVEL_VERBOSE,
275 "AFSCommonWrite (%p) Request completed due to zero length\n",
278 try_return( ntStatus);
282 // Is this Fcb valid???
285 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID))
288 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
289 AFS_TRACE_LEVEL_ERROR,
290 "AFSCommonWrite (%p) Failing request due to INVALID fcb\n",
293 Irp->IoStatus.Information = 0;
295 try_return( ntStatus = STATUS_FILE_DELETED);
298 if( BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED) ||
299 BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
302 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
303 AFS_TRACE_LEVEL_ERROR,
304 "AFSCommonWrite (%p) Request failed due to file deleted\n",
307 try_return( ntStatus = STATUS_FILE_DELETED);
310 if( FlagOn( pIrpSp->MinorFunction, IRP_MN_COMPLETE))
313 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
314 AFS_TRACE_LEVEL_VERBOSE,
315 "AFSCommonWrite (%p) IRP_MN_COMPLETE being processed\n",
318 CcMdlWriteComplete(pFileObject, &pIrpSp->Parameters.Write.ByteOffset, Irp->MdlAddress);
321 // Mdl is now Deallocated
324 Irp->MdlAddress = NULL;
326 try_return( ntStatus = STATUS_SUCCESS );
330 // If we get a non cached IO for a cached file we should do a purge.
331 // For now we will just promote to cached
333 if( NULL != pFileObject->SectionObjectPointer->DataSectionObject && !bPagingIo && bNonCachedIo)
335 bNonCachedIo = FALSE;
338 if ( !bNonCachedIo && !bPagingIo)
341 if( pFileObject->PrivateCacheMap == NULL)
344 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
345 AFS_TRACE_LEVEL_VERBOSE,
346 "AFSCommonWrite Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
347 &pNPFcb->SectionObjectResource,
348 PsGetCurrentThread());
350 AFSAcquireExcl( &pNPFcb->SectionObjectResource,
353 bReleaseSectionObject = TRUE;
358 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
359 AFS_TRACE_LEVEL_VERBOSE,
360 "AFSCommonWrite Initialize caching on Fcb %p FileObject %p\n",
364 CcInitializeCacheMap( pFileObject,
365 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
367 AFSLibCacheManagerCallbacks,
370 CcSetReadAheadGranularity( pFileObject,
371 pDeviceExt->Specific.RDR.MaximumRPCLength);
373 CcSetDirtyPageThreshold( pFileObject,
374 AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength / 4096);
376 __except( EXCEPTION_EXECUTE_HANDLER)
379 ntStatus = GetExceptionCode();
381 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
382 AFS_TRACE_LEVEL_ERROR,
383 "AFSCommonWrite (%p) Exception thrown while initializing cache map Status %08lX\n",
388 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
389 AFS_TRACE_LEVEL_VERBOSE,
390 "AFSCommonWrite Releasing Fcb SectionObject lock %p EXCL %08lX\n",
391 &pNPFcb->SectionObjectResource,
392 PsGetCurrentThread());
394 AFSReleaseResource( &pNPFcb->SectionObjectResource);
396 bReleaseSectionObject = FALSE;
398 if( !NT_SUCCESS( ntStatus))
401 try_return( ntStatus);
405 if (!CcCanIWrite( pFileObject,
411 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
412 AFS_TRACE_LEVEL_WARNING,
413 "AFSCommonWrite (FO: %p) CcCanIWrite says No room for Offset %0I64X Length %08lX bytes! Deferring%s\n",
415 liStartingByte.QuadPart,
417 bRetry ? " RETRY" : "");
419 ntStatus = AFSDeferWrite( DeviceObject, pFileObject, hCallingUser, Irp, ulByteCount, bRetry);
421 if ( STATUS_PENDING == ntStatus)
424 bCompleteIrp = FALSE;
429 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
430 AFS_TRACE_LEVEL_ERROR,
431 "AFSCommonWrite (FO: %p) AFSDeferWrite failure Status %08lX\n",
436 try_return( ntStatus);
441 // Save off the PID if this is not a paging IO
445 ( pFcb->Specific.File.ExtentRequestProcessId == 0 ||
446 ( ullProcessId != (ULONGLONG)AFSSysProcess &&
447 pFcb->Specific.File.ExtentRequestProcessId != ullProcessId)))
450 pFcb->Specific.File.ExtentRequestProcessId = ullProcessId;
452 if( ullProcessId == (ULONGLONG)AFSSysProcess)
454 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
455 AFS_TRACE_LEVEL_WARNING,
456 "%s Setting LastWriterExtentProcessId to system process for Fcb %p\n",
465 // - if Paging then we need to do nothing (the precalls will
466 // have acquired the paging resource), for clarity we will collect
467 // the paging resource
468 // - If extending Write then take the fileresource EX (EOF will change, Allocation will only move out)
469 // - Otherwise we collect the file shared, check against extending and
480 //ASSERT( NULL != OnBehalfOf || ExIsResourceAcquiredLite( &pNPFcb->Resource ));
482 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
483 AFS_TRACE_LEVEL_VERBOSE,
484 "AFSCommonWrite Acquiring Fcb PagingIo lock %p SHARED %08lX\n",
485 &pNPFcb->PagingResource,
486 PsGetCurrentThread());
488 AFSAcquireShared( &pNPFcb->PagingResource,
491 bReleasePaging = TRUE;
494 // We have the correct lock - we cannot have the wrong one
501 bExtendingWrite = (((liStartingByte.QuadPart + ulByteCount) >=
502 pFcb->Header.FileSize.QuadPart) ||
503 (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
504 liStartingByte.HighPart == -1)) ;
509 // Check for lock inversion
512 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
514 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
515 AFS_TRACE_LEVEL_VERBOSE,
516 "AFSCommonWrite Acquiring Fcb lock %p EXCL %08lX\n",
518 PsGetCurrentThread());
520 AFSAcquireExcl( &pNPFcb->Resource,
525 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
526 AFS_TRACE_LEVEL_VERBOSE,
527 "AFSCommonWrite Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
528 &pNPFcb->SectionObjectResource,
529 PsGetCurrentThread());
531 AFSAcquireExcl( &pNPFcb->SectionObjectResource,
534 bReleaseSectionObject = TRUE;
536 if (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
537 liStartingByte.HighPart == -1)
539 if (pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
541 liStartingByte = pFcb->Header.ValidDataLength;
545 liStartingByte = pFcb->Header.FileSize;
550 // We have the correct lock - even if we don't end up truncating
556 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
558 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
559 AFS_TRACE_LEVEL_VERBOSE,
560 "AFSCommonWrite Acquiring Fcb lock %p SHARED %08lX\n",
562 PsGetCurrentThread());
564 AFSAcquireShared( &pNPFcb->Resource,
569 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
570 AFS_TRACE_LEVEL_VERBOSE,
571 "AFSCommonWrite Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
572 &pNPFcb->SectionObjectResource,
573 PsGetCurrentThread());
575 AFSAcquireShared( &pNPFcb->SectionObjectResource,
578 bReleaseSectionObject = TRUE;
581 // Have things moved? Are we extending? If so, the the lock isn't OK
583 bLockOK = (liStartingByte.QuadPart + ulByteCount) < pFcb->Header.FileSize.QuadPart;
587 AFSReleaseResource( &pNPFcb->Resource);
589 bReleaseMain = FALSE;
600 // Check the BR locks on the file.
603 if ( !FsRtlCheckLockForWriteAccess( &pFcb->Specific.File.FileLock,
607 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
608 AFS_TRACE_LEVEL_ERROR,
609 "AFSCommonWrite (%p) Request failed due to lock conflict\n",
612 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
618 ntStatus = AFSExtendingWrite( pFcb, pFileObject, (liStartingByte.QuadPart + ulByteCount));
620 if( !NT_SUCCESS(ntStatus))
623 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
624 AFS_TRACE_LEVEL_ERROR,
625 "AFSCommonWrite (%p) Failed extending write request Status %08lX\n",
629 try_return( ntStatus );
635 // Fire off the request as appropriate
637 bCompleteIrp = FALSE;
644 // Main and SectionObject resources held Shared
647 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
648 AFS_TRACE_LEVEL_VERBOSE,
649 "AFSCommonWrite (%p) Processing CACHED request Offset %0I64X Len %08lX%s\n",
651 liStartingByte.QuadPart,
653 bRetry ? " RETRY" : "");
655 ntStatus = AFSCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount, TRUE);
662 // if bPagingIo, Paging Resource held Shared
663 // else Main and SectionObject resources held Shared
666 if( bReleaseSectionObject)
669 AFSReleaseResource( &pNPFcb->SectionObjectResource);
671 bReleaseSectionObject = FALSE;
677 AFSReleaseResource( &pNPFcb->PagingResource);
679 bReleasePaging = FALSE;
685 AFSReleaseResource( &pNPFcb->Resource);
687 bReleaseMain = FALSE;
690 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
691 AFS_TRACE_LEVEL_VERBOSE,
692 "AFSCommonWrite (%p) Processing NON-CACHED request Offset %0I64X Len %08lX%s\n",
694 liStartingByte.QuadPart,
696 bRetry ? " RETRY" : "");
698 ntStatus = AFSNonCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount);
703 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
704 AFS_TRACE_LEVEL_VERBOSE,
705 "AFSCommonWrite (%p) Process complete Status %08lX\n",
709 ObDereferenceObject(pFileObject);
711 if( bReleaseSectionObject)
714 AFSReleaseResource( &pNPFcb->SectionObjectResource);
720 AFSReleaseResource( &pNPFcb->PagingResource);
726 AFSReleaseResource( &pNPFcb->Resource);
732 AFSCompleteRequest( Irp,
741 AFSIOCtlWrite( IN PDEVICE_OBJECT DeviceObject,
745 UNREFERENCED_PARAMETER(DeviceObject);
746 NTSTATUS ntStatus = STATUS_SUCCESS;
747 AFSPIOCtlIORequestCB stIORequestCB;
748 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
751 AFSPIOCtlIOResultCB stIOResultCB;
752 ULONG ulBytesReturned = 0;
753 AFSFileID stParentFID;
758 RtlZeroMemory( &stIORequestCB,
759 sizeof( AFSPIOCtlIORequestCB));
761 if( pIrpSp->Parameters.Write.Length == 0)
765 // Nothing to do in this case
768 try_return( ntStatus);
771 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
773 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
775 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
776 AFS_TRACE_LEVEL_VERBOSE,
777 "AFSIOCtlWrite Acquiring Fcb lock %p SHARED %08lX\n",
778 &pFcb->NPFcb->Resource,
779 PsGetCurrentThread());
781 AFSAcquireShared( &pFcb->NPFcb->Resource,
785 // Get the parent fid to pass to the cm
788 RtlZeroMemory( &stParentFID,
791 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
795 // The parent directory FID of the node
798 stParentFID = pFcb->ObjectInformation->ParentFileId;
802 // Set the control block up
805 stIORequestCB.RequestId = pCcb->RequestID;
807 if( pFcb->ObjectInformation->VolumeCB != NULL)
809 stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
813 // Lock down the buffer
816 stIORequestCB.MappedBuffer = AFSMapToService( Irp,
817 pIrpSp->Parameters.Write.Length);
819 if( stIORequestCB.MappedBuffer == NULL)
822 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
825 stIORequestCB.BufferLength = pIrpSp->Parameters.Write.Length;
827 stIOResultCB.BytesProcessed = 0;
829 ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
832 // Issue the request to the service
835 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_WRITE,
836 AFS_REQUEST_FLAG_SYNCHRONOUS,
842 (void *)&stIORequestCB,
843 sizeof( AFSPIOCtlIORequestCB),
847 if( !NT_SUCCESS( ntStatus))
850 try_return( ntStatus);
854 // Update the length written
857 Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
861 if( stIORequestCB.MappedBuffer != NULL)
864 AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
871 AFSReleaseResource( &pFcb->NPFcb->Resource);
879 // This function is called when we know we have to read from the AFS Cache.
881 // It ensures that we have exents for the entirety of the write and
882 // then pins the extents into memory (meaning that although we may
883 // add we will not remove). Then it creates a scatter gather write
884 // and fires off the IRPs
888 AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject,
890 IN LARGE_INTEGER StartingByte,
893 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
894 VOID *pSystemBuffer = NULL;
895 BOOLEAN bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
896 BOOLEAN bLocked = FALSE;
897 BOOLEAN bCompleteIrp = TRUE;
898 AFSGatherIo *pGatherIo = NULL;
899 AFSIoRun *pIoRuns = NULL;
900 AFSIoRun stIoRuns[AFS_MAX_STACK_IO_RUNS];
901 ULONG extentsCount = 0, runCount = 0;
902 AFSExtent *pStartExtent = NULL;
903 AFSExtent *pIgnoreExtent = NULL;
904 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
905 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
906 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
907 AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
908 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
909 AFSDeviceExt *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
910 LARGE_INTEGER liCurrentTime, liLastRequestTime;
911 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
912 PFILE_OBJECT pCacheFileObject = NULL;
913 BOOLEAN bDerefExtents = FALSE;
917 Irp->IoStatus.Information = 0;
919 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
920 AFS_TRACE_LEVEL_VERBOSE,
921 "AFSNonCachedWrite (FO: %p) StartingByte %08lX:%08lX Length %08lX\n",
923 StartingByte.HighPart,
924 StartingByte.LowPart,
927 if (ByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
930 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
931 AFS_TRACE_LEVEL_ERROR,
932 "AFSNonCachedWrite (%p) Request %08lX Actual %08lX larger than MaxIO %I64X\n",
935 pIrpSp->Parameters.Write.Length,
936 pDevExt->Specific.RDR.MaxIo.QuadPart);
938 try_return( ntStatus = STATUS_UNSUCCESSFUL);
942 // Get the mapping for the buffer
944 pSystemBuffer = AFSLockSystemBuffer( Irp,
947 if( pSystemBuffer == NULL)
950 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
951 AFS_TRACE_LEVEL_ERROR,
952 "AFSNonCachedWrite (%p) Failed to map system buffer\n",
955 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
960 // Provoke a get of the extents - if we need to.
963 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
964 AFS_TRACE_LEVEL_VERBOSE,
965 "AFSNonCachedWrite Requesting extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
966 pFcb->ObjectInformation->FileId.Cell,
967 pFcb->ObjectInformation->FileId.Volume,
968 pFcb->ObjectInformation->FileId.Vnode,
969 pFcb->ObjectInformation->FileId.Unique,
970 StartingByte.QuadPart,
973 ntStatus = AFSRequestExtentsAsync( pFcb,
978 if (!NT_SUCCESS(ntStatus))
981 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
982 AFS_TRACE_LEVEL_ERROR,
983 "AFSNonCachedWrite (%p) Failed to request extents Status %08lX\n",
987 try_return( ntStatus);
990 KeQueryTickCount( &liLastRequestTime);
995 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
996 AFS_TRACE_LEVEL_VERBOSE,
997 "AFSNonCachedWrite Acquiring Fcb extents lock %p SHARED %08lX\n",
998 &pFcb->NPFcb->Specific.File.ExtentsResource,
999 PsGetCurrentThread());
1001 ASSERT( !ExIsResourceAcquiredLite( &pFcb->NPFcb->Specific.File.ExtentsResource ));
1003 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource, TRUE );
1006 pStartExtent = NULL;
1007 pIgnoreExtent = NULL;
1009 if ( AFSDoExtentsMapRegion( pFcb, &StartingByte, ByteCount, &pStartExtent, &pIgnoreExtent ))
1014 KeClearEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete );
1016 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1017 AFS_TRACE_LEVEL_VERBOSE,
1018 "AFSNonCachedWrite Releasing(1) Fcb extents lock %p SHARED %08lX\n",
1019 &pFcb->NPFcb->Specific.File.ExtentsResource,
1020 PsGetCurrentThread());
1022 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1026 // We will re-request the extents after waiting for them
1029 KeQueryTickCount( &liCurrentTime);
1031 if( liCurrentTime.QuadPart - liLastRequestTime.QuadPart >= pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart)
1034 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1035 AFS_TRACE_LEVEL_VERBOSE,
1036 "AFSNonCachedWrite Requesting extents, again, for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
1037 pFcb->ObjectInformation->FileId.Cell,
1038 pFcb->ObjectInformation->FileId.Volume,
1039 pFcb->ObjectInformation->FileId.Vnode,
1040 pFcb->ObjectInformation->FileId.Unique,
1041 StartingByte.QuadPart,
1044 ntStatus = AFSRequestExtentsAsync( pFcb,
1049 if (!NT_SUCCESS(ntStatus))
1052 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1053 AFS_TRACE_LEVEL_ERROR,
1054 "AFSNonCachedWrite (%p) Failed to request extents Status %08lX\n",
1058 try_return( ntStatus);
1061 KeQueryTickCount( &liLastRequestTime);
1065 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1066 AFS_TRACE_LEVEL_VERBOSE,
1067 "AFSNonCachedWrite Waiting for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
1068 pFcb->ObjectInformation->FileId.Cell,
1069 pFcb->ObjectInformation->FileId.Volume,
1070 pFcb->ObjectInformation->FileId.Vnode,
1071 pFcb->ObjectInformation->FileId.Unique,
1072 StartingByte.QuadPart,
1079 ntStatus = AFSWaitForExtentMapping ( pFcb, pCcb);
1081 if (!NT_SUCCESS(ntStatus))
1084 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1085 AFS_TRACE_LEVEL_ERROR,
1086 "AFSNonCachedWrite Failed wait for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
1087 pFcb->ObjectInformation->FileId.Cell,
1088 pFcb->ObjectInformation->FileId.Volume,
1089 pFcb->ObjectInformation->FileId.Vnode,
1090 pFcb->ObjectInformation->FileId.Unique,
1091 StartingByte.QuadPart,
1095 try_return( ntStatus);
1100 // As per the read path -
1103 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1104 AFS_TRACE_LEVEL_VERBOSE,
1105 "AFSNonCachedWrite Extents located for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
1106 pFcb->ObjectInformation->FileId.Cell,
1107 pFcb->ObjectInformation->FileId.Volume,
1108 pFcb->ObjectInformation->FileId.Vnode,
1109 pFcb->ObjectInformation->FileId.Unique,
1110 StartingByte.QuadPart,
1113 ntStatus = AFSGetExtents( pFcb,
1120 if (!NT_SUCCESS(ntStatus))
1123 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1124 AFS_TRACE_LEVEL_ERROR,
1125 "AFSNonCachedWrite (%p) Failed to retrieve mapped extents Status %08lX\n",
1129 try_return( ntStatus );
1132 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1133 AFS_TRACE_LEVEL_VERBOSE,
1134 "AFSNonCachedWrite (%p) Successfully retrieved map extents count %d run count %d\n",
1139 if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
1142 Irp->IoStatus.Information = ByteCount;
1146 // Setup the MD5 for each extent
1149 AFSSetupMD5Hash( pFcb,
1157 ntStatus = AFSProcessExtentRun( pSystemBuffer,
1163 if (!NT_SUCCESS(ntStatus))
1166 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1167 AFS_TRACE_LEVEL_ERROR,
1168 "AFSNonCachedWrite (%p) Failed to process extent run for non-persistent cache Status %08lX\n",
1173 try_return( ntStatus);
1177 // Retrieve the cache file object
1180 pCacheFileObject = AFSReferenceCacheFileObject();
1182 if( pCacheFileObject == NULL)
1185 ntStatus = STATUS_DEVICE_NOT_READY;
1187 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1188 AFS_TRACE_LEVEL_ERROR,
1189 "AFSNonCachedWrite Failed to retrieve cache fileobject for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
1190 pFcb->ObjectInformation->FileId.Cell,
1191 pFcb->ObjectInformation->FileId.Volume,
1192 pFcb->ObjectInformation->FileId.Vnode,
1193 pFcb->ObjectInformation->FileId.Unique,
1194 StartingByte.QuadPart,
1198 try_return( ntStatus);
1201 if (runCount > AFS_MAX_STACK_IO_RUNS)
1204 pIoRuns = (AFSIoRun*) AFSExAllocatePoolWithTag( PagedPool,
1205 runCount * sizeof( AFSIoRun ),
1207 if (NULL == pIoRuns)
1210 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1211 AFS_TRACE_LEVEL_ERROR,
1212 "AFSNonCachedWrite (%p) Failed to allocate IO run block\n",
1215 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1224 RtlZeroMemory( pIoRuns, runCount * sizeof( AFSIoRun ));
1226 ntStatus = AFSSetupIoRun( IoGetRelatedDeviceObject( pCacheFileObject),
1235 if (!NT_SUCCESS(ntStatus))
1238 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1239 AFS_TRACE_LEVEL_ERROR,
1240 "AFSNonCachedWrite (%p) Failed to initialize IO run block Status %08lX\n",
1244 try_return( ntStatus );
1247 AFSReferenceActiveExtents( pStartExtent,
1250 bDerefExtents = TRUE;
1252 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1253 AFS_TRACE_LEVEL_VERBOSE,
1254 "AFSNonCachedWrite Releasing(2) Fcb extents lock %p SHARED %08lX\n",
1255 &pFcb->NPFcb->Specific.File.ExtentsResource,
1256 PsGetCurrentThread());
1258 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1261 pGatherIo = (AFSGatherIo*) AFSExAllocatePoolWithTag( NonPagedPool,
1262 sizeof( AFSGatherIo),
1265 if (NULL == pGatherIo)
1268 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1269 AFS_TRACE_LEVEL_ERROR,
1270 "AFSNonCachedWrite (%p) Failed to allocate IO gather block\n",
1273 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1274 AFS_TRACE_LEVEL_VERBOSE,
1275 "AFSNonCachedWrite Acquiring(1) Fcb extents lock %p SHARED %08lX\n",
1276 &pFcb->NPFcb->Specific.File.ExtentsResource,
1277 PsGetCurrentThread());
1279 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1283 AFSDereferenceActiveExtents( pStartExtent,
1286 try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1289 RtlZeroMemory( pGatherIo, sizeof( AFSGatherIo ));
1292 // Initialize count to 1, that was we won't get an early
1293 // completion if the first irp completes before the second is
1296 pGatherIo->Count = 1;
1297 pGatherIo->Status = STATUS_SUCCESS;
1298 pGatherIo->MasterIrp = Irp;
1299 pGatherIo->Synchronous = TRUE;
1300 pGatherIo->CompleteMasterIrp = FALSE;
1302 bCompleteIrp = TRUE;
1304 if( pGatherIo->Synchronous)
1306 KeInitializeEvent( &pGatherIo->Event, NotificationEvent, FALSE );
1311 // Setup the MD5 for each extent
1314 AFSSetupMD5Hash( pFcb,
1323 // Pre-emptively set up the count
1326 Irp->IoStatus.Information = ByteCount;
1328 ntStatus = AFSQueueStartIos( pCacheFileObject,
1330 IRP_WRITE_OPERATION | IRP_SYNCHRONOUS_API,
1335 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1336 AFS_TRACE_LEVEL_VERBOSE,
1337 "AFSNonCachedWrite (%p) AFSStartIos completed Status %08lX\n",
1341 if( !NT_SUCCESS( ntStatus))
1344 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1345 AFS_TRACE_LEVEL_VERBOSE,
1346 "AFSNonCachedWrite Acquiring(2) Fcb extents lock %p SHARED %08lX\n",
1347 &pFcb->NPFcb->Specific.File.ExtentsResource,
1348 PsGetCurrentThread());
1350 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1354 AFSDereferenceActiveExtents( pStartExtent,
1357 try_return( ntStatus);
1361 // Wait for completion of All IOs we started.
1364 ntStatus = KeWaitForSingleObject( &pGatherIo->Event,
1370 if( NT_SUCCESS( ntStatus))
1373 ntStatus = pGatherIo->Status;
1376 if( !NT_SUCCESS( ntStatus))
1379 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1380 AFS_TRACE_LEVEL_VERBOSE,
1381 "AFSNonCachedWrite Acquiring(3) Fcb extents lock %p SHARED %08lX\n",
1382 &pFcb->NPFcb->Specific.File.ExtentsResource,
1383 PsGetCurrentThread());
1385 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1389 AFSDereferenceActiveExtents( pStartExtent,
1392 try_return( ntStatus);
1397 if( NT_SUCCESS( ntStatus) &&
1398 pStartExtent != NULL &&
1399 Irp->IoStatus.Information > 0)
1405 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1411 // Since this is dirty we can mark the extents dirty now.
1412 // AFSMarkDirty will dereference the extents. Do not call
1413 // AFSDereferenceActiveExtents() in this code path.
1425 // This was an uncached user write - tell the server to do
1426 // the flush when the worker thread next wakes up
1428 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1432 if( pCacheFileObject != NULL)
1434 AFSReleaseCacheFileObject( pCacheFileObject);
1437 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1438 AFS_TRACE_LEVEL_VERBOSE,
1439 "AFSNonCachedWrite (FO: %p) StartingByte %08lX:%08lX Length %08lX Status %08lX\n",
1441 StartingByte.HighPart,
1442 StartingByte.LowPart,
1446 if (NT_SUCCESS(ntStatus) &&
1451 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1457 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1458 AFS_TRACE_LEVEL_VERBOSE,
1459 "AFSNonCachedWrite Releasing Fcb extents lock %p SHARED %08lX\n",
1460 &pFcb->NPFcb->Specific.File.ExtentsResource,
1461 PsGetCurrentThread());
1463 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1468 AFSExFreePoolWithTag(pGatherIo, AFS_GATHER_TAG);
1471 if( NULL != pIoRuns &&
1472 stIoRuns != pIoRuns)
1474 AFSExFreePoolWithTag(pIoRuns, AFS_IO_RUN_TAG);
1480 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1481 AFS_TRACE_LEVEL_VERBOSE,
1482 "AFSNonCachedWrite Completing Irp %p Status %08lX Info %08lX\n",
1485 Irp->IoStatus.Information);
1487 AFSCompleteRequest( Irp, ntStatus);
1496 AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
1498 IN LARGE_INTEGER StartingByte,
1500 IN BOOLEAN ForceFlush)
1502 UNREFERENCED_PARAMETER(DeviceObject);
1503 PVOID pSystemBuffer = NULL;
1504 NTSTATUS ntStatus = STATUS_SUCCESS;
1505 IO_STATUS_BLOCK iosbFlush;
1506 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1507 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
1508 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
1509 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
1510 ULONG ulCurrentIO = 0, ulTotalLen = ByteCount;
1511 PMDL pCurrentMdl = Irp->MdlAddress;
1512 LARGE_INTEGER liCurrentOffset;
1517 Irp->IoStatus.Information = 0;
1519 if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1525 CcPrepareMdlWrite( pFileObject,
1531 ntStatus = Irp->IoStatus.Status;
1533 __except( EXCEPTION_EXECUTE_HANDLER)
1535 ntStatus = GetExceptionCode();
1537 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1538 AFS_TRACE_LEVEL_ERROR,
1539 "AFSCachedWrite (%p) Exception thrown while preparing mdl write Status %08lX\n",
1544 if( !NT_SUCCESS( ntStatus))
1548 // Free up any potentially allocated mdl's
1551 CcMdlWriteComplete( pFileObject,
1555 Irp->MdlAddress = NULL;
1557 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1558 AFS_TRACE_LEVEL_ERROR,
1559 "AFSCachedWrite (%p) Failed to process MDL write Status %08lX\n",
1564 try_return( ntStatus);
1567 liCurrentOffset.QuadPart = StartingByte.QuadPart;
1569 while( ulTotalLen > 0)
1572 ntStatus = STATUS_SUCCESS;
1574 if( pCurrentMdl != NULL)
1577 pSystemBuffer = MmGetSystemAddressForMdlSafe( pCurrentMdl,
1578 NormalPagePriority);
1580 ulCurrentIO = MmGetMdlByteCount( pCurrentMdl);
1582 if( ulCurrentIO > ulTotalLen)
1584 ulCurrentIO = ulTotalLen;
1590 pSystemBuffer = AFSLockSystemBuffer( Irp,
1593 ulCurrentIO = ulTotalLen;
1596 if( pSystemBuffer == NULL)
1599 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1600 AFS_TRACE_LEVEL_ERROR,
1601 "AFSCachedWrite (%p) Failed to lock system buffer\n",
1604 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1610 if( !CcCopyWrite( pFileObject,
1617 // Failed to process request.
1620 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1621 AFS_TRACE_LEVEL_ERROR,
1622 "AFSCachedWrite (%p) Failed to issue CcCopyWrite %wZ @ %0I64X Status %08lX\n",
1624 &pFileObject->FileName,
1625 liCurrentOffset.QuadPart,
1626 Irp->IoStatus.Status);
1628 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1631 __except( EXCEPTION_EXECUTE_HANDLER)
1634 ntStatus = GetExceptionCode();
1636 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1637 AFS_TRACE_LEVEL_ERROR,
1638 "AFSCachedWrite (%p) CcCopyWrite Threw exception %wZ @ %0I64X Status %08lX\n",
1640 &pFileObject->FileName,
1641 liCurrentOffset.QuadPart,
1645 if( !NT_SUCCESS( ntStatus))
1647 try_return( ntStatus);
1651 BooleanFlagOn(pFileObject->Flags, (FO_NO_INTERMEDIATE_BUFFERING + FO_WRITE_THROUGH)))
1655 // We have detected a file we do a write through with.
1658 CcFlushCache(&pFcb->NPFcb->SectionObjectPointers,
1663 if( !NT_SUCCESS( iosbFlush.Status))
1666 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1667 AFS_TRACE_LEVEL_ERROR,
1668 "AFSCachedWrite (%p) CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1670 &pFileObject->FileName,
1671 pFcb->ObjectInformation->FileId.Cell,
1672 pFcb->ObjectInformation->FileId.Volume,
1673 pFcb->ObjectInformation->FileId.Vnode,
1674 pFcb->ObjectInformation->FileId.Unique,
1676 iosbFlush.Information);
1678 try_return( ntStatus = iosbFlush.Status);
1682 if( ulTotalLen <= ulCurrentIO)
1687 liCurrentOffset.QuadPart += ulCurrentIO;
1689 ulTotalLen -= ulCurrentIO;
1691 pCurrentMdl = pCurrentMdl->Next;
1696 if( NT_SUCCESS( ntStatus))
1699 Irp->IoStatus.Information = ByteCount;
1704 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1708 // If this extended the Vdl, then update it accordingly
1711 if( StartingByte.QuadPart + ByteCount > pFcb->Header.ValidDataLength.QuadPart)
1714 pFcb->Header.ValidDataLength.QuadPart = StartingByte.QuadPart + ByteCount;
1718 BooleanFlagOn(pFileObject->Flags, (FO_NO_INTERMEDIATE_BUFFERING + FO_WRITE_THROUGH)))
1721 // Write through asked for... Set things so that we get
1722 // flush when the worker thread next wakes up
1724 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1727 if( !BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
1730 SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME);
1732 KeQuerySystemTime( &pFcb->ObjectInformation->LastWriteTime);
1736 AFSCompleteRequest( Irp,
1745 AFSExtendingWrite( IN AFSFcb *Fcb,
1746 IN PFILE_OBJECT FileObject,
1747 IN LONGLONG NewLength)
1749 LARGE_INTEGER liSaveFileSize = Fcb->Header.FileSize;
1750 LARGE_INTEGER liSaveAllocation = Fcb->Header.AllocationSize;
1751 NTSTATUS ntStatus = STATUS_SUCCESS;
1752 AFSCcb *pCcb = (AFSCcb *)FileObject->FsContext2;
1754 if( NewLength > Fcb->Header.AllocationSize.QuadPart)
1757 Fcb->Header.AllocationSize.QuadPart = NewLength;
1759 Fcb->ObjectInformation->AllocationSize = Fcb->Header.AllocationSize;
1762 if( NewLength > Fcb->Header.FileSize.QuadPart)
1765 Fcb->Header.FileSize.QuadPart = NewLength;
1767 Fcb->ObjectInformation->EndOfFile = Fcb->Header.FileSize;
1774 ntStatus = AFSUpdateFileInformation( &Fcb->ObjectInformation->ParentFileId,
1775 Fcb->ObjectInformation,
1778 if (NT_SUCCESS(ntStatus))
1781 KeQuerySystemTime( &Fcb->ObjectInformation->ChangeTime);
1783 SetFlag( Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1786 // If the file is currently cached, then let the MM know about the extension
1789 if( CcIsFileCached( FileObject))
1791 CcSetFileSizes( FileObject,
1792 (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
1797 Fcb->Header.FileSize = liSaveFileSize;
1798 Fcb->Header.AllocationSize = liSaveAllocation;
1802 // DownConvert file resource to shared
1804 ExConvertExclusiveToSharedLite( &Fcb->NPFcb->Resource);
1810 AFSShareWrite( IN PDEVICE_OBJECT DeviceObject,
1814 UNREFERENCED_PARAMETER(DeviceObject);
1815 NTSTATUS ntStatus = STATUS_SUCCESS;
1816 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1817 AFSFcb *pFcb = NULL;
1818 AFSCcb *pCcb = NULL;
1819 AFSPipeIORequestCB *pIoRequest = NULL;
1820 void *pBuffer = NULL;
1821 AFSPipeIOResultCB stIoResult;
1822 ULONG ulBytesReturned = 0;
1827 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1829 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1831 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1832 AFS_TRACE_LEVEL_VERBOSE,
1833 "AFSShareWrite On pipe %wZ Length %08lX\n",
1834 &pCcb->DirectoryCB->NameInformation.FileName,
1835 pIrpSp->Parameters.Write.Length);
1837 if( pIrpSp->Parameters.Write.Length == 0)
1841 // Nothing to do in this case
1844 try_return( ntStatus);
1848 // Retrieve the buffer for the read request
1851 pBuffer = AFSLockSystemBuffer( Irp,
1852 pIrpSp->Parameters.Write.Length);
1854 if( pBuffer == NULL)
1857 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1858 AFS_TRACE_LEVEL_ERROR,
1859 "AFSShareWrite Failed to map buffer on pipe %wZ\n",
1860 &pCcb->DirectoryCB->NameInformation.FileName);
1862 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1865 AFSAcquireShared( &pFcb->NPFcb->Resource,
1868 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1869 sizeof( AFSPipeIORequestCB) +
1870 pIrpSp->Parameters.Write.Length,
1871 AFS_GENERIC_MEMORY_14_TAG);
1873 if( pIoRequest == NULL)
1876 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1879 RtlZeroMemory( pIoRequest,
1880 sizeof( AFSPipeIORequestCB) + pIrpSp->Parameters.Write.Length);
1882 pIoRequest->RequestId = pCcb->RequestID;
1884 pIoRequest->RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1886 pIoRequest->BufferLength = pIrpSp->Parameters.Write.Length;
1888 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1890 pIrpSp->Parameters.Write.Length);
1892 stIoResult.BytesProcessed = 0;
1894 ulBytesReturned = sizeof( AFSPipeIOResultCB);
1897 // Issue the open request to the service
1900 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_WRITE,
1901 AFS_REQUEST_FLAG_SYNCHRONOUS,
1903 &pCcb->DirectoryCB->NameInformation.FileName,
1908 sizeof( AFSPipeIORequestCB) +
1909 pIrpSp->Parameters.Write.Length,
1913 if( !NT_SUCCESS( ntStatus))
1916 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1917 AFS_TRACE_LEVEL_ERROR,
1918 "AFSShareWrite (%p) Failed service write Status %08lX\n",
1922 try_return( ntStatus);
1925 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1926 AFS_TRACE_LEVEL_VERBOSE,
1927 "AFSShareWrite Completed on pipe %wZ Length read %08lX\n",
1928 &pCcb->DirectoryCB->NameInformation.FileName,
1929 stIoResult.BytesProcessed);
1931 Irp->IoStatus.Information = stIoResult.BytesProcessed;
1938 AFSReleaseResource( &pFcb->NPFcb->Resource);
1941 if( pIoRequest != NULL)
1944 AFSExFreePoolWithTag( pIoRequest, AFS_GENERIC_MEMORY_14_TAG);