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