033ab2666ce9766e95eab4212b39b1fe9186ec04
[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 %08lX run count %08lX\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 // Function: AFSDispatch
761 //
762 // Description:
763 //
764 // A shim around AFSCommonRead (qv)
765 //
766 NTSTATUS
767 AFSRead( IN PDEVICE_OBJECT LibDeviceObject,
768          IN PIRP Irp)
769 {
770
771     UNREFERENCED_PARAMETER(LibDeviceObject);
772     NTSTATUS ntStatus = STATUS_SUCCESS;
773
774     __try
775     {
776
777         ntStatus = AFSCommonRead( AFSRDRDeviceObject, Irp, NULL);
778     }
779     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
780     {
781
782         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
783
784         AFSDumpTraceFilesFnc();
785     }
786
787     return ntStatus;
788 }
789 //
790 // Function: AFSRead
791 //
792 // Description:
793 //
794 //      This function is a slightly widened Dispatch handler for the
795 //      AFS Read function.  The third parameter is NULL if we were called
796 //      at our dispatch point and a process handle if we have been posted.
797 //
798 //      After doing the obvious (completing MDL writes and so forth)
799 //      we then post, or not.
800 //
801 // Return:
802 //
803 //      A status is returned for the function
804 //
805
806 NTSTATUS
807 AFSCommonRead( IN PDEVICE_OBJECT DeviceObject,
808                IN PIRP Irp,
809                IN HANDLE OnBehalfOf)
810 {
811
812     UNREFERENCED_PARAMETER(OnBehalfOf);
813     NTSTATUS            ntStatus = STATUS_SUCCESS;
814     AFSDeviceExt       *pDeviceExt;
815     IO_STACK_LOCATION  *pIrpSp;
816     AFSFcb             *pFcb = NULL;
817     AFSCcb             *pCcb = NULL;
818     BOOLEAN             bReleaseMain = FALSE;
819     BOOLEAN             bReleaseSectionObject = FALSE;
820     BOOLEAN             bReleasePaging = FALSE;
821     BOOLEAN             bPagingIo = FALSE;
822     BOOLEAN             bNonCachedIo = FALSE;
823     BOOLEAN             bCompleteIrp = TRUE;
824     PFILE_OBJECT        pFileObject = NULL;
825     LARGE_INTEGER       liStartingByte;
826     ULONG               ulByteCount;
827
828     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
829     pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
830
831     __Enter
832     {
833         //
834         // Decode the fileobject
835         //
836         pFileObject = pIrpSp->FileObject;
837
838         //
839         // There is a risk (albeit infinitely small) that the Irp will
840         // complete before this function exits, then a cleanup and
841         // close will happen and the FCB will be torn down before we
842         // get to the try_exit.  Pin the file Object which will pin the FCB
843         //
844
845         ObReferenceObject( pFileObject);
846
847         //
848         // If we are in shutdown mode then fail the request
849         //
850
851         if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
852         {
853
854             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
855                           AFS_TRACE_LEVEL_WARNING,
856                           "AFSCommonRead (%p) Open request after shutdown\n",
857                           Irp);
858
859             try_return( ntStatus = STATUS_TOO_LATE);
860         }
861
862         pFcb = (AFSFcb *)pFileObject->FsContext;
863
864         pCcb = (AFSCcb *)pFileObject->FsContext2;
865
866         if( pFcb == NULL)
867         {
868
869             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
870                           AFS_TRACE_LEVEL_ERROR,
871                           "AFSCommonRead Attempted read (%p) when pFcb == NULL\n",
872                           Irp);
873
874             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
875         }
876
877         bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
878         bNonCachedIo = BooleanFlagOn( Irp->Flags,IRP_NOCACHE);
879
880         liStartingByte = pIrpSp->Parameters.Read.ByteOffset;
881         ulByteCount = pIrpSp->Parameters.Read.Length;
882
883         if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
884             pFcb->Header.NodeTypeCode != AFS_FILE_FCB &&
885             pFcb->Header.NodeTypeCode != AFS_SPECIAL_SHARE_FCB)
886         {
887
888             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
889                           AFS_TRACE_LEVEL_ERROR,
890                           "AFSCommonRead Attempted read (%p) on an invalid node type %08lX\n",
891                           Irp,
892                           pFcb->Header.NodeTypeCode);
893
894             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
895         }
896
897         //
898         // If this is a read against an IOCtl node then handle it
899         // in a different pathway
900         //
901
902         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
903         {
904
905             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
906                           AFS_TRACE_LEVEL_VERBOSE,
907                           "AFSCommonRead (%p) Processing file (PIOCTL) Offset %I64X Length %08lX Irp Flags %08lX\n",
908                           Irp,
909                           liStartingByte.QuadPart,
910                           ulByteCount,
911                           Irp->Flags);
912
913             ntStatus = AFSIOCtlRead( DeviceObject,
914                                      Irp);
915
916             try_return( ntStatus);
917         }
918         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
919         {
920
921             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
922                           AFS_TRACE_LEVEL_VERBOSE,
923                           "AFSCommonRead (%p) Processing file (SHARE) Offset %I64X Length %08lX Irp Flags %08lX\n",
924                           Irp,
925                           liStartingByte.QuadPart,
926                           ulByteCount,
927                           Irp->Flags);
928
929             ntStatus = AFSShareRead( DeviceObject,
930                                      Irp);
931
932             try_return( ntStatus);
933         }
934
935         //
936         // No fileobject yet?  Bail.
937         //
938         if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
939             NULL == pDeviceExt->Specific.RDR.CacheFileObject)
940         {
941
942             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
943                           AFS_TRACE_LEVEL_ERROR,
944                           "AFSCommonRead (%p) Request failed due to AFS cache closed\n",
945                           Irp);
946
947             try_return( ntStatus = STATUS_TOO_LATE );
948         }
949
950         if( pIrpSp->Parameters.Read.Length == 0)
951         {
952
953             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
954                           AFS_TRACE_LEVEL_VERBOSE,
955                           "AFSCommonRead (%p) Request completed due to zero length\n",
956                           Irp);
957
958             try_return( ntStatus);
959         }
960
961         if ( FlagOn(pIrpSp->MinorFunction, IRP_MN_COMPLETE) )
962         {
963
964             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
965                           AFS_TRACE_LEVEL_VERBOSE,
966                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
967                           &pFcb->NPFcb->SectionObjectResource,
968                           PsGetCurrentThread());
969
970             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
971                               TRUE);
972
973             bReleaseSectionObject = TRUE;
974
975             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
976                           AFS_TRACE_LEVEL_VERBOSE,
977                           "AFSCommonRead (%p) IRP_MN_COMPLETE being processed\n",
978                           Irp);
979
980             CcMdlReadComplete(pIrpSp->FileObject, Irp->MdlAddress);
981
982             //
983             // Mdl is now Deallocated
984             //
985
986             Irp->MdlAddress = NULL;
987
988             try_return( ntStatus = STATUS_SUCCESS );
989         }
990
991         //
992         // If we get a non cached IO for a cached file we should do a purge.
993         // For now we will just promote to cached
994         //
995         if (NULL != pFileObject->SectionObjectPointer->DataSectionObject && !bPagingIo)
996         {
997
998             bNonCachedIo = FALSE;
999         }
1000
1001         //
1002         // We acquire the main/paging resource first to synchronize
1003         // against size checks.
1004         //
1005
1006         if( bPagingIo)
1007         {
1008
1009             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1010                           AFS_TRACE_LEVEL_VERBOSE,
1011                           "AFSCommonRead Acquiring Fcb PagingIo lock %p SHARED %08lX\n",
1012                           &pFcb->NPFcb->PagingResource,
1013                           PsGetCurrentThread());
1014
1015             AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1016                               TRUE);
1017
1018             bReleasePaging = TRUE;
1019
1020             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1021                           AFS_TRACE_LEVEL_VERBOSE,
1022                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1023                           &pFcb->NPFcb->SectionObjectResource,
1024                           PsGetCurrentThread());
1025
1026             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1027                               TRUE);
1028
1029             bReleaseSectionObject = TRUE;
1030
1031         }
1032         else
1033         {
1034
1035             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1036                           AFS_TRACE_LEVEL_VERBOSE,
1037                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1038                           &pFcb->NPFcb->SectionObjectResource,
1039                           PsGetCurrentThread());
1040
1041             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1042                               TRUE);
1043
1044             bReleaseSectionObject = TRUE;
1045
1046             //
1047             // Check the BR locks
1048             //
1049
1050             if( !FsRtlCheckLockForReadAccess( &pFcb->Specific.File.FileLock,
1051                                               Irp))
1052             {
1053
1054                 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1055                               AFS_TRACE_LEVEL_ERROR,
1056                               "AFSCommonRead (%p) Request failed due to lock conflict\n",
1057                               Irp);
1058
1059                 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
1060             }
1061         }
1062
1063         if( BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED) ||
1064             BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1065         {
1066
1067             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1068                           AFS_TRACE_LEVEL_ERROR,
1069                           "AFSCommonRead (%p) Request failed due to file deleted\n",
1070                           Irp);
1071
1072             try_return( ntStatus = STATUS_FILE_DELETED);
1073         }
1074
1075         //
1076         // If the read starts beyond End of File, return EOF.
1077         //
1078
1079         if( liStartingByte.QuadPart >= pFcb->Header.FileSize.QuadPart)
1080         {
1081
1082             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1083                           AFS_TRACE_LEVEL_VERBOSE,
1084                           "AFSCommonRead (%p) Request beyond EOF %I64X\n",
1085                           Irp,
1086                           pFcb->Header.FileSize.QuadPart);
1087
1088             try_return( ntStatus = STATUS_END_OF_FILE);
1089         }
1090
1091         //
1092         //
1093
1094         if( liStartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
1095         {
1096
1097             ulByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - liStartingByte.QuadPart);
1098
1099             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1100                           AFS_TRACE_LEVEL_VERBOSE,
1101                           "AFSCommonRead (%p) Truncated read request to %08lX\n",
1102                           Irp,
1103                           ulByteCount);
1104         }
1105
1106         //
1107         // Is this Fcb valid???
1108         //
1109
1110         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID))
1111         {
1112
1113             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1114                           AFS_TRACE_LEVEL_ERROR,
1115                           "AFSCommonRead (%p) Failing request due to INVALID fcb\n",
1116                           Irp);
1117
1118             Irp->IoStatus.Information = 0;
1119
1120             try_return( ntStatus = STATUS_FILE_DELETED);
1121         }
1122
1123         //
1124         // If this is an cached IO
1125         //
1126         if( (!bPagingIo && !bNonCachedIo))
1127         {
1128             //
1129             // This is a top level irp. Init the caching if it has not yet
1130             // been initialzed for this FO
1131             //
1132
1133             if( pFileObject->PrivateCacheMap == NULL)
1134             {
1135
1136                 __try
1137                 {
1138
1139                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1140                                   AFS_TRACE_LEVEL_VERBOSE,
1141                                   "AFSCommonRead Initialize caching on Fcb %p FO %p\n",
1142                                   pFcb,
1143                                   pFileObject);
1144
1145                     CcInitializeCacheMap( pFileObject,
1146                                           (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
1147                                           FALSE,
1148                                           AFSLibCacheManagerCallbacks,
1149                                           pFcb);
1150
1151                     CcSetReadAheadGranularity( pFileObject,
1152                                                pDeviceExt->Specific.RDR.MaximumRPCLength);
1153
1154                     CcSetDirtyPageThreshold( pFileObject,
1155                                              AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength);
1156                 }
1157                 __except( EXCEPTION_EXECUTE_HANDLER)
1158                 {
1159
1160                     ntStatus = GetExceptionCode();
1161
1162                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1163                                   AFS_TRACE_LEVEL_ERROR,
1164                                   "AFSCommonRead (%p) Exception thrown while initializing cache map Status %08lX\n",
1165                                   Irp,
1166                                   ntStatus);
1167                 }
1168
1169                 if( !NT_SUCCESS( ntStatus))
1170                 {
1171
1172                     try_return( ntStatus);
1173                 }
1174             }
1175
1176             //
1177             // And if this is MDL operation, deal with it now (yes we
1178             // could post, but we are almost certainly posted
1179             // already and we don't want to grow and SVA for it..)
1180             //
1181
1182             if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1183             {
1184                 __try
1185                 {
1186
1187                     CcMdlRead( pFileObject,
1188                                &liStartingByte,
1189                                ulByteCount,
1190                                &Irp->MdlAddress,
1191                                &Irp->IoStatus);
1192                     ntStatus = Irp->IoStatus.Status;
1193                 }
1194                 __except( EXCEPTION_EXECUTE_HANDLER)
1195                 {
1196                     ntStatus = GetExceptionCode();
1197
1198                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1199                                   AFS_TRACE_LEVEL_ERROR,
1200                                   "AFSCommonRead (%p) Exception thrown during mdl read Status %08lX\n",
1201                                   Irp,
1202                                   ntStatus);
1203                 }
1204
1205                 if( !NT_SUCCESS( ntStatus))
1206                 {
1207
1208                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1209                                   AFS_TRACE_LEVEL_ERROR,
1210                                   "AFSCommonRead (%p) Failed to process MDL read Status %08lX\n",
1211                                   Irp,
1212                                   ntStatus);
1213
1214                     try_return( ntStatus);
1215                 }
1216
1217                 //
1218                 // Update the CBO if this is a sync read
1219                 //
1220
1221                 if( BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
1222                 {
1223
1224                     pFileObject->CurrentByteOffset.QuadPart = liStartingByte.QuadPart + ulByteCount;
1225                 }
1226
1227                 try_return( ntStatus);
1228             }
1229         }
1230
1231         //
1232         // The called request completes the IRP for us.
1233         //
1234
1235         bCompleteIrp = FALSE;
1236
1237         if( !bPagingIo &&
1238             !bNonCachedIo)
1239         {
1240
1241             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1242                           AFS_TRACE_LEVEL_VERBOSE,
1243                           "AFSCommonRead (%p) Processing CACHED request Offset %I64X Len %08lX\n",
1244                           Irp,
1245                           liStartingByte.QuadPart,
1246                           ulByteCount);
1247
1248             ntStatus = AFSCachedRead( DeviceObject, Irp, liStartingByte, ulByteCount);
1249         }
1250         else
1251         {
1252
1253             if( bReleasePaging)
1254             {
1255
1256                 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1257
1258                 bReleasePaging = FALSE;
1259             }
1260
1261             if( bReleaseSectionObject)
1262             {
1263
1264                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1265
1266                 bReleaseSectionObject = FALSE;
1267             }
1268
1269             if( bReleaseMain)
1270             {
1271
1272                 AFSReleaseResource( &pFcb->NPFcb->Resource);
1273
1274                 bReleaseMain = FALSE;
1275             }
1276
1277             AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1278                           AFS_TRACE_LEVEL_VERBOSE,
1279                           "AFSCommonRead (%p) Processing NON-CACHED request Offset %I64X Len %08lX\n",
1280                           Irp,
1281                           liStartingByte.QuadPart,
1282                           ulByteCount);
1283
1284             ntStatus = AFSNonCachedRead( DeviceObject, Irp,  liStartingByte);
1285         }
1286
1287 try_exit:
1288
1289         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1290                       AFS_TRACE_LEVEL_VERBOSE,
1291                       "AFSCommonRead (%p) Process complete Status %08lX\n",
1292                       Irp,
1293                       ntStatus);
1294
1295         if( bReleasePaging)
1296         {
1297
1298             AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1299         }
1300
1301         if( bReleaseSectionObject)
1302         {
1303
1304             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1305         }
1306
1307         if( bReleaseMain)
1308         {
1309
1310             AFSReleaseResource( &pFcb->NPFcb->Resource);
1311         }
1312
1313         if( bCompleteIrp)
1314         {
1315
1316             AFSCompleteRequest( Irp, ntStatus);
1317         }
1318
1319         ObDereferenceObject( pFileObject);
1320     }
1321
1322     return ntStatus;
1323 }
1324
1325 NTSTATUS
1326 AFSIOCtlRead( IN PDEVICE_OBJECT DeviceObject,
1327               IN PIRP Irp)
1328 {
1329
1330     UNREFERENCED_PARAMETER(DeviceObject);
1331     NTSTATUS ntStatus = STATUS_SUCCESS;
1332     AFSPIOCtlIORequestCB stIORequestCB;
1333     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1334     AFSFcb *pFcb = NULL;
1335     AFSCcb *pCcb = NULL;
1336     AFSPIOCtlIOResultCB stIOResultCB;
1337     ULONG ulBytesReturned = 0;
1338     AFSFileID   stParentFID;
1339
1340     __Enter
1341     {
1342
1343         RtlZeroMemory( &stIORequestCB,
1344                        sizeof( AFSPIOCtlIORequestCB));
1345
1346         if( pIrpSp->Parameters.Read.Length == 0)
1347         {
1348
1349             //
1350             // Nothing to do in this case
1351             //
1352
1353             try_return( ntStatus);
1354         }
1355
1356         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1357
1358         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1359
1360         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1361                       AFS_TRACE_LEVEL_VERBOSE,
1362                       "AFSIOCtlRead Acquiring Fcb lock %p SHARED %08lX\n",
1363                       &pFcb->NPFcb->Resource,
1364                       PsGetCurrentThread());
1365
1366         AFSAcquireShared( &pFcb->NPFcb->Resource,
1367                           TRUE);
1368
1369         //
1370         // Get the parent fid to pass to the cm
1371         //
1372
1373         RtlZeroMemory( &stParentFID,
1374                        sizeof( AFSFileID));
1375
1376         if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
1377         {
1378
1379             //
1380             // The parent directory FID of the node
1381             //
1382
1383             ASSERT( pFcb->ObjectInformation->ParentObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
1384
1385             stParentFID = pFcb->ObjectInformation->ParentObjectInformation->FileId;
1386         }
1387
1388         //
1389         // Set the control block up
1390         //
1391
1392         stIORequestCB.RequestId = pCcb->RequestID;
1393
1394         if( pFcb->ObjectInformation->VolumeCB != NULL)
1395         {
1396             stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1397         }
1398
1399         //
1400         // Lock down the buffer
1401         //
1402
1403         stIORequestCB.MappedBuffer = AFSMapToService( Irp,
1404                                                       pIrpSp->Parameters.Read.Length);
1405
1406         if( stIORequestCB.MappedBuffer == NULL)
1407         {
1408
1409             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1410         }
1411
1412         stIORequestCB.BufferLength = pIrpSp->Parameters.Read.Length;
1413
1414         stIOResultCB.BytesProcessed = 0;
1415
1416         ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
1417
1418         //
1419         // Issue the request to the service
1420         //
1421
1422         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_READ,
1423                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1424                                       &pCcb->AuthGroup,
1425                                       NULL,
1426                                       &stParentFID,
1427                                       (void *)&stIORequestCB,
1428                                       sizeof( AFSPIOCtlIORequestCB),
1429                                       &stIOResultCB,
1430                                       &ulBytesReturned);
1431
1432         if( !NT_SUCCESS( ntStatus))
1433         {
1434
1435             try_return( ntStatus);
1436         }
1437
1438         //
1439         // Update the length read
1440         //
1441
1442         Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
1443
1444 try_exit:
1445
1446         if( stIORequestCB.MappedBuffer != NULL)
1447         {
1448
1449             AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
1450                                          Irp->MdlAddress);
1451         }
1452
1453         if( pFcb != NULL)
1454         {
1455
1456             AFSReleaseResource( &pFcb->NPFcb->Resource);
1457         }
1458     }
1459
1460     return ntStatus;
1461 }
1462
1463 NTSTATUS
1464 AFSShareRead( IN PDEVICE_OBJECT DeviceObject,
1465               IN PIRP Irp)
1466 {
1467
1468     UNREFERENCED_PARAMETER(DeviceObject);
1469     NTSTATUS ntStatus = STATUS_SUCCESS;
1470     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1471     AFSFcb *pFcb = NULL;
1472     AFSCcb *pCcb = NULL;
1473     ULONG ulBytesReturned = 0;
1474     void *pBuffer = NULL;
1475     AFSPipeIORequestCB stIoRequest;
1476
1477     __Enter
1478     {
1479
1480         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1481
1482         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1483
1484         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1485                       AFS_TRACE_LEVEL_VERBOSE,
1486                       "AFSShareRead On pipe %wZ Length %08lX\n",
1487                       &pCcb->DirectoryCB->NameInformation.FileName,
1488                       pIrpSp->Parameters.Read.Length);
1489
1490         if( pIrpSp->Parameters.Read.Length == 0)
1491         {
1492
1493             //
1494             // Nothing to do in this case
1495             //
1496
1497             try_return( ntStatus);
1498         }
1499
1500         AFSAcquireShared( &pFcb->NPFcb->Resource,
1501                           TRUE);
1502
1503         //
1504         // Retrieve the buffer for the read request
1505         //
1506
1507         pBuffer = AFSLockSystemBuffer( Irp,
1508                                        pIrpSp->Parameters.Read.Length);
1509
1510         if( pBuffer == NULL)
1511         {
1512
1513             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1514                           AFS_TRACE_LEVEL_ERROR,
1515                           "AFSShareRead Failed to map buffer on pipe %wZ\n",
1516                           &pCcb->DirectoryCB->NameInformation.FileName);
1517
1518             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1519         }
1520
1521         RtlZeroMemory( &stIoRequest,
1522                        sizeof( AFSPipeIORequestCB));
1523
1524         stIoRequest.RequestId = pCcb->RequestID;
1525
1526         stIoRequest.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1527
1528         stIoRequest.BufferLength = pIrpSp->Parameters.Read.Length;
1529
1530         ulBytesReturned = pIrpSp->Parameters.Read.Length;
1531
1532         //
1533         // Issue the open request to the service
1534         //
1535
1536         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_READ,
1537                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1538                                       &pCcb->AuthGroup,
1539                                       &pCcb->DirectoryCB->NameInformation.FileName,
1540                                       NULL,
1541                                       (void *)&stIoRequest,
1542                                       sizeof( AFSPipeIORequestCB),
1543                                       pBuffer,
1544                                       &ulBytesReturned);
1545
1546         if( !NT_SUCCESS( ntStatus) &&
1547             ntStatus != STATUS_BUFFER_OVERFLOW)
1548         {
1549
1550             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1551                           AFS_TRACE_LEVEL_ERROR,
1552                           "AFSShareRead (%p) Failed service read Status %08lX\n",
1553                           Irp,
1554                           ntStatus);
1555
1556             try_return( ntStatus);
1557         }
1558
1559         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
1560                       AFS_TRACE_LEVEL_VERBOSE,
1561                       "AFSShareRead Completed on pipe %wZ Length read %08lX Status %08lX\n",
1562                       &pCcb->DirectoryCB->NameInformation.FileName,
1563                       ulBytesReturned,
1564                       ntStatus);
1565
1566         Irp->IoStatus.Information = ulBytesReturned;
1567
1568 try_exit:
1569
1570         if( pFcb != NULL)
1571         {
1572
1573             AFSReleaseResource( &pFcb->NPFcb->Resource);
1574         }
1575     }
1576
1577     return ntStatus;
1578 }