Windows: Call CcDeferWrite rather than loop
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSRead.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
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
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
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.
21  *
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.
33  */
34
35 //
36 // File: AFSRead.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 static
42 NTSTATUS
43 AFSCachedRead( IN PDEVICE_OBJECT DeviceObject,
44                IN PIRP Irp,
45                IN LARGE_INTEGER StartingByte,
46                IN ULONG ByteCount)
47 {
48     UNREFERENCED_PARAMETER(DeviceObject);
49     NTSTATUS           ntStatus = STATUS_SUCCESS;
50     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
51     PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
52     BOOLEAN            bSynchronousIo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
53     VOID              *pSystemBuffer = NULL;
54     ULONG              ulCurrentIO = 0, ulTotalLen = ByteCount;
55     PMDL               pCurrentMdl = Irp->MdlAddress;
56     LARGE_INTEGER      liCurrentOffset;
57
58     __Enter
59     {
60
61         Irp->IoStatus.Information = 0;
62
63         liCurrentOffset.QuadPart = StartingByte.QuadPart;
64
65         while( ulTotalLen > 0)
66         {
67
68             ntStatus = STATUS_SUCCESS;
69
70             if( pCurrentMdl != NULL)
71             {
72
73                 ASSERT( pCurrentMdl != NULL);
74
75                 pSystemBuffer = MmGetSystemAddressForMdlSafe( pCurrentMdl,
76                                                               NormalPagePriority);
77
78                 ulCurrentIO = MmGetMdlByteCount( pCurrentMdl);
79
80                 if( ulCurrentIO > ulTotalLen)
81                 {
82                     ulCurrentIO = ulTotalLen;
83                 }
84             }
85             else
86             {
87
88                 pSystemBuffer = AFSLockSystemBuffer( Irp,
89                                                      ulTotalLen);
90
91                 ulCurrentIO = ulTotalLen;
92             }
93
94             if( pSystemBuffer == NULL)
95             {
96
97                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
98                               AFS_TRACE_LEVEL_ERROR,
99                               "AFSCachedRead (%p) Failed to lock system buffer\n",
100                               Irp);
101
102                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
103             }
104
105             __try
106             {
107
108                 if( !CcCopyRead( pFileObject,
109                                  &liCurrentOffset,
110                                  ulCurrentIO,
111                                  TRUE,
112                                  pSystemBuffer,
113                                  &Irp->IoStatus))
114                 {
115
116                     //
117                     // Failed to process request.
118                     //
119
120                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
121                                   AFS_TRACE_LEVEL_ERROR,
122                                   "AFSCachedRead (%p) Failed CcCopyRead() %wZ @ %0I64X Status %08lX\n",
123                                   Irp,
124                                   &pFileObject->FileName,
125                                   liCurrentOffset.QuadPart,
126                                   Irp->IoStatus.Status);
127
128                     try_return( ntStatus = Irp->IoStatus.Status);
129                 }
130             }
131             __except( EXCEPTION_EXECUTE_HANDLER)
132             {
133                 ntStatus = GetExceptionCode();
134
135                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
136                               AFS_TRACE_LEVEL_ERROR,
137                               "AFSCachedRead (%p) CcCopyRead() Threw exception %wZ @ %0I64X Status %08lX\n",
138                               Irp,
139                               &pFileObject->FileName,
140                               liCurrentOffset.QuadPart,
141                               ntStatus);
142             }
143
144             if( !NT_SUCCESS( ntStatus))
145             {
146
147                 try_return( ntStatus);
148             }
149
150             if( ulTotalLen <= ulCurrentIO)
151             {
152                 break;
153             }
154
155             liCurrentOffset.QuadPart += ulCurrentIO;
156
157             ulTotalLen -= ulCurrentIO;
158
159             pCurrentMdl = pCurrentMdl->Next;
160         }
161
162 try_exit:
163
164         if( NT_SUCCESS( ntStatus))
165         {
166
167             Irp->IoStatus.Information = ByteCount;
168
169             //
170             // Update the CBO if this is a sync read
171             //
172
173             if( bSynchronousIo)
174             {
175
176                 pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
177             }
178         }
179
180         AFSCompleteRequest( Irp,
181                             ntStatus);
182     }
183
184     return ntStatus;
185 }
186
187 static
188 NTSTATUS
189 AFSNonCachedRead( IN PDEVICE_OBJECT DeviceObject,
190                   IN PIRP Irp,
191                   IN LARGE_INTEGER StartingByte)
192 {
193     NTSTATUS           ntStatus = STATUS_UNSUCCESSFUL;
194     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
195     PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
196     AFSFcb            *pFcb = (AFSFcb *)pFileObject->FsContext;
197     AFSCcb            *pCcb = (AFSCcb *)pFileObject->FsContext2;
198     VOID              *pSystemBuffer = NULL;
199     BOOLEAN            bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
200     BOOLEAN            bLocked = FALSE;
201     AFSGatherIo       *pGatherIo = NULL;
202     AFSIoRun          *pIoRuns = NULL;
203     AFSIoRun           stIoRuns[AFS_MAX_STACK_IO_RUNS];
204     ULONG              extentsCount = 0, runCount = 0;
205     AFSExtent         *pStartExtent = NULL;
206     AFSExtent         *pIgnoreExtent = NULL;
207     BOOLEAN            bCompleteIrp = TRUE;
208     ULONG              ulReadByteCount;
209     ULONG              ulByteCount;
210     AFSDeviceExt      *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
211     LARGE_INTEGER      liCurrentTime, liLastRequestTime;
212     AFSDeviceExt      *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
213     PFILE_OBJECT       pCacheFileObject = NULL;
214
215     __Enter
216     {
217
218         ulByteCount = pIrpSp->Parameters.Read.Length;
219
220         if (ulByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
221         {
222
223             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
224                           AFS_TRACE_LEVEL_ERROR,
225                           "AFSNonCachedRead (%p) Request larger than MaxIO %I64X\n",
226                           Irp,
227                           pDevExt->Specific.RDR.MaxIo.QuadPart);
228
229             try_return( ntStatus = STATUS_UNSUCCESSFUL);
230         }
231
232         pSystemBuffer = AFSLockSystemBuffer( Irp,
233                                              ulByteCount);
234
235         if( pSystemBuffer == NULL)
236         {
237
238             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
239                           AFS_TRACE_LEVEL_ERROR,
240                           "AFSNonCachedRead (%p) Failed to map system buffer\n",
241                           Irp);
242
243             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
244         }
245
246         if( StartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
247         {
248             ULONG zeroCount = (ULONG) (StartingByte.QuadPart + ulByteCount - pFcb->Header.FileSize.QuadPart);
249             ulReadByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - StartingByte.QuadPart);
250
251             //
252             // Clear up to EOF
253             //
254
255             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
256                           AFS_TRACE_LEVEL_VERBOSE,
257                           "AFSNonCachedRead (%p) Zeroing to EOF zero byte length %08lX\n",
258                           Irp,
259                           zeroCount);
260
261             RtlZeroMemory( ((PCHAR)pSystemBuffer) + ulReadByteCount, zeroCount);
262         }
263         else
264         {
265             ulReadByteCount = ulByteCount;
266         }
267
268         //
269         // Provoke a get of the extents - if we need to.
270         //
271
272         pStartExtent = NULL;
273
274         AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
275                       AFS_TRACE_LEVEL_VERBOSE,
276                       "AFSNonCachedRead Requesting extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
277                       pFcb->ObjectInformation->FileId.Cell,
278                       pFcb->ObjectInformation->FileId.Volume,
279                       pFcb->ObjectInformation->FileId.Vnode,
280                       pFcb->ObjectInformation->FileId.Unique,
281                       StartingByte.QuadPart,
282                       ulReadByteCount);
283
284         ntStatus = AFSRequestExtentsAsync( pFcb,
285                                            pCcb,
286                                            &StartingByte,
287                                            ulReadByteCount);
288
289         if (!NT_SUCCESS(ntStatus))
290         {
291
292             AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
293                           AFS_TRACE_LEVEL_ERROR,
294                           "AFSNonCachedRead (%p) Failed to request extents Status %08lX\n",
295                           Irp,
296                           ntStatus);
297
298             try_return( ntStatus);
299         }
300
301         KeQueryTickCount( &liLastRequestTime);
302
303         while (TRUE)
304         {
305
306             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
307                           AFS_TRACE_LEVEL_VERBOSE,
308                           "AFSNonCachedRead Acquiring Fcb extents lock %p SHARED %08lX\n",
309                           &pFcb->NPFcb->Specific.File.ExtentsResource,
310                           PsGetCurrentThread());
311
312             AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource, TRUE );
313             bLocked = TRUE;
314
315             pStartExtent = NULL;
316             pIgnoreExtent = NULL;
317
318             if( AFSDoExtentsMapRegion( pFcb,
319                                        &StartingByte,
320                                        ulReadByteCount,
321                                        &pStartExtent,
322                                        &pIgnoreExtent ))
323             {
324                 break;
325             }
326
327             KeClearEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete);
328
329             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
330                           AFS_TRACE_LEVEL_VERBOSE,
331                           "AFSNonCachedRead Releasing Fcb extents lock %p SHARED %08lX\n",
332                           &pFcb->NPFcb->Specific.File.ExtentsResource,
333                           PsGetCurrentThread());
334
335             AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
336             bLocked= FALSE;
337
338             //
339             // We will re-request the extents after 10 seconds of waiting for them
340             //
341
342             KeQueryTickCount( &liCurrentTime);
343
344             if( liCurrentTime.QuadPart - liLastRequestTime.QuadPart >= pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart)
345             {
346
347                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
348                               AFS_TRACE_LEVEL_VERBOSE,
349                               "AFSNonCachedRead Requesting extents, again, for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
350                               pFcb->ObjectInformation->FileId.Cell,
351                               pFcb->ObjectInformation->FileId.Volume,
352                               pFcb->ObjectInformation->FileId.Vnode,
353                               pFcb->ObjectInformation->FileId.Unique,
354                               StartingByte.QuadPart,
355                               ulReadByteCount);
356
357                 ntStatus = AFSRequestExtentsAsync( pFcb,
358                                                    pCcb,
359                                                    &StartingByte,
360                                                    ulReadByteCount);
361
362                 if (!NT_SUCCESS(ntStatus))
363                 {
364
365                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
366                                   AFS_TRACE_LEVEL_ERROR,
367                                   "AFSNonCachedRead (%p) Failed to request extents Status %08lX\n",
368                                   Irp,
369                                   ntStatus);
370
371                     try_return( ntStatus);
372                 }
373
374                 KeQueryTickCount( &liLastRequestTime);
375             }
376
377             AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
378                           AFS_TRACE_LEVEL_VERBOSE,
379                           "AFSNonCachedRead Waiting for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
380                           pFcb->ObjectInformation->FileId.Cell,
381                           pFcb->ObjectInformation->FileId.Volume,
382                           pFcb->ObjectInformation->FileId.Vnode,
383                           pFcb->ObjectInformation->FileId.Unique,
384                           StartingByte.QuadPart,
385                           ulReadByteCount);
386
387             ntStatus =  AFSWaitForExtentMapping ( pFcb, pCcb);
388
389             if (!NT_SUCCESS(ntStatus))
390             {
391
392                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
393                               AFS_TRACE_LEVEL_ERROR,
394                               "AFSNonCachedRead Failed wait for extents for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
395                               pFcb->ObjectInformation->FileId.Cell,
396                               pFcb->ObjectInformation->FileId.Volume,
397                               pFcb->ObjectInformation->FileId.Vnode,
398                               pFcb->ObjectInformation->FileId.Unique,
399                               StartingByte.QuadPart,
400                               ulReadByteCount,
401                               ntStatus);
402
403                 try_return( ntStatus);
404             }
405         }
406
407         //
408         // At this stage we know that the extents are fully mapped and
409         // that, because we took a reference they won't be unmapped.
410         // Thus the list will not move between the start and end.
411         //
412
413         AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
414                       AFS_TRACE_LEVEL_VERBOSE,
415                       "AFSNonCachedRead Extents mapped for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX\n",
416                       pFcb->ObjectInformation->FileId.Cell,
417                       pFcb->ObjectInformation->FileId.Volume,
418                       pFcb->ObjectInformation->FileId.Vnode,
419                       pFcb->ObjectInformation->FileId.Unique,
420                       StartingByte.QuadPart,
421                       ulReadByteCount);
422
423         ntStatus = AFSGetExtents( pFcb,
424                                   &StartingByte,
425                                   ulReadByteCount,
426                                   pStartExtent,
427                                   &extentsCount,
428                                   &runCount);
429
430         if (!NT_SUCCESS(ntStatus))
431         {
432
433             AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
434                           AFS_TRACE_LEVEL_ERROR,
435                           "AFSNonCachedRead (%p) Failed to retrieve mapped extents Status %08lX\n",
436                           Irp,
437                           ntStatus);
438
439             try_return( ntStatus );
440         }
441
442         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
443                       AFS_TRACE_LEVEL_VERBOSE,
444                       "AFSNonCachedRead (%p) Successfully retrieved map extents count %d run count %d\n",
445                       Irp,
446                       extentsCount,
447                       runCount);
448
449         if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
450         {
451
452             Irp->IoStatus.Information = ulReadByteCount;
453
454             ntStatus = AFSProcessExtentRun( pSystemBuffer,
455                                             &StartingByte,
456                                             ulReadByteCount,
457                                             pStartExtent,
458                                             FALSE);
459
460             if (!NT_SUCCESS(ntStatus))
461             {
462
463                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
464                               AFS_TRACE_LEVEL_ERROR,
465                               "AFSNonCachedRead (%p) Failed to process extent run for non-persistent cache Status %08lX\n",
466                               Irp,
467                               ntStatus);
468             }
469
470             try_return( ntStatus);
471         }
472
473         //
474         // Retrieve the cache file object
475         //
476
477         pCacheFileObject = AFSReferenceCacheFileObject();
478
479         if( pCacheFileObject == NULL)
480         {
481
482             ntStatus = STATUS_DEVICE_NOT_READY;
483
484             AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
485                           AFS_TRACE_LEVEL_ERROR,
486                           "AFSNonCachedRead Failed to retrieve cache fileobject for fid %08lX-%08lX-%08lX-%08lX Offset %I64X Length %08lX Status %08lX\n",
487                           pFcb->ObjectInformation->FileId.Cell,
488                           pFcb->ObjectInformation->FileId.Volume,
489                           pFcb->ObjectInformation->FileId.Vnode,
490                           pFcb->ObjectInformation->FileId.Unique,
491                           StartingByte.QuadPart,
492                           ulReadByteCount,
493                           ntStatus);
494
495             try_return( ntStatus);
496         }
497
498         if (runCount > AFS_MAX_STACK_IO_RUNS)
499         {
500
501             pIoRuns = (AFSIoRun*) AFSExAllocatePoolWithTag( PagedPool,
502                                                             runCount * sizeof( AFSIoRun ),
503                                                             AFS_IO_RUN_TAG );
504             if (NULL == pIoRuns)
505             {
506
507                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
508                               AFS_TRACE_LEVEL_ERROR,
509                               "AFSNonCachedRead (%p) Failed to allocate IO run block\n",
510                               Irp);
511
512                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
513             }
514         }
515         else
516         {
517
518             pIoRuns = stIoRuns;
519         }
520
521         RtlZeroMemory( pIoRuns, runCount * sizeof( AFSIoRun ));
522
523         ntStatus = AFSSetupIoRun( IoGetRelatedDeviceObject( pCacheFileObject),
524                                   Irp,
525                                   pSystemBuffer,
526                                   pIoRuns,
527                                   &StartingByte,
528                                   ulReadByteCount,
529                                   pStartExtent,
530                                   &runCount );
531
532         if (!NT_SUCCESS(ntStatus))
533         {
534
535             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
536                           AFS_TRACE_LEVEL_ERROR,
537                           "AFSNonCachedRead (%p) Failed to initialize IO run block Status %08lX\n",
538                           Irp,
539                           ntStatus);
540
541             try_return( ntStatus );
542         }
543
544         AFSReferenceActiveExtents( pStartExtent,
545                                    extentsCount);
546
547         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
548                       AFS_TRACE_LEVEL_VERBOSE,
549                       "AFSNonCachedRead Releasing Fcb extents lock %p SHARED %08lX\n",
550                       &pFcb->NPFcb->Specific.File.ExtentsResource,
551                       PsGetCurrentThread());
552
553         AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
554         bLocked = FALSE;
555
556         pGatherIo = (AFSGatherIo*) AFSExAllocatePoolWithTag( NonPagedPool,
557                                                              sizeof( AFSGatherIo ),
558                                                              AFS_GATHER_TAG );
559
560         if (NULL == pGatherIo)
561         {
562
563             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
564                           AFS_TRACE_LEVEL_ERROR,
565                           "AFSNonCachedRead (%p) Failed to allocate IO gather block\n",
566                           Irp);
567
568             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
569                           AFS_TRACE_LEVEL_VERBOSE,
570                           "AFSNonCachedRead Acquiring(2) Fcb extents lock %p SHARED %08lX\n",
571                           &pFcb->NPFcb->Specific.File.ExtentsResource,
572                           PsGetCurrentThread());
573
574             AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
575                               TRUE);
576             bLocked = TRUE;
577
578             AFSDereferenceActiveExtents( pStartExtent,
579                                          extentsCount);
580
581             try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
582         }
583
584         RtlZeroMemory( pGatherIo, sizeof( AFSGatherIo ));
585
586         //
587         // Initialize count to 1, that was we won't get an early
588         // completion if the first irp completes before the second is
589         // queued.
590         //
591         pGatherIo->Count = 1;
592         pGatherIo->Status = STATUS_SUCCESS;
593         pGatherIo->MasterIrp = Irp;
594         pGatherIo->Synchronous = TRUE;
595         pGatherIo->Fcb = pFcb;
596         pGatherIo->CompleteMasterIrp = FALSE;
597
598         bCompleteIrp = TRUE;
599
600         if (pGatherIo->Synchronous)
601         {
602             KeInitializeEvent( &pGatherIo->Event, NotificationEvent, FALSE );
603         }
604         else
605         {
606             IoMarkIrpPending( Irp);
607         }
608
609         //
610         // Pre-emptively set up the count
611         //
612
613         Irp->IoStatus.Information = ulByteCount;
614
615         ntStatus = AFSQueueStartIos( pCacheFileObject,
616                                      IRP_MJ_READ,
617                                      IRP_READ_OPERATION | IRP_SYNCHRONOUS_API,
618                                      pIoRuns,
619                                      runCount,
620                                      pGatherIo);
621
622         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
623                       AFS_TRACE_LEVEL_VERBOSE,
624                       "AFSNonCachedRead (%p) AFSStartIos completed Status %08lX\n",
625                       Irp,
626                       ntStatus);
627
628         if( !NT_SUCCESS( ntStatus))
629         {
630
631             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
632                           AFS_TRACE_LEVEL_VERBOSE,
633                           "AFSNonCachedRead Acquiring(3) Fcb extents lock %p SHARED %08lX\n",
634                           &pFcb->NPFcb->Specific.File.ExtentsResource,
635                           PsGetCurrentThread());
636
637             AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
638                               TRUE);
639             bLocked = TRUE;
640
641             AFSDereferenceActiveExtents( pStartExtent,
642                                          extentsCount);
643
644             try_return( ntStatus);
645         }
646
647         //
648         // Wait for completion of all IOs we started.
649         //
650         (VOID) KeWaitForSingleObject( &pGatherIo->Event,
651                                       Executive,
652                                       KernelMode,
653                                       FALSE,
654                                       NULL);
655
656         ntStatus = pGatherIo->Status;
657
658         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
659                       AFS_TRACE_LEVEL_VERBOSE,
660                       "AFSNonCachedRead (%p) AFSStartIos wait completed Status %08lX\n",
661                       Irp,
662                       ntStatus);
663
664         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
665                       AFS_TRACE_LEVEL_VERBOSE,
666                       "AFSNonCachedRead Acquiring(4) Fcb extents lock %p SHARED %08lX\n",
667                       &pFcb->NPFcb->Specific.File.ExtentsResource,
668                       PsGetCurrentThread());
669
670         AFSAcquireShared( &pFcb->NPFcb->Specific.File.ExtentsResource,
671                           TRUE);
672         bLocked = TRUE;
673
674         AFSDereferenceActiveExtents( pStartExtent,
675                                      extentsCount);
676
677         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
678                       AFS_TRACE_LEVEL_VERBOSE,
679                       "AFSNonCachedRead Releasing Fcb extents lock %p SHARED %08lX\n",
680                       &pFcb->NPFcb->Specific.File.ExtentsResource,
681                       PsGetCurrentThread());
682
683         AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
684         bLocked = FALSE;
685
686         //
687         // The data is there now.  Give back the extents now so the service
688         // has some in hand
689         //
690
691         if ( pFcb->Specific.File.ExtentLength > 4096)
692         {
693
694             (VOID) AFSReleaseExtentsWithFlush( pFcb,
695                                                &pCcb->AuthGroup,
696                                                FALSE);
697         }
698
699 try_exit:
700
701         if( pCacheFileObject != NULL)
702         {
703             AFSReleaseCacheFileObject( pCacheFileObject);
704         }
705
706         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
707                       AFS_TRACE_LEVEL_VERBOSE,
708                       "AFSNonCachedRead (%p) Completed request Status %08lX\n",
709                       Irp,
710                       ntStatus);
711
712         if (NT_SUCCESS(ntStatus) &&
713             !bPagingIo &&
714             BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
715         {
716             //
717             // Update the CBO if this is a sync, nopaging read
718             //
719             pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ulByteCount;
720         }
721
722         if (bLocked)
723         {
724
725             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
726                           AFS_TRACE_LEVEL_VERBOSE,
727                           "AFSNonCachedRead Releasing Fcb extents lock %p SHARED %08lX\n",
728                           &pFcb->NPFcb->Specific.File.ExtentsResource,
729                           PsGetCurrentThread());
730
731             AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource );
732         }
733
734         if (pGatherIo)
735         {
736             AFSExFreePoolWithTag(pGatherIo, AFS_GATHER_TAG);
737         }
738
739         if (NULL != pIoRuns && stIoRuns != pIoRuns)
740         {
741             AFSExFreePoolWithTag(pIoRuns, AFS_IO_RUN_TAG);
742         }
743
744         if (bCompleteIrp)
745         {
746
747             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
748                           AFS_TRACE_LEVEL_VERBOSE,
749                           "AFSNonCachedRead Completing irp %08lX Status %08lX Info %08lX\n",
750                           Irp,
751                           ntStatus,
752                           Irp->IoStatus.Information);
753
754             AFSCompleteRequest( Irp, ntStatus );
755         }
756     }
757     return ntStatus;
758 }
759
760 //
761 // Function: AFSDispatch
762 //
763 // Description:
764 //
765 // A shim around AFSCommonRead (qv)
766 //
767 NTSTATUS
768 AFSRead( IN PDEVICE_OBJECT LibDeviceObject,
769          IN PIRP Irp)
770 {
771
772     UNREFERENCED_PARAMETER(LibDeviceObject);
773     NTSTATUS ntStatus = STATUS_SUCCESS;
774
775     __try
776     {
777
778         ntStatus = AFSCommonRead( AFSRDRDeviceObject, Irp, NULL);
779     }
780     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
781     {
782
783         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
784
785         AFSDumpTraceFilesFnc();
786     }
787
788     return ntStatus;
789 }
790 //
791 // Function: AFSRead
792 //
793 // Description:
794 //
795 //      This function is a slightly widened Dispatch handler for the
796 //      AFS Read function.  The third parameter is NULL if we were called
797 //      at our dispatch point and a process handle if we have been posted.
798 //
799 //      After doing the obvious (completing MDL writes and so forth)
800 //      we then post, or not.
801 //
802 // Return:
803 //
804 //      A status is returned for the function
805 //
806
807 NTSTATUS
808 AFSCommonRead( IN PDEVICE_OBJECT DeviceObject,
809                IN PIRP Irp,
810                IN HANDLE OnBehalfOf)
811 {
812
813     UNREFERENCED_PARAMETER(OnBehalfOf);
814     NTSTATUS            ntStatus = STATUS_SUCCESS;
815     AFSDeviceExt       *pDeviceExt;
816     IO_STACK_LOCATION  *pIrpSp;
817     AFSFcb             *pFcb = NULL;
818     AFSCcb             *pCcb = NULL;
819     BOOLEAN             bReleaseMain = FALSE;
820     BOOLEAN             bReleaseSectionObject = FALSE;
821     BOOLEAN             bReleasePaging = FALSE;
822     BOOLEAN             bPagingIo = FALSE;
823     BOOLEAN             bNonCachedIo = FALSE;
824     BOOLEAN             bCompleteIrp = TRUE;
825     PFILE_OBJECT        pFileObject = NULL;
826     LARGE_INTEGER       liStartingByte;
827     ULONG               ulByteCount;
828
829     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
830     pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
831
832     __Enter
833     {
834         //
835         // Decode the fileobject
836         //
837         pFileObject = pIrpSp->FileObject;
838
839         //
840         // There is a risk (albeit infinitely small) that the Irp will
841         // complete before this function exits, then a cleanup and
842         // close will happen and the FCB will be torn down before we
843         // get to the try_exit.  Pin the file Object which will pin the FCB
844         //
845
846         ObReferenceObject( pFileObject);
847
848         //
849         // If we are in shutdown mode then fail the request
850         //
851
852         if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
853         {
854
855             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
856                           AFS_TRACE_LEVEL_WARNING,
857                           "AFSCommonRead (%p) Open request after shutdown\n",
858                           Irp);
859
860             try_return( ntStatus = STATUS_TOO_LATE);
861         }
862
863         pFcb = (AFSFcb *)pFileObject->FsContext;
864
865         pCcb = (AFSCcb *)pFileObject->FsContext2;
866
867         if( pFcb == NULL)
868         {
869
870             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
871                           AFS_TRACE_LEVEL_ERROR,
872                           "AFSCommonRead Attempted read (%p) when pFcb == NULL\n",
873                           Irp);
874
875             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
876         }
877
878         bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
879         bNonCachedIo = BooleanFlagOn( Irp->Flags,IRP_NOCACHE);
880
881         liStartingByte = pIrpSp->Parameters.Read.ByteOffset;
882         ulByteCount = pIrpSp->Parameters.Read.Length;
883
884         if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
885             pFcb->Header.NodeTypeCode != AFS_FILE_FCB &&
886             pFcb->Header.NodeTypeCode != AFS_SPECIAL_SHARE_FCB)
887         {
888
889             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
890                           AFS_TRACE_LEVEL_ERROR,
891                           "AFSCommonRead Attempted read (%p) on an invalid node type %08lX\n",
892                           Irp,
893                           pFcb->Header.NodeTypeCode);
894
895             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
896         }
897
898         //
899         // If this is a read against an IOCtl node then handle it
900         // in a different pathway
901         //
902
903         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
904         {
905
906             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
907                           AFS_TRACE_LEVEL_VERBOSE,
908                           "AFSCommonRead (%p) Processing file (PIOCTL) Offset %I64X Length %08lX Irp Flags %08lX\n",
909                           Irp,
910                           liStartingByte.QuadPart,
911                           ulByteCount,
912                           Irp->Flags);
913
914             ntStatus = AFSIOCtlRead( DeviceObject,
915                                      Irp);
916
917             try_return( ntStatus);
918         }
919         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
920         {
921
922             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
923                           AFS_TRACE_LEVEL_VERBOSE,
924                           "AFSCommonRead (%p) Processing file (SHARE) Offset %I64X Length %08lX Irp Flags %08lX\n",
925                           Irp,
926                           liStartingByte.QuadPart,
927                           ulByteCount,
928                           Irp->Flags);
929
930             ntStatus = AFSShareRead( DeviceObject,
931                                      Irp);
932
933             try_return( ntStatus);
934         }
935
936         //
937         // No fileobject yet?  Bail.
938         //
939         if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
940             NULL == pDeviceExt->Specific.RDR.CacheFileObject)
941         {
942
943             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
944                           AFS_TRACE_LEVEL_ERROR,
945                           "AFSCommonRead (%p) Request failed due to AFS cache closed\n",
946                           Irp);
947
948             try_return( ntStatus = STATUS_TOO_LATE );
949         }
950
951         if( pIrpSp->Parameters.Read.Length == 0)
952         {
953
954             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
955                           AFS_TRACE_LEVEL_VERBOSE,
956                           "AFSCommonRead (%p) Request completed due to zero length\n",
957                           Irp);
958
959             try_return( ntStatus);
960         }
961
962         if ( FlagOn(pIrpSp->MinorFunction, IRP_MN_COMPLETE) )
963         {
964
965             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
966                           AFS_TRACE_LEVEL_VERBOSE,
967                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
968                           &pFcb->NPFcb->SectionObjectResource,
969                           PsGetCurrentThread());
970
971             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
972                               TRUE);
973
974             bReleaseSectionObject = TRUE;
975
976             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
977                           AFS_TRACE_LEVEL_VERBOSE,
978                           "AFSCommonRead (%p) IRP_MN_COMPLETE being processed\n",
979                           Irp);
980
981             CcMdlReadComplete(pIrpSp->FileObject, Irp->MdlAddress);
982
983             //
984             // Mdl is now Deallocated
985             //
986
987             Irp->MdlAddress = NULL;
988
989             try_return( ntStatus = STATUS_SUCCESS );
990         }
991
992         //
993         // If we get a non cached IO for a cached file we should do a purge.
994         // For now we will just promote to cached
995         //
996         if (NULL != pFileObject->SectionObjectPointer->DataSectionObject && !bPagingIo)
997         {
998
999             bNonCachedIo = FALSE;
1000         }
1001
1002         //
1003         // We acquire the main/paging resource first to synchronize
1004         // against size checks.
1005         //
1006
1007         if( bPagingIo)
1008         {
1009
1010             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1011                           AFS_TRACE_LEVEL_VERBOSE,
1012                           "AFSCommonRead Acquiring Fcb PagingIo lock %p SHARED %08lX\n",
1013                           &pFcb->NPFcb->PagingResource,
1014                           PsGetCurrentThread());
1015
1016             AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1017                               TRUE);
1018
1019             bReleasePaging = TRUE;
1020
1021             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1022                           AFS_TRACE_LEVEL_VERBOSE,
1023                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1024                           &pFcb->NPFcb->SectionObjectResource,
1025                           PsGetCurrentThread());
1026
1027             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1028                               TRUE);
1029
1030             bReleaseSectionObject = TRUE;
1031
1032         }
1033         else
1034         {
1035
1036             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1037                           AFS_TRACE_LEVEL_VERBOSE,
1038                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1039                           &pFcb->NPFcb->SectionObjectResource,
1040                           PsGetCurrentThread());
1041
1042             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1043                               TRUE);
1044
1045             bReleaseSectionObject = TRUE;
1046
1047             //
1048             // Check the BR locks
1049             //
1050
1051             if( !FsRtlCheckLockForReadAccess( &pFcb->Specific.File.FileLock,
1052                                               Irp))
1053             {
1054
1055                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1056                               AFS_TRACE_LEVEL_ERROR,
1057                               "AFSCommonRead (%p) Request failed due to lock conflict\n",
1058                               Irp);
1059
1060                 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
1061             }
1062         }
1063
1064         if( BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED) ||
1065             BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1066         {
1067
1068             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1069                           AFS_TRACE_LEVEL_ERROR,
1070                           "AFSCommonRead (%p) Request failed due to file deleted\n",
1071                           Irp);
1072
1073             try_return( ntStatus = STATUS_FILE_DELETED);
1074         }
1075
1076         //
1077         // If the read starts beyond End of File, return EOF.
1078         //
1079
1080         if( liStartingByte.QuadPart >= pFcb->Header.FileSize.QuadPart)
1081         {
1082
1083             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1084                           AFS_TRACE_LEVEL_VERBOSE,
1085                           "AFSCommonRead (%p) Request beyond EOF %I64X\n",
1086                           Irp,
1087                           pFcb->Header.FileSize.QuadPart);
1088
1089             try_return( ntStatus = STATUS_END_OF_FILE);
1090         }
1091
1092         //
1093         //
1094
1095         if( liStartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
1096         {
1097
1098             ulByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - liStartingByte.QuadPart);
1099
1100             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1101                           AFS_TRACE_LEVEL_VERBOSE,
1102                           "AFSCommonRead (%p) Truncated read request to %08lX\n",
1103                           Irp,
1104                           ulByteCount);
1105         }
1106
1107         //
1108         // Is this Fcb valid???
1109         //
1110
1111         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID))
1112         {
1113
1114             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1115                           AFS_TRACE_LEVEL_ERROR,
1116                           "AFSCommonRead (%p) Failing request due to INVALID fcb\n",
1117                           Irp);
1118
1119             Irp->IoStatus.Information = 0;
1120
1121             try_return( ntStatus = STATUS_FILE_DELETED);
1122         }
1123
1124         //
1125         // If this is an cached IO
1126         //
1127         if( (!bPagingIo && !bNonCachedIo))
1128         {
1129             //
1130             // This is a top level irp. Init the caching if it has not yet
1131             // been initialzed for this FO
1132             //
1133
1134             if( pFileObject->PrivateCacheMap == NULL)
1135             {
1136
1137                 __try
1138                 {
1139
1140                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1141                                   AFS_TRACE_LEVEL_VERBOSE,
1142                                   "AFSCommonRead Initialize caching on Fcb %p FO %p\n",
1143                                   pFcb,
1144                                   pFileObject);
1145
1146                     CcInitializeCacheMap( pFileObject,
1147                                           (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
1148                                           FALSE,
1149                                           AFSLibCacheManagerCallbacks,
1150                                           pFcb);
1151
1152                     CcSetReadAheadGranularity( pFileObject,
1153                                                pDeviceExt->Specific.RDR.MaximumRPCLength);
1154
1155                     CcSetDirtyPageThreshold( pFileObject,
1156                                              AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength / 4096);
1157                 }
1158                 __except( EXCEPTION_EXECUTE_HANDLER)
1159                 {
1160
1161                     ntStatus = GetExceptionCode();
1162
1163                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1164                                   AFS_TRACE_LEVEL_ERROR,
1165                                   "AFSCommonRead (%p) Exception thrown while initializing cache map Status %08lX\n",
1166                                   Irp,
1167                                   ntStatus);
1168                 }
1169
1170                 if( !NT_SUCCESS( ntStatus))
1171                 {
1172
1173                     try_return( ntStatus);
1174                 }
1175             }
1176
1177             //
1178             // And if this is MDL operation, deal with it now (yes we
1179             // could post, but we are almost certainly posted
1180             // already and we don't want to grow and SVA for it..)
1181             //
1182
1183             if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1184             {
1185                 __try
1186                 {
1187
1188                     CcMdlRead( pFileObject,
1189                                &liStartingByte,
1190                                ulByteCount,
1191                                &Irp->MdlAddress,
1192                                &Irp->IoStatus);
1193                     ntStatus = Irp->IoStatus.Status;
1194                 }
1195                 __except( EXCEPTION_EXECUTE_HANDLER)
1196                 {
1197                     ntStatus = GetExceptionCode();
1198
1199                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1200                                   AFS_TRACE_LEVEL_ERROR,
1201                                   "AFSCommonRead (%p) Exception thrown during mdl read Status %08lX\n",
1202                                   Irp,
1203                                   ntStatus);
1204                 }
1205
1206                 if( !NT_SUCCESS( ntStatus))
1207                 {
1208
1209                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1210                                   AFS_TRACE_LEVEL_ERROR,
1211                                   "AFSCommonRead (%p) Failed to process MDL read Status %08lX\n",
1212                                   Irp,
1213                                   ntStatus);
1214
1215                     try_return( ntStatus);
1216                 }
1217
1218                 //
1219                 // Update the CBO if this is a sync read
1220                 //
1221
1222                 if( BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
1223                 {
1224
1225                     pFileObject->CurrentByteOffset.QuadPart = liStartingByte.QuadPart + ulByteCount;
1226                 }
1227
1228                 try_return( ntStatus);
1229             }
1230         }
1231
1232         //
1233         // The called request completes the IRP for us.
1234         //
1235
1236         bCompleteIrp = FALSE;
1237
1238         if( !bPagingIo &&
1239             !bNonCachedIo)
1240         {
1241
1242             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1243                           AFS_TRACE_LEVEL_VERBOSE,
1244                           "AFSCommonRead (%p) Processing CACHED request Offset %I64X Len %08lX\n",
1245                           Irp,
1246                           liStartingByte.QuadPart,
1247                           ulByteCount);
1248
1249             ntStatus = AFSCachedRead( DeviceObject, Irp, liStartingByte, ulByteCount);
1250         }
1251         else
1252         {
1253
1254             if( bReleasePaging)
1255             {
1256
1257                 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1258
1259                 bReleasePaging = FALSE;
1260             }
1261
1262             if( bReleaseSectionObject)
1263             {
1264
1265                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1266
1267                 bReleaseSectionObject = FALSE;
1268             }
1269
1270             if( bReleaseMain)
1271             {
1272
1273                 AFSReleaseResource( &pFcb->NPFcb->Resource);
1274
1275                 bReleaseMain = FALSE;
1276             }
1277
1278             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1279                           AFS_TRACE_LEVEL_VERBOSE,
1280                           "AFSCommonRead (%p) Processing NON-CACHED request Offset %I64X Len %08lX\n",
1281                           Irp,
1282                           liStartingByte.QuadPart,
1283                           ulByteCount);
1284
1285             ntStatus = AFSNonCachedRead( DeviceObject, Irp,  liStartingByte);
1286         }
1287
1288 try_exit:
1289
1290         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1291                       AFS_TRACE_LEVEL_VERBOSE,
1292                       "AFSCommonRead (%p) Process complete Status %08lX\n",
1293                       Irp,
1294                       ntStatus);
1295
1296         if( bReleasePaging)
1297         {
1298
1299             AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1300         }
1301
1302         if( bReleaseSectionObject)
1303         {
1304
1305             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1306         }
1307
1308         if( bReleaseMain)
1309         {
1310
1311             AFSReleaseResource( &pFcb->NPFcb->Resource);
1312         }
1313
1314         if( bCompleteIrp)
1315         {
1316
1317             AFSCompleteRequest( Irp, ntStatus);
1318         }
1319
1320         ObDereferenceObject( pFileObject);
1321     }
1322
1323     return ntStatus;
1324 }
1325
1326 NTSTATUS
1327 AFSIOCtlRead( IN PDEVICE_OBJECT DeviceObject,
1328               IN PIRP Irp)
1329 {
1330
1331     UNREFERENCED_PARAMETER(DeviceObject);
1332     NTSTATUS ntStatus = STATUS_SUCCESS;
1333     AFSPIOCtlIORequestCB stIORequestCB;
1334     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1335     AFSFcb *pFcb = NULL;
1336     AFSCcb *pCcb = NULL;
1337     AFSPIOCtlIOResultCB stIOResultCB;
1338     ULONG ulBytesReturned = 0;
1339     AFSFileID   stParentFID;
1340
1341     __Enter
1342     {
1343
1344         RtlZeroMemory( &stIORequestCB,
1345                        sizeof( AFSPIOCtlIORequestCB));
1346
1347         if( pIrpSp->Parameters.Read.Length == 0)
1348         {
1349
1350             //
1351             // Nothing to do in this case
1352             //
1353
1354             try_return( ntStatus);
1355         }
1356
1357         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1358
1359         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1360
1361         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1362                       AFS_TRACE_LEVEL_VERBOSE,
1363                       "AFSIOCtlRead Acquiring Fcb lock %p SHARED %08lX\n",
1364                       &pFcb->NPFcb->Resource,
1365                       PsGetCurrentThread());
1366
1367         AFSAcquireShared( &pFcb->NPFcb->Resource,
1368                           TRUE);
1369
1370         //
1371         // Get the parent fid to pass to the cm
1372         //
1373
1374         RtlZeroMemory( &stParentFID,
1375                        sizeof( AFSFileID));
1376
1377         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1378         {
1379
1380             //
1381             // The parent directory FID of the node
1382             //
1383
1384             stParentFID = pFcb->ObjectInformation->ParentFileId;
1385         }
1386
1387         //
1388         // Set the control block up
1389         //
1390
1391         stIORequestCB.RequestId = pCcb->RequestID;
1392
1393         if( pFcb->ObjectInformation->VolumeCB != NULL)
1394         {
1395             stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1396         }
1397
1398         //
1399         // Lock down the buffer
1400         //
1401
1402         stIORequestCB.MappedBuffer = AFSMapToService( Irp,
1403                                                       pIrpSp->Parameters.Read.Length);
1404
1405         if( stIORequestCB.MappedBuffer == NULL)
1406         {
1407
1408             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1409         }
1410
1411         stIORequestCB.BufferLength = pIrpSp->Parameters.Read.Length;
1412
1413         stIOResultCB.BytesProcessed = 0;
1414
1415         ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
1416
1417         //
1418         // Issue the request to the service
1419         //
1420
1421         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_READ,
1422                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1423                                       &pCcb->AuthGroup,
1424                                       NULL,
1425                                       &stParentFID,
1426                                       NULL,
1427                                       0,
1428                                       (void *)&stIORequestCB,
1429                                       sizeof( AFSPIOCtlIORequestCB),
1430                                       &stIOResultCB,
1431                                       &ulBytesReturned);
1432
1433         if( !NT_SUCCESS( ntStatus))
1434         {
1435
1436             try_return( ntStatus);
1437         }
1438
1439         //
1440         // Update the length read
1441         //
1442
1443         Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
1444
1445 try_exit:
1446
1447         if( stIORequestCB.MappedBuffer != NULL)
1448         {
1449
1450             AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
1451                                          Irp->MdlAddress);
1452         }
1453
1454         if( pFcb != NULL)
1455         {
1456
1457             AFSReleaseResource( &pFcb->NPFcb->Resource);
1458         }
1459     }
1460
1461     return ntStatus;
1462 }
1463
1464 NTSTATUS
1465 AFSShareRead( IN PDEVICE_OBJECT DeviceObject,
1466               IN PIRP Irp)
1467 {
1468
1469     UNREFERENCED_PARAMETER(DeviceObject);
1470     NTSTATUS ntStatus = STATUS_SUCCESS;
1471     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1472     AFSFcb *pFcb = NULL;
1473     AFSCcb *pCcb = NULL;
1474     ULONG ulBytesReturned = 0;
1475     void *pBuffer = NULL;
1476     AFSPipeIORequestCB stIoRequest;
1477
1478     __Enter
1479     {
1480
1481         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1482
1483         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1484
1485         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1486                       AFS_TRACE_LEVEL_VERBOSE,
1487                       "AFSShareRead On pipe %wZ Length %08lX\n",
1488                       &pCcb->DirectoryCB->NameInformation.FileName,
1489                       pIrpSp->Parameters.Read.Length);
1490
1491         if( pIrpSp->Parameters.Read.Length == 0)
1492         {
1493
1494             //
1495             // Nothing to do in this case
1496             //
1497
1498             try_return( ntStatus);
1499         }
1500
1501         AFSAcquireShared( &pFcb->NPFcb->Resource,
1502                           TRUE);
1503
1504         //
1505         // Retrieve the buffer for the read request
1506         //
1507
1508         pBuffer = AFSLockSystemBuffer( Irp,
1509                                        pIrpSp->Parameters.Read.Length);
1510
1511         if( pBuffer == NULL)
1512         {
1513
1514             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1515                           AFS_TRACE_LEVEL_ERROR,
1516                           "AFSShareRead Failed to map buffer on pipe %wZ\n",
1517                           &pCcb->DirectoryCB->NameInformation.FileName);
1518
1519             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1520         }
1521
1522         RtlZeroMemory( &stIoRequest,
1523                        sizeof( AFSPipeIORequestCB));
1524
1525         stIoRequest.RequestId = pCcb->RequestID;
1526
1527         stIoRequest.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1528
1529         stIoRequest.BufferLength = pIrpSp->Parameters.Read.Length;
1530
1531         ulBytesReturned = pIrpSp->Parameters.Read.Length;
1532
1533         //
1534         // Issue the open request to the service
1535         //
1536
1537         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_READ,
1538                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1539                                       &pCcb->AuthGroup,
1540                                       &pCcb->DirectoryCB->NameInformation.FileName,
1541                                       NULL,
1542                                       NULL,
1543                                       0,
1544                                       (void *)&stIoRequest,
1545                                       sizeof( AFSPipeIORequestCB),
1546                                       pBuffer,
1547                                       &ulBytesReturned);
1548
1549         if( !NT_SUCCESS( ntStatus) &&
1550             ntStatus != STATUS_BUFFER_OVERFLOW)
1551         {
1552
1553             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1554                           AFS_TRACE_LEVEL_ERROR,
1555                           "AFSShareRead (%p) Failed service read Status %08lX\n",
1556                           Irp,
1557                           ntStatus);
1558
1559             try_return( ntStatus);
1560         }
1561
1562         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1563                       AFS_TRACE_LEVEL_VERBOSE,
1564                       "AFSShareRead Completed on pipe %wZ Length read %08lX Status %08lX\n",
1565                       &pCcb->DirectoryCB->NameInformation.FileName,
1566                       ulBytesReturned,
1567                       ntStatus);
1568
1569         Irp->IoStatus.Information = ulBytesReturned;
1570
1571 try_exit:
1572
1573         if( pFcb != NULL)
1574         {
1575
1576             AFSReleaseResource( &pFcb->NPFcb->Resource);
1577         }
1578     }
1579
1580     return ntStatus;
1581 }