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( 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;
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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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;
339 if( (!bPagingIo && !bNonCachedIo))
342 if( pFileObject->PrivateCacheMap == NULL)
348 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
349 AFS_TRACE_LEVEL_VERBOSE,
350 "AFSCommonWrite Initialize caching on Fcb %08lX FileObject %08lX\n",
354 CcInitializeCacheMap( pFileObject,
355 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
357 AFSLibCacheManagerCallbacks,
360 CcSetReadAheadGranularity( pFileObject,
361 READ_AHEAD_GRANULARITY);
364 __except( EXCEPTION_EXECUTE_HANDLER)
367 ntStatus = GetExceptionCode();
369 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
370 AFS_TRACE_LEVEL_ERROR,
371 "AFSCommonWrite (%08lX) Exception thrown while initializing cache map Status %08lX\n",
376 if( !NT_SUCCESS( ntStatus))
379 try_return( ntStatus);
384 while (!bNonCachedIo && !CcCanIWrite( pFileObject,
389 static const LONGLONG llWriteDelay = (LONGLONG)-100000;
391 KeDelayExecutionThread(KernelMode, FALSE, (PLARGE_INTEGER)&llWriteDelay);
395 // Save off the PID if this is not a paging IO
399 ( pFcb->Specific.File.ExtentRequestProcessId == 0 ||
400 ( PsGetCurrentProcessId() != AFSSysProcess &&
401 pFcb->Specific.File.ExtentRequestProcessId != (ULONGLONG)PsGetCurrentProcessId())))
404 pFcb->Specific.File.ExtentRequestProcessId = (ULONGLONG)PsGetCurrentProcessId();
406 if( pFcb->Specific.File.ExtentRequestProcessId == (ULONGLONG)AFSSysProcess)
408 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
409 AFS_TRACE_LEVEL_WARNING,
410 "%s Setting LastWriterExtentProcessId to system process for Fcb %p\n",
415 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
419 // We should be ready to go. So first of all ask for the extents
420 // Provoke a get of the extents - if we need to.
424 if( !bPagingIo && !bNonCachedIo)
427 ntStatus = AFSRequestExtentsAsync( pFcb, &liStartingByte, ulByteCount);
429 if (!NT_SUCCESS(ntStatus))
432 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
433 AFS_TRACE_LEVEL_ERROR,
434 "AFSCommonWrite (%08lX) Failed to request extents Status %08lX\n",
438 try_return( ntStatus );
444 // If they are not mapped and we are the Lazy Writer then just
447 if (!bMapped && pFcb->Specific.File.LazyWriterThread == PsGetCurrentThread())
450 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
451 AFS_TRACE_LEVEL_VERBOSE,
452 "AFSCommonWrite (%08lX) Failing lazy writer for unmapped request\n",
455 try_return ( ntStatus = STATUS_FILE_LOCK_CONFLICT);
461 // - if Paging then we need to nothing (the precalls will
462 // have acquired the paging resource), for clarity we will collect
463 // the paging resource
464 // - If extending Write then take the fileresource EX (EOF will change, Allocation will only move out)
465 // - Otherwise we collect the file shared, check against extending and
476 bExtendingWrite = (((liStartingByte.QuadPart + ulByteCount) >=
477 pFcb->Header.FileSize.QuadPart) ||
478 (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
479 liStartingByte.HighPart == -1)) ;
485 //ASSERT( NULL != OnBehalfOf || ExIsResourceAcquiredLite( &pNPFcb->Resource ));
487 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
488 AFS_TRACE_LEVEL_VERBOSE,
489 "AFSCommonWrite Acquiring Fcb PagingIo lock %08lX SHARED %08lX\n",
490 &pNPFcb->PagingResource,
491 PsGetCurrentThread());
493 AFSAcquireShared( &pNPFcb->PagingResource,
496 bReleasePaging = TRUE;
499 // We have the correct lock - we cannot have the wrong one
503 else if( bExtendingWrite)
506 // Check for lock inversion
509 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
511 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
512 AFS_TRACE_LEVEL_VERBOSE,
513 "AFSCommonWrite Acquiring Fcb lock %08lX EXCL %08lX\n",
515 PsGetCurrentThread());
517 AFSAcquireExcl( &pNPFcb->Resource,
520 if (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
521 liStartingByte.HighPart == -1)
523 if (pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
525 liStartingByte = pFcb->Header.ValidDataLength;
529 liStartingByte = pFcb->Header.FileSize;
535 // We have the correct lock - even if we don't end up truncating
541 ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->PagingResource ));
543 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
544 AFS_TRACE_LEVEL_VERBOSE,
545 "AFSCommonWrite Acquiring Fcb lock %08lX SHARED %08lX\n",
547 PsGetCurrentThread());
549 AFSAcquireShared( &pNPFcb->Resource,
555 // Have things moved? Are we extending? If so, the the lock isn't OK
557 bLockOK = (liStartingByte.QuadPart + ulByteCount) < pFcb->Header.FileSize.QuadPart;
561 AFSReleaseResource( &pNPFcb->Resource);
562 bReleaseMain = FALSE;
569 // Check the BR locks on the file.
573 !FsRtlCheckLockForWriteAccess( &pFcb->Specific.File.FileLock,
577 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
578 AFS_TRACE_LEVEL_ERROR,
579 "AFSCommonWrite (%08lX) Request failed due to lock conflict\n",
582 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
588 ntStatus = AFSExtendingWrite( pFcb, pFileObject, (liStartingByte.QuadPart + ulByteCount));
590 if( !NT_SUCCESS(ntStatus))
593 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
594 AFS_TRACE_LEVEL_ERROR,
595 "AFSCommonWrite (%08lX) Failed extending write request Status %08lX\n",
599 try_return( ntStatus );
604 // Fire off the request as appropriate
606 bCompleteIrp = FALSE;
612 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
613 AFS_TRACE_LEVEL_VERBOSE,
614 "AFSCommonWrite (%08lX) Processing CACHED request Offset %I64X Len %08lX\n",
616 liStartingByte.QuadPart,
619 ntStatus = AFSCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount, bForceFlush);
625 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
626 AFS_TRACE_LEVEL_VERBOSE,
627 "AFSCommonWrite (%08lX) Processing NON-CACHED request Offset %I64X Len %08lX\n",
629 liStartingByte.QuadPart,
632 ntStatus = AFSNonCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount);
637 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
638 AFS_TRACE_LEVEL_VERBOSE,
639 "AFSCommonWrite (%08lX) Process complete Status %08lX\n",
643 ObDereferenceObject(pFileObject);
648 AFSReleaseResource( &pNPFcb->Resource);
654 AFSReleaseResource( &pNPFcb->PagingResource);
660 AFSCompleteRequest( Irp,
669 AFSIOCtlWrite( IN PDEVICE_OBJECT DeviceObject,
673 NTSTATUS ntStatus = STATUS_SUCCESS;
674 AFSPIOCtlIORequestCB stIORequestCB;
675 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
678 AFSPIOCtlIOResultCB stIOResultCB;
679 ULONG ulBytesReturned = 0;
680 AFSFileID stParentFID;
685 RtlZeroMemory( &stIORequestCB,
686 sizeof( AFSPIOCtlIORequestCB));
688 if( pIrpSp->Parameters.Write.Length == 0)
692 // Nothing to do in this case
695 try_return( ntStatus);
698 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
700 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
702 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
703 AFS_TRACE_LEVEL_VERBOSE,
704 "AFSIOCtlWrite Acquiring Fcb lock %08lX SHARED %08lX\n",
705 &pFcb->NPFcb->Resource,
706 PsGetCurrentThread());
708 AFSAcquireShared( &pFcb->NPFcb->Resource,
712 // Get the parent fid to pass to the cm
715 RtlZeroMemory( &stParentFID,
718 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
722 // The parent directory FID of the node
725 stParentFID = pFcb->ObjectInformation->ParentObjectInformation->FileId;
729 // Set the control block up
732 stIORequestCB.RequestId = pCcb->RequestID;
734 if( pFcb->ObjectInformation->VolumeCB != NULL)
736 stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
740 // Lock down the buffer
743 stIORequestCB.MappedBuffer = AFSMapToService( Irp,
744 pIrpSp->Parameters.Write.Length);
746 if( stIORequestCB.MappedBuffer == NULL)
749 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
752 stIORequestCB.BufferLength = pIrpSp->Parameters.Write.Length;
754 stIOResultCB.BytesProcessed = 0;
756 ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
759 // Issue the request to the service
762 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_WRITE,
763 AFS_REQUEST_FLAG_SYNCHRONOUS,
767 (void *)&stIORequestCB,
768 sizeof( AFSPIOCtlIORequestCB),
772 if( !NT_SUCCESS( ntStatus))
775 try_return( ntStatus);
779 // Update the length written
782 Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
786 if( stIORequestCB.MappedBuffer != NULL)
789 AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
796 AFSReleaseResource( &pFcb->NPFcb->Resource);
804 // This function is called when we know we have to read from the AFS Cache.
806 // It ensures that we have exents for the entirety of the write and
807 // then pins the extents into memory (meaning that although we may
808 // add we will not remove). Then it creates a scatter gather write
809 // and fires off the IRPs
813 AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject,
815 IN LARGE_INTEGER StartingByte,
818 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
819 VOID *pSystemBuffer = NULL;
820 BOOLEAN bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
821 BOOLEAN bLocked = FALSE;
822 BOOLEAN bCompleteIrp = TRUE;
823 BOOLEAN bExtentsMapped = FALSE;
824 AFSGatherIo *pGatherIo = NULL;
825 AFSIoRun *pIoRuns = NULL;
826 AFSIoRun stIoRuns[AFS_MAX_STACK_IO_RUNS];
827 ULONG extentsCount = 0, runCount = 0;
828 AFSExtent *pStartExtent = NULL;
829 AFSExtent *pIgnoreExtent = NULL;
830 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
831 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
832 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
833 AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
834 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
835 AFSDeviceExt *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
836 ULONG ulRequestCount = 0;
837 LARGE_INTEGER liCurrentTime, liLastRequestTime;
838 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
839 PFILE_OBJECT pCacheFileObject = NULL;
843 Irp->IoStatus.Information = 0;
845 if (ByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
848 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
849 AFS_TRACE_LEVEL_ERROR,
850 "AFSNonCachedWrite (%08lX) Request %08lX Actual %08lX larger than MaxIO %I64X\n",
853 pIrpSp->Parameters.Write.Length,
854 pDevExt->Specific.RDR.MaxIo.QuadPart);
856 try_return( ntStatus = STATUS_UNSUCCESSFUL);
860 // Get the mapping for the buffer
862 pSystemBuffer = AFSLockSystemBuffer( Irp,
865 if( pSystemBuffer == NULL)
868 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
869 AFS_TRACE_LEVEL_ERROR,
870 "AFSNonCachedWrite (%08lX) Failed to map system buffer\n",
873 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
878 // Provoke a get of the extents - if we need to.
881 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
882 AFS_TRACE_LEVEL_VERBOSE,
883 "AFSNonCachedWrite Requesting extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
884 pFcb->ObjectInformation->FileId.Cell,
885 pFcb->ObjectInformation->FileId.Volume,
886 pFcb->ObjectInformation->FileId.Vnode,
887 pFcb->ObjectInformation->FileId.Unique,
888 StartingByte.QuadPart,
891 ntStatus = AFSRequestExtentsAsync( pFcb,
895 if (!NT_SUCCESS(ntStatus))
898 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
899 AFS_TRACE_LEVEL_ERROR,
900 "AFSNonCachedWrite (%08lX) Failed to request extents Status %08lX\n",
904 try_return( ntStatus);
907 KeQueryTickCount( &liLastRequestTime);
912 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
913 AFS_TRACE_LEVEL_VERBOSE,
914 "AFSNonCachedWrite Acquiring Fcb extents lock %08lX SHARED %08lX\n",
915 &pFcb->NPFcb->Specific.File.ExtentsResource,
916 PsGetCurrentThread());
918 ASSERT( !ExIsResourceAcquiredLite( &pFcb->NPFcb->Specific.File.ExtentsResource ));
920 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource, TRUE );
924 pIgnoreExtent = NULL;
926 if ( AFSDoExtentsMapRegion( pFcb, &StartingByte, ByteCount, &pStartExtent, &pIgnoreExtent ))
931 KeClearEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete );
933 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
934 AFS_TRACE_LEVEL_VERBOSE,
935 "AFSNonCachedWrite Releasing(1) Fcb extents lock %08lX SHARED %08lX\n",
936 &pFcb->NPFcb->Specific.File.ExtentsResource,
937 PsGetCurrentThread());
939 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
943 // We will re-request the extents after 10 seconds of waiting for them
946 KeQueryTickCount( &liCurrentTime);
948 if( liCurrentTime.QuadPart - liLastRequestTime.QuadPart >= pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart)
951 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
952 AFS_TRACE_LEVEL_VERBOSE,
953 "AFSNonCachedWrite Requesting extents, again, for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
954 pFcb->ObjectInformation->FileId.Cell,
955 pFcb->ObjectInformation->FileId.Volume,
956 pFcb->ObjectInformation->FileId.Vnode,
957 pFcb->ObjectInformation->FileId.Unique,
958 StartingByte.QuadPart,
961 ntStatus = AFSRequestExtentsAsync( pFcb,
965 if (!NT_SUCCESS(ntStatus))
968 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
969 AFS_TRACE_LEVEL_ERROR,
970 "AFSNonCachedWrite (%08lX) Failed to request extents Status %08lX\n",
974 try_return( ntStatus);
977 KeQueryTickCount( &liLastRequestTime);
981 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
982 AFS_TRACE_LEVEL_VERBOSE,
983 "AFSNonCachedWrite Waiting for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
984 pFcb->ObjectInformation->FileId.Cell,
985 pFcb->ObjectInformation->FileId.Volume,
986 pFcb->ObjectInformation->FileId.Vnode,
987 pFcb->ObjectInformation->FileId.Unique,
988 StartingByte.QuadPart,
995 ntStatus = AFSWaitForExtentMapping ( pFcb );
997 if (!NT_SUCCESS(ntStatus))
1000 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1001 AFS_TRACE_LEVEL_ERROR,
1002 "AFSNonCachedWrite Failed wait for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
1003 pFcb->ObjectInformation->FileId.Cell,
1004 pFcb->ObjectInformation->FileId.Volume,
1005 pFcb->ObjectInformation->FileId.Vnode,
1006 pFcb->ObjectInformation->FileId.Unique,
1007 StartingByte.QuadPart,
1011 try_return( ntStatus);
1016 // As per the read path -
1019 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1020 AFS_TRACE_LEVEL_VERBOSE,
1021 "AFSNonCachedWrite Extents located for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
1022 pFcb->ObjectInformation->FileId.Cell,
1023 pFcb->ObjectInformation->FileId.Volume,
1024 pFcb->ObjectInformation->FileId.Vnode,
1025 pFcb->ObjectInformation->FileId.Unique,
1026 StartingByte.QuadPart,
1029 ntStatus = AFSGetExtents( pFcb,
1036 if (!NT_SUCCESS(ntStatus))
1039 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1040 AFS_TRACE_LEVEL_ERROR,
1041 "AFSNonCachedWrite (%08lX) Failed to retrieve mapped extents Status %08lX\n",
1045 try_return( ntStatus );
1048 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1049 AFS_TRACE_LEVEL_VERBOSE,
1050 "AFSNonCachedWrite (%08lX) Successfully retrieved map extents count %08lX run count %08lX\n",
1055 if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
1058 Irp->IoStatus.Information = ByteCount;
1062 // Setup the MD5 for each extent
1065 AFSSetupMD5Hash( pFcb,
1073 ntStatus = AFSProcessExtentRun( pSystemBuffer,
1079 if (!NT_SUCCESS(ntStatus))
1082 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1083 AFS_TRACE_LEVEL_ERROR,
1084 "AFSNonCachedWrite (%08lX) Failed to process extent run for non-persistent cache Status %08lX\n",
1089 try_return( ntStatus);
1093 // Retrieve the cache file object
1096 pCacheFileObject = AFSReferenceCacheFileObject();
1098 if( pCacheFileObject == NULL)
1101 ntStatus = STATUS_DEVICE_NOT_READY;
1103 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
1104 AFS_TRACE_LEVEL_ERROR,
1105 "AFSNonCachedWrite Failed to retrieve cache fileobject for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %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,
1114 try_return( ntStatus);
1117 if (runCount > AFS_MAX_STACK_IO_RUNS)
1120 pIoRuns = (AFSIoRun*) AFSExAllocatePoolWithTag( PagedPool,
1121 runCount * sizeof( AFSIoRun ),
1123 if (NULL == pIoRuns)
1126 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1127 AFS_TRACE_LEVEL_ERROR,
1128 "AFSNonCachedWrite (%08lX) Failed to allocate IO run block\n",
1131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1140 RtlZeroMemory( pIoRuns, runCount * sizeof( AFSIoRun ));
1142 ntStatus = AFSSetupIoRun( IoGetRelatedDeviceObject( pCacheFileObject),
1151 if (!NT_SUCCESS(ntStatus))
1154 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1155 AFS_TRACE_LEVEL_ERROR,
1156 "AFSNonCachedWrite (%08lX) Failed to initialize IO run block Status %08lX\n",
1160 try_return( ntStatus );
1163 AFSReferenceActiveExtents( pStartExtent,
1166 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1167 AFS_TRACE_LEVEL_VERBOSE,
1168 "AFSNonCachedWrite Releasing(2) Fcb extents lock %08lX SHARED %08lX\n",
1169 &pFcb->NPFcb->Specific.File.ExtentsResource,
1170 PsGetCurrentThread());
1172 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1175 pGatherIo = (AFSGatherIo*) AFSExAllocatePoolWithTag( NonPagedPool,
1176 sizeof( AFSGatherIo),
1179 if (NULL == pGatherIo)
1182 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1183 AFS_TRACE_LEVEL_ERROR,
1184 "AFSNonCachedWrite (%08lX) Failed to allocate IO gather block\n",
1187 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1188 AFS_TRACE_LEVEL_VERBOSE,
1189 "AFSNonCachedWrite Acquiring(1) Fcb extents lock %08lX SHARED %08lX\n",
1190 &pFcb->NPFcb->Specific.File.ExtentsResource,
1191 PsGetCurrentThread());
1193 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1197 AFSDereferenceActiveExtents( pStartExtent,
1200 try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
1203 RtlZeroMemory( pGatherIo, sizeof( AFSGatherIo ));
1206 // Initialize count to 1, that was we won't get an early
1207 // completion if the first irp completes before the second is
1210 pGatherIo->Count = 1;
1211 pGatherIo->Status = STATUS_SUCCESS;
1212 pGatherIo->MasterIrp = Irp;
1213 pGatherIo->Synchronous = TRUE;
1214 pGatherIo->CompleteMasterIrp = FALSE;
1216 bCompleteIrp = TRUE;
1218 if( pGatherIo->Synchronous)
1220 KeInitializeEvent( &pGatherIo->Event, NotificationEvent, FALSE );
1225 // Setup the MD5 for each extent
1228 AFSSetupMD5Hash( pFcb,
1237 // Pre-emptively set up the count
1240 Irp->IoStatus.Information = ByteCount;
1242 ntStatus = AFSQueueStartIos( pCacheFileObject,
1244 IRP_WRITE_OPERATION | IRP_SYNCHRONOUS_API,
1249 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1250 AFS_TRACE_LEVEL_VERBOSE,
1251 "AFSNonCachedWrite (%08lX) AFSStartIos completed Status %08lX\n",
1255 if( !NT_SUCCESS( ntStatus))
1258 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1259 AFS_TRACE_LEVEL_VERBOSE,
1260 "AFSNonCachedWrite Acquiring(2) Fcb extents lock %08lX SHARED %08lX\n",
1261 &pFcb->NPFcb->Specific.File.ExtentsResource,
1262 PsGetCurrentThread());
1264 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1268 AFSDereferenceActiveExtents( pStartExtent,
1271 try_return( ntStatus);
1275 // Wait for completion of All IOs we started.
1278 ntStatus = KeWaitForSingleObject( &pGatherIo->Event,
1284 if( NT_SUCCESS( ntStatus))
1287 ntStatus = pGatherIo->Status;
1290 if( !NT_SUCCESS( ntStatus))
1293 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1294 AFS_TRACE_LEVEL_VERBOSE,
1295 "AFSNonCachedWrite Acquiring(3) Fcb extents lock %08lX SHARED %08lX\n",
1296 &pFcb->NPFcb->Specific.File.ExtentsResource,
1297 PsGetCurrentThread());
1299 AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
1303 AFSDereferenceActiveExtents( pStartExtent,
1306 try_return( ntStatus);
1310 // Since this is dirty we can mark the extents dirty now.
1311 // AFSMarkDirty will dereference the extents. Do not call
1312 // AFSDereferenceActiveExtents() in this code path.
1323 // This was an uncached user write - tell the server to do
1324 // the flush when the worker thread next wakes up
1326 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1335 if( pCacheFileObject != NULL)
1337 AFSReleaseCacheFileObject( pCacheFileObject);
1340 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1341 AFS_TRACE_LEVEL_VERBOSE,
1342 "AFSNonCachedWrite (%08lX) Completed request Status %08lX\n",
1346 if (NT_SUCCESS(ntStatus) &&
1351 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1357 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1358 AFS_TRACE_LEVEL_VERBOSE,
1359 "AFSNonCachedWrite Releasing Fcb extents lock %08lX SHARED %08lX\n",
1360 &pFcb->NPFcb->Specific.File.ExtentsResource,
1361 PsGetCurrentThread());
1363 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
1368 AFSExFreePool(pGatherIo);
1371 if( NULL != pIoRuns &&
1372 stIoRuns != pIoRuns)
1374 AFSExFreePool(pIoRuns);
1380 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1381 AFS_TRACE_LEVEL_VERBOSE,
1382 "AFSNonCachedWrite Completing Irp %08lX Status %08lX Info %08lX\n",
1385 Irp->IoStatus.Information);
1387 AFSCompleteRequest( Irp, ntStatus);
1396 AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
1398 IN LARGE_INTEGER StartingByte,
1400 IN BOOLEAN ForceFlush)
1402 PVOID pSystemBuffer = NULL;
1403 NTSTATUS ntStatus = STATUS_SUCCESS;
1404 IO_STATUS_BLOCK iosbFlush;
1405 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1406 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
1407 AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
1408 AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
1409 BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
1410 BOOLEAN bMapped = FALSE;
1411 ULONG ulCurrentIO = 0, ulTotalLen = ByteCount;
1412 PMDL pCurrentMdl = Irp->MdlAddress;
1413 LARGE_INTEGER liCurrentOffset;
1418 Irp->IoStatus.Information = 0;
1420 if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1426 CcPrepareMdlWrite( pFileObject,
1432 ntStatus = Irp->IoStatus.Status;
1434 __except( EXCEPTION_EXECUTE_HANDLER)
1436 ntStatus = GetExceptionCode();
1438 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1439 AFS_TRACE_LEVEL_ERROR,
1440 "AFSCachedWrite (%08lX) Exception thrown while preparing mdl write Status %08lX\n",
1445 if( !NT_SUCCESS( ntStatus))
1449 // Free up any potentially allocated mdl's
1452 CcMdlWriteComplete( pFileObject,
1456 Irp->MdlAddress = NULL;
1458 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1459 AFS_TRACE_LEVEL_ERROR,
1460 "AFSCachedWrite (%08lX) Failed to process MDL write Status %08lX\n",
1465 try_return( ntStatus);
1468 liCurrentOffset.QuadPart = StartingByte.QuadPart;
1470 while( ulTotalLen > 0)
1473 ntStatus = STATUS_SUCCESS;
1475 if( pCurrentMdl != NULL)
1478 pSystemBuffer = MmGetSystemAddressForMdlSafe( pCurrentMdl,
1479 NormalPagePriority);
1481 ulCurrentIO = MmGetMdlByteCount( pCurrentMdl);
1483 if( ulCurrentIO > ulTotalLen)
1485 ulCurrentIO = ulTotalLen;
1491 pSystemBuffer = AFSLockSystemBuffer( Irp,
1494 ulCurrentIO = ulTotalLen;
1497 if( pSystemBuffer == NULL)
1500 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1501 AFS_TRACE_LEVEL_ERROR,
1502 "AFSCachedWrite (%08lX) Failed to lock system buffer\n",
1505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1511 if( !CcCopyWrite( pFileObject,
1518 // Failed to process request.
1521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1522 AFS_TRACE_LEVEL_ERROR,
1523 "AFSCachedWrite (%08lX) Failed to issue CcCopyWrite %wZ @ %0I64X Status %08lX\n",
1525 &pFileObject->FileName,
1526 liCurrentOffset.QuadPart,
1527 Irp->IoStatus.Status);
1529 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1532 __except( EXCEPTION_EXECUTE_HANDLER)
1535 ntStatus = GetExceptionCode();
1537 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1538 AFS_TRACE_LEVEL_ERROR,
1539 "AFSCachedWrite (%08lX) CcCopyWrite Threw exception %wZ @ %0I64X Status %08lX\n",
1541 &pFileObject->FileName,
1542 liCurrentOffset.QuadPart,
1546 if( !NT_SUCCESS( ntStatus))
1548 try_return( ntStatus);
1555 // We have detected a file we do a write through with.
1558 CcFlushCache(&pFcb->NPFcb->SectionObjectPointers,
1563 if( !NT_SUCCESS( iosbFlush.Status))
1566 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1567 AFS_TRACE_LEVEL_ERROR,
1568 "AFSCachedWrite (%08lX) CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1570 &pFileObject->FileName,
1571 pFcb->ObjectInformation->FileId.Cell,
1572 pFcb->ObjectInformation->FileId.Volume,
1573 pFcb->ObjectInformation->FileId.Vnode,
1574 pFcb->ObjectInformation->FileId.Unique,
1576 iosbFlush.Information);
1578 try_return( ntStatus = iosbFlush.Status);
1582 if( ulTotalLen <= ulCurrentIO)
1587 liCurrentOffset.QuadPart += ulCurrentIO;
1589 ulTotalLen -= ulCurrentIO;
1591 pCurrentMdl = pCurrentMdl->Next;
1596 if( NT_SUCCESS( ntStatus))
1599 Irp->IoStatus.Information = ByteCount;
1604 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
1608 // If this extended the Vdl, then update it accordingly
1611 if( StartingByte.QuadPart + ByteCount > pFcb->Header.ValidDataLength.QuadPart)
1614 pFcb->Header.ValidDataLength.QuadPart = StartingByte.QuadPart + ByteCount;
1617 if (BooleanFlagOn(pFileObject->Flags, (FO_NO_INTERMEDIATE_BUFFERING + FO_WRITE_THROUGH)))
1620 // Write through asked for... Set things so that we get
1621 // flush when the worker thread next wakes up
1623 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
1626 if( !BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
1629 SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME);
1631 KeQuerySystemTime( &pFcb->ObjectInformation->LastWriteTime);
1635 AFSCompleteRequest( Irp,
1644 AFSExtendingWrite( IN AFSFcb *Fcb,
1645 IN PFILE_OBJECT FileObject,
1646 IN LONGLONG NewLength)
1648 LARGE_INTEGER liSaveFileSize = Fcb->Header.FileSize;
1649 LARGE_INTEGER liSaveAllocation = Fcb->Header.AllocationSize;
1650 NTSTATUS ntStatus = STATUS_SUCCESS;
1651 AFSCcb *pCcb = (AFSCcb *)FileObject->FsContext2;
1653 if( NewLength > Fcb->Header.AllocationSize.QuadPart)
1656 Fcb->Header.AllocationSize.QuadPart = NewLength;
1658 Fcb->ObjectInformation->AllocationSize = Fcb->Header.AllocationSize;
1661 if( NewLength > Fcb->Header.FileSize.QuadPart)
1664 Fcb->Header.FileSize.QuadPart = NewLength;
1666 Fcb->ObjectInformation->EndOfFile = Fcb->Header.FileSize;
1673 ntStatus = AFSUpdateFileInformation( &Fcb->ObjectInformation->ParentObjectInformation->FileId,
1674 Fcb->ObjectInformation,
1677 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1678 AFS_TRACE_LEVEL_VERBOSE,
1679 "AFSExtendingWrite Acquiring Fcb lock %08lX EXCL %08lX\n",
1680 &Fcb->NPFcb->Resource,
1681 PsGetCurrentThread());
1683 if (NT_SUCCESS(ntStatus))
1686 KeQuerySystemTime( &Fcb->ObjectInformation->ChangeTime);
1688 SetFlag( Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1691 // If the file is currently cached, then let the MM know about the extension
1694 if( CcIsFileCached( FileObject))
1696 CcSetFileSizes( FileObject,
1697 (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
1702 Fcb->Header.FileSize = liSaveFileSize;
1703 Fcb->Header.AllocationSize = liSaveAllocation;
1707 // DownConvert file resource to shared
1709 ExConvertExclusiveToSharedLite( &Fcb->NPFcb->Resource);
1715 AFSShareWrite( IN PDEVICE_OBJECT DeviceObject,
1719 NTSTATUS ntStatus = STATUS_SUCCESS;
1720 AFSPIOCtlIORequestCB stIORequestCB;
1721 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1722 AFSFcb *pFcb = NULL;
1723 AFSCcb *pCcb = NULL;
1724 AFSPipeIORequestCB *pIoRequest = NULL;
1725 void *pBuffer = NULL;
1726 AFSPipeIOResultCB stIoResult;
1727 ULONG ulBytesReturned = 0;
1732 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1734 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1736 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1737 AFS_TRACE_LEVEL_VERBOSE,
1738 "AFSShareWrite On pipe %wZ Length %08lX\n",
1739 &pCcb->DirectoryCB->NameInformation.FileName,
1740 pIrpSp->Parameters.Write.Length);
1742 if( pIrpSp->Parameters.Write.Length == 0)
1746 // Nothing to do in this case
1749 try_return( ntStatus);
1753 // Retrieve the buffer for the read request
1756 pBuffer = AFSLockSystemBuffer( Irp,
1757 pIrpSp->Parameters.Write.Length);
1759 if( pBuffer == NULL)
1762 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1763 AFS_TRACE_LEVEL_ERROR,
1764 "AFSShareWrite Failed to map buffer on pipe %wZ\n",
1765 &pCcb->DirectoryCB->NameInformation.FileName);
1767 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1770 AFSAcquireShared( &pFcb->NPFcb->Resource,
1773 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1774 sizeof( AFSPipeIORequestCB) +
1775 pIrpSp->Parameters.Write.Length,
1776 AFS_GENERIC_MEMORY_14_TAG);
1778 if( pIoRequest == NULL)
1781 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1784 RtlZeroMemory( pIoRequest,
1785 sizeof( AFSPipeIORequestCB) + pIrpSp->Parameters.Write.Length);
1787 pIoRequest->RequestId = pCcb->RequestID;
1789 pIoRequest->RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1791 pIoRequest->BufferLength = pIrpSp->Parameters.Write.Length;
1793 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1795 pIrpSp->Parameters.Write.Length);
1797 stIoResult.BytesProcessed = 0;
1799 ulBytesReturned = sizeof( AFSPipeIOResultCB);
1802 // Issue the open request to the service
1805 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_WRITE,
1806 AFS_REQUEST_FLAG_SYNCHRONOUS,
1808 &pCcb->DirectoryCB->NameInformation.FileName,
1811 sizeof( AFSPipeIORequestCB) +
1812 pIrpSp->Parameters.Write.Length,
1816 if( !NT_SUCCESS( ntStatus))
1819 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1820 AFS_TRACE_LEVEL_ERROR,
1821 "AFSShareWrite (%08lX) Failed service write Status %08lX\n",
1825 try_return( ntStatus);
1828 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1829 AFS_TRACE_LEVEL_VERBOSE,
1830 "AFSShareWrite Completed on pipe %wZ Length read %08lX\n",
1831 &pCcb->DirectoryCB->NameInformation.FileName,
1832 stIoResult.BytesProcessed);
1834 Irp->IoStatus.Information = stIoResult.BytesProcessed;
1841 AFSReleaseResource( &pFcb->NPFcb->Resource);
1844 if( pIoRequest != NULL)
1847 AFSExFreePool( pIoRequest);