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 NTSTATUS ntStatus = STATUS_SUCCESS;
82 ntStatus = AFSCommonWrite( AFSRDRDeviceObject, Irp, NULL);
84 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
87 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
94 AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
99 NTSTATUS ntStatus = STATUS_SUCCESS;
100 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
101 IO_STACK_LOCATION *pIrpSp;
104 AFSNonPagedFcb *pNPFcb = NULL;
105 ULONG ulByteCount = 0;
106 LARGE_INTEGER liStartingByte;
107 PFILE_OBJECT pFileObject;
108 BOOLEAN bPagingIo = FALSE;
109 BOOLEAN bNonCachedIo = FALSE;
110 BOOLEAN bReleaseMain = FALSE;
111 BOOLEAN bReleasePaging = FALSE;
112 BOOLEAN bExtendingWrite = FALSE;
113 BOOLEAN bCompleteIrp = TRUE;
114 BOOLEAN bForceFlush = FALSE;
116 BOOLEAN bMapped = TRUE;
117 HANDLE hCallingUser = OnBehalfOf;
118 ULONG ulExtensionLength = 0;
119 BOOLEAN bRetry = FALSE;
120 ULONGLONG ullProcessId = (ULONGLONG)PsGetCurrentProcessId();
122 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
127 pFileObject = pIrpSp->FileObject;
130 // Extract the fileobject references
133 pFcb = (AFSFcb *)pFileObject->FsContext;
134 pCcb = (AFSCcb *)pFileObject->FsContext2;
136 ObReferenceObject( pFileObject);
141 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
142 AFS_TRACE_LEVEL_ERROR,
143 "AFSCommonWrite Attempted write (%08lX) when pFcb == NULL\n",
146 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
149 pNPFcb = pFcb->NPFcb;
152 // If we are in shutdown mode then fail the request
155 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
159 AFS_TRACE_LEVEL_WARNING,
160 "AFSCommonWrite (%08lX) Open request after shutdown\n",
163 try_return( ntStatus = STATUS_TOO_LATE);
166 liStartingByte = pIrpSp->Parameters.Write.ByteOffset;
167 bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
168 bNonCachedIo = BooleanFlagOn( Irp->Flags, IRP_NOCACHE);
169 ulByteCount = pIrpSp->Parameters.Write.Length;
171 if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
172 pFcb->Header.NodeTypeCode != AFS_FILE_FCB &&
173 pFcb->Header.NodeTypeCode != AFS_SPECIAL_SHARE_FCB)
176 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
177 AFS_TRACE_LEVEL_ERROR,
178 "AFSCommonWrite Attempted write (%08lX) on an invalid node type %08lX\n",
180 pFcb->Header.NodeTypeCode);
182 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
186 // If this is a write against an IOCtl node then handle it
187 // in a different pathway
190 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
193 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
194 AFS_TRACE_LEVEL_VERBOSE,
195 "AFSCommonWrite (%08lX) Processing file (PIOCTL) Offset %I64X Length %08lX Irp Flags %08lX\n",
197 liStartingByte.QuadPart,
201 ntStatus = AFSIOCtlWrite( DeviceObject,
204 try_return( ntStatus);
206 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
209 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
210 AFS_TRACE_LEVEL_VERBOSE,
211 "AFSCommonWrite (%08lX) Processing file (SHARE) Offset %I64X Length %08lX Irp Flags %08lX\n",
213 liStartingByte.QuadPart,
217 ntStatus = AFSShareWrite( DeviceObject,
220 try_return( ntStatus);
224 // Is the Cache not there yet? Exit.
226 if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
227 NULL == pDeviceExt->Specific.RDR.CacheFileObject)
230 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
231 AFS_TRACE_LEVEL_ERROR,
232 "AFSCommonWrite (%08lX) Request failed due to AFS cache closed\n",
235 try_return( ntStatus = STATUS_TOO_LATE );
238 if( pFcb->ObjectInformation->VolumeCB != NULL &&
239 BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
242 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
243 AFS_TRACE_LEVEL_ERROR,
244 "AFSCommonWrite (%08lX) Request failed due to read only volume\n",
247 try_return( ntStatus = STATUS_ACCESS_DENIED);
251 // We need to know on whose behalf we have been called (which
252 // we will eventually tell to the server - for non paging
253 // writes). If we were posted then we were told. If this is
254 // the first time we saw the irp then we grab it now.
256 if( NULL == OnBehalfOf )
259 hCallingUser = PsGetCurrentProcessId();
264 hCallingUser = OnBehalfOf;
268 // Check for zero length write
271 if( ulByteCount == 0)
274 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSCommonWrite (%08lX) Request completed due to zero length\n",
279 try_return( ntStatus);
283 // Is this Fcb valid???
286 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID))
289 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
290 AFS_TRACE_LEVEL_ERROR,
291 "AFSCommonWrite (%08lX) Failing request due to INVALID fcb\n",
294 Irp->IoStatus.Information = 0;
296 try_return( ntStatus = STATUS_FILE_DELETED);
299 if( BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED) ||
300 BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
303 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
304 AFS_TRACE_LEVEL_ERROR,
305 "AFSCommonWrite (%08lX) Request failed due to file deleted\n",
308 try_return( ntStatus = STATUS_FILE_DELETED);
311 if( FlagOn( pIrpSp->MinorFunction, IRP_MN_COMPLETE))
314 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
315 AFS_TRACE_LEVEL_VERBOSE,
316 "AFSCommonWrite (%08lX) IRP_MN_COMPLETE being processed\n",
319 CcMdlWriteComplete(pFileObject, &pIrpSp->Parameters.Write.ByteOffset, Irp->MdlAddress);
322 // Mdl is now Deallocated
325 Irp->MdlAddress = NULL;
327 try_return( ntStatus = STATUS_SUCCESS );
331 // If we get a non cached IO for a cached file we should do a purge.
332 // For now we will just promote to cached
334 if( NULL != pFileObject->SectionObjectPointer->DataSectionObject && !bPagingIo && bNonCachedIo)
336 bNonCachedIo = FALSE;
340 if( (!bPagingIo && !bNonCachedIo))
343 if( pFileObject->PrivateCacheMap == NULL)
349 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
350 AFS_TRACE_LEVEL_VERBOSE,
351 "AFSCommonWrite Initialize caching on Fcb %08lX FileObject %08lX\n",
355 CcInitializeCacheMap( pFileObject,
356 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
358 AFSLibCacheManagerCallbacks,
361 CcSetReadAheadGranularity( pFileObject,
362 pDeviceExt->Specific.RDR.MaximumRPCLength);
364 CcSetDirtyPageThreshold( pFileObject,
365 AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength);
367 __except( EXCEPTION_EXECUTE_HANDLER)
370 ntStatus = GetExceptionCode();
372 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
373 AFS_TRACE_LEVEL_ERROR,
374 "AFSCommonWrite (%08lX) Exception thrown while initializing cache map Status %08lX\n",
379 if( !NT_SUCCESS( ntStatus))
382 try_return( ntStatus);
387 while (!bNonCachedIo && !CcCanIWrite( pFileObject,
392 static const LONGLONG llWriteDelay = (LONGLONG)-100000;
394 KeDelayExecutionThread(KernelMode, FALSE, (PLARGE_INTEGER)&llWriteDelay);
398 // Save off the PID if this is not a paging IO
402 ( pFcb->Specific.File.ExtentRequestProcessId == 0 ||
403 ( ullProcessId != (ULONGLONG)AFSSysProcess &&
404 pFcb->Specific.File.ExtentRequestProcessId != ullProcessId)))
407 pFcb->Specific.File.ExtentRequestProcessId = ullProcessId;
409 if( ullProcessId == (ULONGLONG)AFSSysProcess)
411 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
412 AFS_TRACE_LEVEL_WARNING,
413 "%s Setting LastWriterExtentProcessId to system process for Fcb %p\n",
420 // We should be ready to go. So first of all ask for the extents
421 // Provoke a get of the extents - if we need to.
425 if( !bPagingIo && !bNonCachedIo)
428 ntStatus = AFSRequestExtentsAsync( pFcb, pCcb, &liStartingByte, ulByteCount);
430 if (!NT_SUCCESS(ntStatus))
433 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
434 AFS_TRACE_LEVEL_ERROR,
435 "AFSCommonWrite (%08lX) Failed to request extents Status %08lX\n",
439 try_return( ntStatus );
445 // If they are not mapped and we are the Lazy Writer then just
448 if (!bMapped && pFcb->Specific.File.LazyWriterThread == PsGetCurrentThread())
451 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
452 AFS_TRACE_LEVEL_VERBOSE,
453 "AFSCommonWrite (%08lX) Failing lazy writer for unmapped request\n",
456 try_return ( ntStatus = STATUS_FILE_LOCK_CONFLICT);
462 // - if Paging then we need to nothing (the precalls will
463 // have acquired the paging resource), for clarity we will collect
464 // the paging resource
465 // - If extending Write then take the fileresource EX (EOF will change, Allocation will only move out)
466 // - Otherwise we collect the file shared, check against extending and
477 bExtendingWrite = (((liStartingByte.QuadPart + ulByteCount) >=
478 pFcb->Header.FileSize.QuadPart) ||
479 (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
480 liStartingByte.HighPart == -1)) ;
486 //ASSERT( NULL != OnBehalfOf || ExIsResourceAcquiredLite( &pNPFcb->Resource ));
488 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
489 AFS_TRACE_LEVEL_VERBOSE,
490 "AFSCommonWrite Acquiring Fcb PagingIo lock %08lX SHARED %08lX\n",
491 &pNPFcb->PagingResource,
492 PsGetCurrentThread());
494 AFSAcquireShared( &pNPFcb->PagingResource,
497 bReleasePaging = TRUE;
500 // We have the correct lock - we cannot have the wrong one
504 else if( bExtendingWrite)
507 // Check for lock inversion
510 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
512 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
513 AFS_TRACE_LEVEL_VERBOSE,
514 "AFSCommonWrite Acquiring Fcb lock %08lX EXCL %08lX\n",
516 PsGetCurrentThread());
518 AFSAcquireExcl( &pNPFcb->Resource,
521 if (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
522 liStartingByte.HighPart == -1)
524 if (pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
526 liStartingByte = pFcb->Header.ValidDataLength;
530 liStartingByte = pFcb->Header.FileSize;
536 // We have the correct lock - even if we don't end up truncating
542 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
544 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
545 AFS_TRACE_LEVEL_VERBOSE,
546 "AFSCommonWrite Acquiring Fcb lock %08lX SHARED %08lX\n",
548 PsGetCurrentThread());
550 AFSAcquireShared( &pNPFcb->Resource,
556 // Have things moved? Are we extending? If so, the the lock isn't OK
558 bLockOK = (liStartingByte.QuadPart + ulByteCount) < pFcb->Header.FileSize.QuadPart;
562 AFSReleaseResource( &pNPFcb->Resource);
563 bReleaseMain = FALSE;
570 // Check the BR locks on the file.
574 !FsRtlCheckLockForWriteAccess( &pFcb->Specific.File.FileLock,
578 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
579 AFS_TRACE_LEVEL_ERROR,
580 "AFSCommonWrite (%08lX) Request failed due to lock conflict\n",
583 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
589 ntStatus = AFSExtendingWrite( pFcb, pFileObject, (liStartingByte.QuadPart + ulByteCount));
591 if( !NT_SUCCESS(ntStatus))
594 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
595 AFS_TRACE_LEVEL_ERROR,
596 "AFSCommonWrite (%08lX) Failed extending write request Status %08lX\n",
600 try_return( ntStatus );
605 // Fire off the request as appropriate
607 bCompleteIrp = FALSE;
613 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
614 AFS_TRACE_LEVEL_VERBOSE,
615 "AFSCommonWrite (%08lX) Processing CACHED request Offset %I64X Len %08lX\n",
617 liStartingByte.QuadPart,
620 ntStatus = AFSCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount, bForceFlush);
626 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
627 AFS_TRACE_LEVEL_VERBOSE,
628 "AFSCommonWrite (%08lX) Processing NON-CACHED request Offset %I64X Len %08lX\n",
630 liStartingByte.QuadPart,
633 ntStatus = AFSNonCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount);
638 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
639 AFS_TRACE_LEVEL_VERBOSE,
640 "AFSCommonWrite (%08lX) Process complete Status %08lX\n",
644 ObDereferenceObject(pFileObject);
649 AFSReleaseResource( &pNPFcb->Resource);
655 AFSReleaseResource( &pNPFcb->PagingResource);
661 AFSCompleteRequest( Irp,
670 AFSIOCtlWrite( IN PDEVICE_OBJECT DeviceObject,
674 NTSTATUS ntStatus = STATUS_SUCCESS;
675 AFSPIOCtlIORequestCB stIORequestCB;
676 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
679 AFSPIOCtlIOResultCB stIOResultCB;
680 ULONG ulBytesReturned = 0;
681 AFSFileID stParentFID;
686 RtlZeroMemory( &stIORequestCB,
687 sizeof( AFSPIOCtlIORequestCB));
689 if( pIrpSp->Parameters.Write.Length == 0)
693 // Nothing to do in this case
696 try_return( ntStatus);
699 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
701 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
703 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
704 AFS_TRACE_LEVEL_VERBOSE,
705 "AFSIOCtlWrite Acquiring Fcb lock %08lX SHARED %08lX\n",
706 &pFcb->NPFcb->Resource,
707 PsGetCurrentThread());
709 AFSAcquireShared( &pFcb->NPFcb->Resource,
713 // Get the parent fid to pass to the cm
716 RtlZeroMemory( &stParentFID,
719 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
723 // The parent directory FID of the node
726 stParentFID = pFcb->ObjectInformation->ParentObjectInformation->FileId;
730 // Set the control block up
733 stIORequestCB.RequestId = pCcb->RequestID;
735 if( pFcb->ObjectInformation->VolumeCB != NULL)
737 stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
741 // Lock down the buffer
744 stIORequestCB.MappedBuffer = AFSMapToService( Irp,
745 pIrpSp->Parameters.Write.Length);
747 if( stIORequestCB.MappedBuffer == NULL)
750 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
753 stIORequestCB.BufferLength = pIrpSp->Parameters.Write.Length;
755 stIOResultCB.BytesProcessed = 0;
757 ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
760 // Issue the request to the service
763 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_WRITE,
764 AFS_REQUEST_FLAG_SYNCHRONOUS,
768 (void *)&stIORequestCB,
769 sizeof( AFSPIOCtlIORequestCB),
773 if( !NT_SUCCESS( ntStatus))
776 try_return( ntStatus);
780 // Update the length written
783 Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
787 if( stIORequestCB.MappedBuffer != NULL)
790 AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
797 AFSReleaseResource( &pFcb->NPFcb->Resource);
805 // This function is called when we know we have to read from the AFS Cache.
807 // It ensures that we have exents for the entirety of the write and
808 // then pins the extents into memory (meaning that although we may
809 // add we will not remove). Then it creates a scatter gather write
810 // and fires off the IRPs
814 AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject,
816 IN LARGE_INTEGER StartingByte,
819 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
820 VOID *pSystemBuffer = NULL;
821 BOOLEAN bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
822 BOOLEAN bLocked = FALSE;
823 BOOLEAN bCompleteIrp = TRUE;
824 BOOLEAN bExtentsMapped = FALSE;
825 AFSGatherIo *pGatherIo = NULL;
826 AFSIoRun *pIoRuns = NULL;
827 AFSIoRun stIoRuns[AFS_MAX_STACK_IO_RUNS];
828 ULONG extentsCount = 0, runCount = 0;
829 AFSExtent *pStartExtent = NULL;
830 AFSExtent *pIgnoreExtent = NULL;
831 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
832 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
833 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
834 AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
835 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
836 AFSDeviceExt *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
837 ULONG ulRequestCount = 0;
838 LARGE_INTEGER liCurrentTime, liLastRequestTime;
839 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
840 PFILE_OBJECT pCacheFileObject = NULL;
841 BOOLEAN bDerefExtents = FALSE;
845 Irp->IoStatus.Information = 0;
847 if (ByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
850 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
851 AFS_TRACE_LEVEL_ERROR,
852 "AFSNonCachedWrite (%08lX) Request %08lX Actual %08lX larger than MaxIO %I64X\n",
855 pIrpSp->Parameters.Write.Length,
856 pDevExt->Specific.RDR.MaxIo.QuadPart);
858 try_return( ntStatus = STATUS_UNSUCCESSFUL);
862 // Get the mapping for the buffer
864 pSystemBuffer = AFSLockSystemBuffer( Irp,
867 if( pSystemBuffer == NULL)
870 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
871 AFS_TRACE_LEVEL_ERROR,
872 "AFSNonCachedWrite (%08lX) Failed to map system buffer\n",
875 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
880 // Provoke a get of the extents - if we need to.
883 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
884 AFS_TRACE_LEVEL_VERBOSE,
885 "AFSNonCachedWrite Requesting extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
886 pFcb->ObjectInformation->FileId.Cell,
887 pFcb->ObjectInformation->FileId.Volume,
888 pFcb->ObjectInformation->FileId.Vnode,
889 pFcb->ObjectInformation->FileId.Unique,
890 StartingByte.QuadPart,
893 ntStatus = AFSRequestExtentsAsync( pFcb,
898 if (!NT_SUCCESS(ntStatus))
901 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
902 AFS_TRACE_LEVEL_ERROR,
903 "AFSNonCachedWrite (%08lX) Failed to request extents Status %08lX\n",
907 try_return( ntStatus);
910 KeQueryTickCount( &liLastRequestTime);
915 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
916 AFS_TRACE_LEVEL_VERBOSE,
917 "AFSNonCachedWrite Acquiring Fcb extents lock %08lX SHARED %08lX\n",
918 &pFcb->NPFcb->Specific.File.ExtentsResource,
919 PsGetCurrentThread());
921 ASSERT( !ExIsResourceAcquiredLite( &pFcb->NPFcb->Specific.File.ExtentsResource ));
923 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource, TRUE );
927 pIgnoreExtent = NULL;
929 if ( AFSDoExtentsMapRegion( pFcb, &StartingByte, ByteCount, &pStartExtent, &pIgnoreExtent ))
934 KeClearEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete );
936 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
937 AFS_TRACE_LEVEL_VERBOSE,
938 "AFSNonCachedWrite Releasing(1) Fcb extents lock %08lX SHARED %08lX\n",
939 &pFcb->NPFcb->Specific.File.ExtentsResource,
940 PsGetCurrentThread());
942 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
946 // We will re-request the extents after waiting for them
949 KeQueryTickCount( &liCurrentTime);
951 if( liCurrentTime.QuadPart - liLastRequestTime.QuadPart >= pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart)
954 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
955 AFS_TRACE_LEVEL_VERBOSE,
956 "AFSNonCachedWrite Requesting extents, again, for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
957 pFcb->ObjectInformation->FileId.Cell,
958 pFcb->ObjectInformation->FileId.Volume,
959 pFcb->ObjectInformation->FileId.Vnode,
960 pFcb->ObjectInformation->FileId.Unique,
961 StartingByte.QuadPart,
964 ntStatus = AFSRequestExtentsAsync( pFcb,
969 if (!NT_SUCCESS(ntStatus))
972 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
973 AFS_TRACE_LEVEL_ERROR,
974 "AFSNonCachedWrite (%08lX) Failed to request extents Status %08lX\n",
978 try_return( ntStatus);
981 KeQueryTickCount( &liLastRequestTime);
985 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
986 AFS_TRACE_LEVEL_VERBOSE,
987 "AFSNonCachedWrite Waiting for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
988 pFcb->ObjectInformation->FileId.Cell,
989 pFcb->ObjectInformation->FileId.Volume,
990 pFcb->ObjectInformation->FileId.Vnode,
991 pFcb->ObjectInformation->FileId.Unique,
992 StartingByte.QuadPart,
999 ntStatus = AFSWaitForExtentMapping ( pFcb, pCcb);
1001 if (!NT_SUCCESS(ntStatus))
1004 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1005 AFS_TRACE_LEVEL_ERROR,
1006 "AFSNonCachedWrite Failed wait for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
1007 pFcb->ObjectInformation->FileId.Cell,
1008 pFcb->ObjectInformation->FileId.Volume,
1009 pFcb->ObjectInformation->FileId.Vnode,
1010 pFcb->ObjectInformation->FileId.Unique,
1011 StartingByte.QuadPart,
1015 try_return( ntStatus);
1020 // As per the read path -
1023 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1024 AFS_TRACE_LEVEL_VERBOSE,
1025 "AFSNonCachedWrite Extents located for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
1026 pFcb->ObjectInformation->FileId.Cell,
1027 pFcb->ObjectInformation->FileId.Volume,
1028 pFcb->ObjectInformation->FileId.Vnode,
1029 pFcb->ObjectInformation->FileId.Unique,
1030 StartingByte.QuadPart,
1033 ntStatus = AFSGetExtents( pFcb,
1040 if (!NT_SUCCESS(ntStatus))
1043 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1044 AFS_TRACE_LEVEL_ERROR,
1045 "AFSNonCachedWrite (%08lX) Failed to retrieve mapped extents Status %08lX\n",
1049 try_return( ntStatus );
1052 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1053 AFS_TRACE_LEVEL_VERBOSE,
1054 "AFSNonCachedWrite (%08lX) Successfully retrieved map extents count %08lX run count %08lX\n",
1059 if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
1062 Irp->IoStatus.Information = ByteCount;
1066 // Setup the MD5 for each extent
1069 AFSSetupMD5Hash( pFcb,
1077 ntStatus = AFSProcessExtentRun( pSystemBuffer,
1083 if (!NT_SUCCESS(ntStatus))
1086 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1087 AFS_TRACE_LEVEL_ERROR,
1088 "AFSNonCachedWrite (%08lX) Failed to process extent run for non-persistent cache Status %08lX\n",
1093 try_return( ntStatus);
1097 // Retrieve the cache file object
1100 pCacheFileObject = AFSReferenceCacheFileObject();
1102 if( pCacheFileObject == NULL)
1105 ntStatus = STATUS_DEVICE_NOT_READY;
1107 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1108 AFS_TRACE_LEVEL_ERROR,
1109 "AFSNonCachedWrite Failed to retrieve cache fileobject for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
1110 pFcb->ObjectInformation->FileId.Cell,
1111 pFcb->ObjectInformation->FileId.Volume,
1112 pFcb->ObjectInformation->FileId.Vnode,
1113 pFcb->ObjectInformation->FileId.Unique,
1114 StartingByte.QuadPart,
1118 try_return( ntStatus);
1121 if (runCount > AFS_MAX_STACK_IO_RUNS)
1124 pIoRuns = (AFSIoRun*) AFSExAllocatePoolWithTag( PagedPool,
1125 runCount * sizeof( AFSIoRun ),
1127 if (NULL == pIoRuns)
1130 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1131 AFS_TRACE_LEVEL_ERROR,
1132 "AFSNonCachedWrite (%08lX) Failed to allocate IO run block\n",
1135 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1144 RtlZeroMemory( pIoRuns, runCount * sizeof( AFSIoRun ));
1146 ntStatus = AFSSetupIoRun( IoGetRelatedDeviceObject( pCacheFileObject),
1155 if (!NT_SUCCESS(ntStatus))
1158 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1159 AFS_TRACE_LEVEL_ERROR,
1160 "AFSNonCachedWrite (%08lX) Failed to initialize IO run block Status %08lX\n",
1164 try_return( ntStatus );
1167 AFSReferenceActiveExtents( pStartExtent,
1170 bDerefExtents = TRUE;
1172 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1173 AFS_TRACE_LEVEL_VERBOSE,
1174 "AFSNonCachedWrite Releasing(2) Fcb extents lock %08lX SHARED %08lX\n",
1175 &pFcb->NPFcb->Specific.File.ExtentsResource,
1176 PsGetCurrentThread());
1178 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1181 pGatherIo = (AFSGatherIo*) AFSExAllocatePoolWithTag( NonPagedPool,
1182 sizeof( AFSGatherIo),
1185 if (NULL == pGatherIo)
1188 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1189 AFS_TRACE_LEVEL_ERROR,
1190 "AFSNonCachedWrite (%08lX) Failed to allocate IO gather block\n",
1193 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1194 AFS_TRACE_LEVEL_VERBOSE,
1195 "AFSNonCachedWrite Acquiring(1) Fcb extents lock %08lX SHARED %08lX\n",
1196 &pFcb->NPFcb->Specific.File.ExtentsResource,
1197 PsGetCurrentThread());
1199 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1203 AFSDereferenceActiveExtents( pStartExtent,
1206 try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1209 RtlZeroMemory( pGatherIo, sizeof( AFSGatherIo ));
1212 // Initialize count to 1, that was we won't get an early
1213 // completion if the first irp completes before the second is
1216 pGatherIo->Count = 1;
1217 pGatherIo->Status = STATUS_SUCCESS;
1218 pGatherIo->MasterIrp = Irp;
1219 pGatherIo->Synchronous = TRUE;
1220 pGatherIo->CompleteMasterIrp = FALSE;
1222 bCompleteIrp = TRUE;
1224 if( pGatherIo->Synchronous)
1226 KeInitializeEvent( &pGatherIo->Event, NotificationEvent, FALSE );
1231 // Setup the MD5 for each extent
1234 AFSSetupMD5Hash( pFcb,
1243 // Pre-emptively set up the count
1246 Irp->IoStatus.Information = ByteCount;
1248 ntStatus = AFSQueueStartIos( pCacheFileObject,
1250 IRP_WRITE_OPERATION | IRP_SYNCHRONOUS_API,
1255 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1256 AFS_TRACE_LEVEL_VERBOSE,
1257 "AFSNonCachedWrite (%08lX) AFSStartIos completed Status %08lX\n",
1261 if( !NT_SUCCESS( ntStatus))
1264 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1265 AFS_TRACE_LEVEL_VERBOSE,
1266 "AFSNonCachedWrite Acquiring(2) Fcb extents lock %08lX SHARED %08lX\n",
1267 &pFcb->NPFcb->Specific.File.ExtentsResource,
1268 PsGetCurrentThread());
1270 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1274 AFSDereferenceActiveExtents( pStartExtent,
1277 try_return( ntStatus);
1281 // Wait for completion of All IOs we started.
1284 ntStatus = KeWaitForSingleObject( &pGatherIo->Event,
1290 if( NT_SUCCESS( ntStatus))
1293 ntStatus = pGatherIo->Status;
1296 if( !NT_SUCCESS( ntStatus))
1299 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1300 AFS_TRACE_LEVEL_VERBOSE,
1301 "AFSNonCachedWrite Acquiring(3) Fcb extents lock %08lX SHARED %08lX\n",
1302 &pFcb->NPFcb->Specific.File.ExtentsResource,
1303 PsGetCurrentThread());
1305 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1309 AFSDereferenceActiveExtents( pStartExtent,
1312 try_return( ntStatus);
1317 if( NT_SUCCESS( ntStatus) &&
1318 pStartExtent != NULL &&
1319 Irp->IoStatus.Information > 0)
1323 // Since this is dirty we can mark the extents dirty now.
1324 // AFSMarkDirty will dereference the extents. Do not call
1325 // AFSDereferenceActiveExtents() in this code path.
1337 // This was an uncached user write - tell the server to do
1338 // the flush when the worker thread next wakes up
1340 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1344 if( pCacheFileObject != NULL)
1346 AFSReleaseCacheFileObject( pCacheFileObject);
1349 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1350 AFS_TRACE_LEVEL_VERBOSE,
1351 "AFSNonCachedWrite (%08lX) Completed request Status %08lX\n",
1355 if (NT_SUCCESS(ntStatus) &&
1360 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1366 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1367 AFS_TRACE_LEVEL_VERBOSE,
1368 "AFSNonCachedWrite Releasing Fcb extents lock %08lX SHARED %08lX\n",
1369 &pFcb->NPFcb->Specific.File.ExtentsResource,
1370 PsGetCurrentThread());
1372 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1377 AFSExFreePool(pGatherIo);
1380 if( NULL != pIoRuns &&
1381 stIoRuns != pIoRuns)
1383 AFSExFreePool(pIoRuns);
1389 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1390 AFS_TRACE_LEVEL_VERBOSE,
1391 "AFSNonCachedWrite Completing Irp %08lX Status %08lX Info %08lX\n",
1394 Irp->IoStatus.Information);
1396 AFSCompleteRequest( Irp, ntStatus);
1405 AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
1407 IN LARGE_INTEGER StartingByte,
1409 IN BOOLEAN ForceFlush)
1411 PVOID pSystemBuffer = NULL;
1412 NTSTATUS ntStatus = STATUS_SUCCESS;
1413 IO_STATUS_BLOCK iosbFlush;
1414 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1415 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
1416 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
1417 AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
1418 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
1419 BOOLEAN bMapped = FALSE;
1420 ULONG ulCurrentIO = 0, ulTotalLen = ByteCount;
1421 PMDL pCurrentMdl = Irp->MdlAddress;
1422 LARGE_INTEGER liCurrentOffset;
1427 Irp->IoStatus.Information = 0;
1429 if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1435 CcPrepareMdlWrite( pFileObject,
1441 ntStatus = Irp->IoStatus.Status;
1443 __except( EXCEPTION_EXECUTE_HANDLER)
1445 ntStatus = GetExceptionCode();
1447 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1448 AFS_TRACE_LEVEL_ERROR,
1449 "AFSCachedWrite (%08lX) Exception thrown while preparing mdl write Status %08lX\n",
1454 if( !NT_SUCCESS( ntStatus))
1458 // Free up any potentially allocated mdl's
1461 CcMdlWriteComplete( pFileObject,
1465 Irp->MdlAddress = NULL;
1467 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1468 AFS_TRACE_LEVEL_ERROR,
1469 "AFSCachedWrite (%08lX) Failed to process MDL write Status %08lX\n",
1474 try_return( ntStatus);
1477 liCurrentOffset.QuadPart = StartingByte.QuadPart;
1479 while( ulTotalLen > 0)
1482 ntStatus = STATUS_SUCCESS;
1484 if( pCurrentMdl != NULL)
1487 pSystemBuffer = MmGetSystemAddressForMdlSafe( pCurrentMdl,
1488 NormalPagePriority);
1490 ulCurrentIO = MmGetMdlByteCount( pCurrentMdl);
1492 if( ulCurrentIO > ulTotalLen)
1494 ulCurrentIO = ulTotalLen;
1500 pSystemBuffer = AFSLockSystemBuffer( Irp,
1503 ulCurrentIO = ulTotalLen;
1506 if( pSystemBuffer == NULL)
1509 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1510 AFS_TRACE_LEVEL_ERROR,
1511 "AFSCachedWrite (%08lX) Failed to lock system buffer\n",
1514 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1520 if( !CcCopyWrite( pFileObject,
1527 // Failed to process request.
1530 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1531 AFS_TRACE_LEVEL_ERROR,
1532 "AFSCachedWrite (%08lX) Failed to issue CcCopyWrite %wZ @ %0I64X Status %08lX\n",
1534 &pFileObject->FileName,
1535 liCurrentOffset.QuadPart,
1536 Irp->IoStatus.Status);
1538 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1541 __except( EXCEPTION_EXECUTE_HANDLER)
1544 ntStatus = GetExceptionCode();
1546 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1547 AFS_TRACE_LEVEL_ERROR,
1548 "AFSCachedWrite (%08lX) CcCopyWrite Threw exception %wZ @ %0I64X Status %08lX\n",
1550 &pFileObject->FileName,
1551 liCurrentOffset.QuadPart,
1555 if( !NT_SUCCESS( ntStatus))
1557 try_return( ntStatus);
1564 // We have detected a file we do a write through with.
1567 CcFlushCache(&pFcb->NPFcb->SectionObjectPointers,
1572 if( !NT_SUCCESS( iosbFlush.Status))
1575 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1576 AFS_TRACE_LEVEL_ERROR,
1577 "AFSCachedWrite (%08lX) CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1579 &pFileObject->FileName,
1580 pFcb->ObjectInformation->FileId.Cell,
1581 pFcb->ObjectInformation->FileId.Volume,
1582 pFcb->ObjectInformation->FileId.Vnode,
1583 pFcb->ObjectInformation->FileId.Unique,
1585 iosbFlush.Information);
1587 try_return( ntStatus = iosbFlush.Status);
1591 if( ulTotalLen <= ulCurrentIO)
1596 liCurrentOffset.QuadPart += ulCurrentIO;
1598 ulTotalLen -= ulCurrentIO;
1600 pCurrentMdl = pCurrentMdl->Next;
1605 if( NT_SUCCESS( ntStatus))
1608 Irp->IoStatus.Information = ByteCount;
1613 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1617 // If this extended the Vdl, then update it accordingly
1620 if( StartingByte.QuadPart + ByteCount > pFcb->Header.ValidDataLength.QuadPart)
1623 pFcb->Header.ValidDataLength.QuadPart = StartingByte.QuadPart + ByteCount;
1626 if (BooleanFlagOn(pFileObject->Flags, (FO_NO_INTERMEDIATE_BUFFERING + FO_WRITE_THROUGH)))
1629 // Write through asked for... Set things so that we get
1630 // flush when the worker thread next wakes up
1632 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1635 if( !BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
1638 SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME);
1640 KeQuerySystemTime( &pFcb->ObjectInformation->LastWriteTime);
1644 AFSCompleteRequest( Irp,
1653 AFSExtendingWrite( IN AFSFcb *Fcb,
1654 IN PFILE_OBJECT FileObject,
1655 IN LONGLONG NewLength)
1657 LARGE_INTEGER liSaveFileSize = Fcb->Header.FileSize;
1658 LARGE_INTEGER liSaveAllocation = Fcb->Header.AllocationSize;
1659 NTSTATUS ntStatus = STATUS_SUCCESS;
1660 AFSCcb *pCcb = (AFSCcb *)FileObject->FsContext2;
1662 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1663 AFS_TRACE_LEVEL_VERBOSE,
1664 "AFSExtendingWrite Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
1665 &Fcb->NPFcb->PagingResource,
1666 PsGetCurrentThread());
1668 AFSAcquireExcl( &Fcb->NPFcb->PagingResource,
1671 if( NewLength > Fcb->Header.AllocationSize.QuadPart)
1674 Fcb->Header.AllocationSize.QuadPart = NewLength;
1676 Fcb->ObjectInformation->AllocationSize = Fcb->Header.AllocationSize;
1679 if( NewLength > Fcb->Header.FileSize.QuadPart)
1682 Fcb->Header.FileSize.QuadPart = NewLength;
1684 Fcb->ObjectInformation->EndOfFile = Fcb->Header.FileSize;
1691 ntStatus = AFSUpdateFileInformation( &Fcb->ObjectInformation->ParentObjectInformation->FileId,
1692 Fcb->ObjectInformation,
1695 if (NT_SUCCESS(ntStatus))
1698 KeQuerySystemTime( &Fcb->ObjectInformation->ChangeTime);
1700 SetFlag( Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1703 // If the file is currently cached, then let the MM know about the extension
1706 if( CcIsFileCached( FileObject))
1708 CcSetFileSizes( FileObject,
1709 (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
1714 Fcb->Header.FileSize = liSaveFileSize;
1715 Fcb->Header.AllocationSize = liSaveAllocation;
1718 AFSReleaseResource( &Fcb->NPFcb->PagingResource);
1721 // DownConvert file resource to shared
1723 ExConvertExclusiveToSharedLite( &Fcb->NPFcb->Resource);
1729 AFSShareWrite( IN PDEVICE_OBJECT DeviceObject,
1733 NTSTATUS ntStatus = STATUS_SUCCESS;
1734 AFSPIOCtlIORequestCB stIORequestCB;
1735 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1736 AFSFcb *pFcb = NULL;
1737 AFSCcb *pCcb = NULL;
1738 AFSPipeIORequestCB *pIoRequest = NULL;
1739 void *pBuffer = NULL;
1740 AFSPipeIOResultCB stIoResult;
1741 ULONG ulBytesReturned = 0;
1746 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1748 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1750 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1751 AFS_TRACE_LEVEL_VERBOSE,
1752 "AFSShareWrite On pipe %wZ Length %08lX\n",
1753 &pCcb->DirectoryCB->NameInformation.FileName,
1754 pIrpSp->Parameters.Write.Length);
1756 if( pIrpSp->Parameters.Write.Length == 0)
1760 // Nothing to do in this case
1763 try_return( ntStatus);
1767 // Retrieve the buffer for the read request
1770 pBuffer = AFSLockSystemBuffer( Irp,
1771 pIrpSp->Parameters.Write.Length);
1773 if( pBuffer == NULL)
1776 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1777 AFS_TRACE_LEVEL_ERROR,
1778 "AFSShareWrite Failed to map buffer on pipe %wZ\n",
1779 &pCcb->DirectoryCB->NameInformation.FileName);
1781 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1784 AFSAcquireShared( &pFcb->NPFcb->Resource,
1787 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1788 sizeof( AFSPipeIORequestCB) +
1789 pIrpSp->Parameters.Write.Length,
1790 AFS_GENERIC_MEMORY_14_TAG);
1792 if( pIoRequest == NULL)
1795 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1798 RtlZeroMemory( pIoRequest,
1799 sizeof( AFSPipeIORequestCB) + pIrpSp->Parameters.Write.Length);
1801 pIoRequest->RequestId = pCcb->RequestID;
1803 pIoRequest->RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1805 pIoRequest->BufferLength = pIrpSp->Parameters.Write.Length;
1807 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1809 pIrpSp->Parameters.Write.Length);
1811 stIoResult.BytesProcessed = 0;
1813 ulBytesReturned = sizeof( AFSPipeIOResultCB);
1816 // Issue the open request to the service
1819 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_WRITE,
1820 AFS_REQUEST_FLAG_SYNCHRONOUS,
1822 &pCcb->DirectoryCB->NameInformation.FileName,
1825 sizeof( AFSPipeIORequestCB) +
1826 pIrpSp->Parameters.Write.Length,
1830 if( !NT_SUCCESS( ntStatus))
1833 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1834 AFS_TRACE_LEVEL_ERROR,
1835 "AFSShareWrite (%08lX) Failed service write Status %08lX\n",
1839 try_return( ntStatus);
1842 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1843 AFS_TRACE_LEVEL_VERBOSE,
1844 "AFSShareWrite Completed on pipe %wZ Length read %08lX\n",
1845 &pCcb->DirectoryCB->NameInformation.FileName,
1846 stIoResult.BytesProcessed);
1848 Irp->IoStatus.Information = stIoResult.BytesProcessed;
1855 AFSReleaseResource( &pFcb->NPFcb->Resource);
1858 if( pIoRequest != NULL)
1861 AFSExFreePool( pIoRequest);