venus: Remove dedebug
[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                 AFSDbgTrace(( 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                     AFSDbgTrace(( 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                 AFSDbgTrace(( 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             AFSDbgTrace(( 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             AFSDbgTrace(( 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             AFSDbgTrace(( 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         AFSDbgTrace(( 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             AFSDbgTrace(( 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             AFSDbgTrace(( 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             AFSDbgTrace(( 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                 AFSDbgTrace(( 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                     AFSDbgTrace(( 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             AFSDbgTrace(( 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                 AFSDbgTrace(( 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         AFSDbgTrace(( 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             AFSDbgTrace(( 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         AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
443                       AFS_TRACE_LEVEL_VERBOSE,
444                       "AFSNonCachedRead (%p) Successfully retrieved map extents count %d run count %d\n",
445                       Irp,
446                       extentsCount,
447                       runCount));
448
449         if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
450         {
451
452             Irp->IoStatus.Information = ulReadByteCount;
453
454             ntStatus = AFSProcessExtentRun( pSystemBuffer,
455                                             &StartingByte,
456                                             ulReadByteCount,
457                                             pStartExtent,
458                                             FALSE);
459
460             if (!NT_SUCCESS(ntStatus))
461             {
462
463                 AFSDbgTrace(( 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             AFSDbgTrace(( 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                 AFSDbgTrace(( 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             AFSDbgTrace(( 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         AFSDbgTrace(( 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             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
564                           AFS_TRACE_LEVEL_ERROR,
565                           "AFSNonCachedRead (%p) Failed to allocate IO gather block\n",
566                           Irp));
567
568             AFSDbgTrace(( 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         AFSDbgTrace(( 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             AFSDbgTrace(( 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         AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
659                       AFS_TRACE_LEVEL_VERBOSE,
660                       "AFSNonCachedRead (%p) AFSStartIos wait completed Status %08lX\n",
661                       Irp,
662                       ntStatus));
663
664         AFSDbgTrace(( 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         AFSDbgTrace(( 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         AFSDbgTrace(( 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             AFSDbgTrace(( 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             AFSDbgTrace(( 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 static
761 NTSTATUS
762 AFSNonCachedReadDirect( IN PDEVICE_OBJECT DeviceObject,
763                         IN PIRP Irp,
764                         IN LARGE_INTEGER StartingByte)
765 {
766     NTSTATUS           ntStatus = STATUS_UNSUCCESSFUL;
767     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
768     PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
769     AFSFcb            *pFcb = (AFSFcb *)pFileObject->FsContext;
770     AFSCcb            *pCcb = (AFSCcb *)pFileObject->FsContext2;
771     VOID              *pSystemBuffer = NULL;
772     ULONG              ulByteCount = 0;
773     ULONG              ulReadByteCount = 0;
774     ULONG              ulFlags;
775     BOOLEAN            bNoIntermediateBuffering = BooleanFlagOn( pFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING);
776     AFSDeviceExt      *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
777     AFSFileIOCB        stFileIORequest;
778     AFSFileIOResultCB  stFileIOResult;
779     ULONG              ulResultLen = 0;
780
781     __Enter
782     {
783
784         Irp->IoStatus.Information = 0;
785
786         ulByteCount = pIrpSp->Parameters.Read.Length;
787
788         if (ulByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
789         {
790
791             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
792                           AFS_TRACE_LEVEL_ERROR,
793                           "AFSNonCachedReadDirect (%p) Request larger than MaxIO %I64X\n",
794                           Irp,
795                           pDevExt->Specific.RDR.MaxIo.QuadPart));
796
797             try_return( ntStatus = STATUS_UNSUCCESSFUL);
798         }
799
800         pSystemBuffer = AFSLockSystemBuffer( Irp,
801                                              ulByteCount);
802
803         if( pSystemBuffer == NULL)
804         {
805
806             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
807                           AFS_TRACE_LEVEL_ERROR,
808                           "AFSNonCachedReadDirect (%p) Failed to map system buffer\n",
809                           Irp));
810
811             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
812         }
813
814         if( StartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
815         {
816             ULONG zeroCount = (ULONG) (StartingByte.QuadPart + ulByteCount - pFcb->Header.FileSize.QuadPart);
817             ulReadByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - StartingByte.QuadPart);
818
819             //
820             // Clear up to EOF
821             //
822
823             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
824                           AFS_TRACE_LEVEL_VERBOSE,
825                           "AFSNonCachedReadDirect (%p) Zeroing to EOF zero byte length %08lX\n",
826                           Irp,
827                           zeroCount));
828
829             RtlZeroMemory( ((PCHAR)pSystemBuffer) + ulReadByteCount, zeroCount);
830         }
831         else
832         {
833             ulReadByteCount = ulByteCount;
834         }
835
836         //
837         // Issue the request at the service for processing
838         //
839
840         ulResultLen = sizeof( AFSFileIOResultCB);
841
842         RtlZeroMemory( &stFileIORequest,
843                        sizeof( AFSFileIOCB));
844
845         RtlZeroMemory( &stFileIOResult,
846                        sizeof( AFSFileIOResultCB));
847
848         stFileIORequest.SystemIOBuffer = pSystemBuffer;
849
850         stFileIORequest.SystemIOBufferMdl = Irp->MdlAddress;
851
852         stFileIORequest.IOOffset = StartingByte;
853
854         stFileIORequest.IOLength = ulReadByteCount;
855
856         ulFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
857
858         if ( bNoIntermediateBuffering)
859         {
860
861             ulFlags |= AFS_REQUEST_FLAG_CACHE_BYPASS;
862         }
863
864         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PROCESS_READ_FILE,
865                                       ulFlags,
866                                       &pCcb->AuthGroup,
867                                       &pCcb->DirectoryCB->NameInformation.FileName,
868                                       &pFcb->ObjectInformation->FileId,
869                                       pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
870                                       pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
871                                       &stFileIORequest,
872                                       sizeof( AFSFileIOCB),
873                                       &stFileIOResult,
874                                       &ulResultLen);
875
876         if( NT_SUCCESS( ntStatus))
877         {
878
879             Irp->IoStatus.Information = (ULONG_PTR)stFileIOResult.Length;
880         }
881         else
882         {
883
884             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
885                           AFS_TRACE_LEVEL_ERROR,
886                           "AFSNonCachedReadDirect (%p) Failed to send read to service Status %08lX\n",
887                           Irp,
888                           ntStatus));
889         }
890
891 try_exit:
892
893         AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
894                       AFS_TRACE_LEVEL_VERBOSE,
895                       "AFSNonCachedReadDirect (%p) Completed request Status %08lX\n",
896                       Irp,
897                       ntStatus));
898
899         if (NT_SUCCESS(ntStatus) &&
900             !BooleanFlagOn( Irp->Flags, IRP_PAGING_IO) &&
901             BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
902         {
903             //
904             // Update the CBO if this is a sync, nopaging read
905             //
906             pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ulByteCount;
907         }
908
909         AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
910                       AFS_TRACE_LEVEL_VERBOSE,
911                       "AFSNonCachedReadDirect Completing irp %08lX Status %08lX Info %08lX\n",
912                       Irp,
913                       ntStatus,
914                       Irp->IoStatus.Information));
915
916         AFSCompleteRequest( Irp, ntStatus );
917     }
918
919     return ntStatus;
920 }
921
922 //
923 // Function: AFSDispatch
924 //
925 // Description:
926 //
927 // A shim around AFSCommonRead (qv)
928 //
929 NTSTATUS
930 AFSRead( IN PDEVICE_OBJECT LibDeviceObject,
931          IN PIRP Irp)
932 {
933
934     UNREFERENCED_PARAMETER(LibDeviceObject);
935     NTSTATUS ntStatus = STATUS_SUCCESS;
936
937     __try
938     {
939
940         ntStatus = AFSCommonRead( AFSRDRDeviceObject, Irp, NULL);
941     }
942     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
943     {
944
945         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
946
947         AFSDumpTraceFilesFnc();
948     }
949
950     return ntStatus;
951 }
952 //
953 // Function: AFSRead
954 //
955 // Description:
956 //
957 //      This function is a slightly widened Dispatch handler for the
958 //      AFS Read function.  The third parameter is NULL if we were called
959 //      at our dispatch point and a process handle if we have been posted.
960 //
961 //      After doing the obvious (completing MDL writes and so forth)
962 //      we then post, or not.
963 //
964 // Return:
965 //
966 //      A status is returned for the function
967 //
968
969 NTSTATUS
970 AFSCommonRead( IN PDEVICE_OBJECT DeviceObject,
971                IN PIRP Irp,
972                IN HANDLE OnBehalfOf)
973 {
974
975     UNREFERENCED_PARAMETER(OnBehalfOf);
976     NTSTATUS            ntStatus = STATUS_SUCCESS;
977     AFSDeviceExt       *pDeviceExt;
978     IO_STACK_LOCATION  *pIrpSp;
979     AFSFcb             *pFcb = NULL;
980     AFSCcb             *pCcb = NULL;
981     BOOLEAN             bReleaseMain = FALSE;
982     BOOLEAN             bReleaseSectionObject = FALSE;
983     BOOLEAN             bReleasePaging = FALSE;
984     BOOLEAN             bPagingIo = FALSE;
985     BOOLEAN             bNonCachedIo = FALSE;
986     BOOLEAN             bCompleteIrp = TRUE;
987     PFILE_OBJECT        pFileObject = NULL;
988     LARGE_INTEGER       liStartingByte;
989     ULONG               ulByteCount;
990     AFSDeviceExt       *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
991
992     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
993     pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
994
995     __Enter
996     {
997         //
998         // Decode the fileobject
999         //
1000         pFileObject = pIrpSp->FileObject;
1001
1002         //
1003         // There is a risk (albeit infinitely small) that the Irp will
1004         // complete before this function exits, then a cleanup and
1005         // close will happen and the FCB will be torn down before we
1006         // get to the try_exit.  Pin the file Object which will pin the FCB
1007         //
1008
1009         ObReferenceObject( pFileObject);
1010
1011         //
1012         // If we are in shutdown mode then fail the request
1013         //
1014
1015         if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
1016         {
1017
1018             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019                           AFS_TRACE_LEVEL_WARNING,
1020                           "AFSCommonRead (%p) Open request after shutdown\n",
1021                           Irp));
1022
1023             try_return( ntStatus = STATUS_TOO_LATE);
1024         }
1025
1026         pFcb = (AFSFcb *)pFileObject->FsContext;
1027
1028         pCcb = (AFSCcb *)pFileObject->FsContext2;
1029
1030         if( pFcb == NULL)
1031         {
1032
1033             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1034                           AFS_TRACE_LEVEL_ERROR,
1035                           "AFSCommonRead Attempted read (%p) when pFcb == NULL\n",
1036                           Irp));
1037
1038             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
1039         }
1040
1041         bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
1042         bNonCachedIo = BooleanFlagOn( Irp->Flags,IRP_NOCACHE);
1043
1044         liStartingByte = pIrpSp->Parameters.Read.ByteOffset;
1045         ulByteCount = pIrpSp->Parameters.Read.Length;
1046
1047         if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
1048             pFcb->Header.NodeTypeCode != AFS_FILE_FCB &&
1049             pFcb->Header.NodeTypeCode != AFS_SPECIAL_SHARE_FCB)
1050         {
1051
1052             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1053                           AFS_TRACE_LEVEL_ERROR,
1054                           "AFSCommonRead Attempted read (%p) on an invalid node type %08lX\n",
1055                           Irp,
1056                           pFcb->Header.NodeTypeCode));
1057
1058             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
1059         }
1060
1061         //
1062         // If this is a read against an IOCtl node then handle it
1063         // in a different pathway
1064         //
1065
1066         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
1067         {
1068
1069             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1070                           AFS_TRACE_LEVEL_VERBOSE,
1071                           "AFSCommonRead (%p) Processing file (PIOCTL) Offset %I64X Length %08lX Irp Flags %08lX\n",
1072                           Irp,
1073                           liStartingByte.QuadPart,
1074                           ulByteCount,
1075                           Irp->Flags));
1076
1077             ntStatus = AFSIOCtlRead( DeviceObject,
1078                                      Irp);
1079
1080             try_return( ntStatus);
1081         }
1082         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
1083         {
1084
1085             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1086                           AFS_TRACE_LEVEL_VERBOSE,
1087                           "AFSCommonRead (%p) Processing file (SHARE) Offset %I64X Length %08lX Irp Flags %08lX\n",
1088                           Irp,
1089                           liStartingByte.QuadPart,
1090                           ulByteCount,
1091                           Irp->Flags));
1092
1093             ntStatus = AFSShareRead( DeviceObject,
1094                                      Irp);
1095
1096             try_return( ntStatus);
1097         }
1098
1099         //
1100         // No fileobject yet?  Bail.
1101         //
1102         if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
1103             !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_REDIR_INIT_PERFORM_SERVICE_IO) &&
1104             NULL == pDeviceExt->Specific.RDR.CacheFileObject)
1105         {
1106
1107             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1108                           AFS_TRACE_LEVEL_ERROR,
1109                           "AFSCommonRead (%p) Request failed due to AFS cache closed\n",
1110                           Irp));
1111
1112             try_return( ntStatus = STATUS_TOO_LATE );
1113         }
1114
1115         if( pIrpSp->Parameters.Read.Length == 0)
1116         {
1117
1118             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1119                           AFS_TRACE_LEVEL_VERBOSE,
1120                           "AFSCommonRead (%p) Request completed due to zero length\n",
1121                           Irp));
1122
1123             try_return( ntStatus);
1124         }
1125
1126         if ( FlagOn(pIrpSp->MinorFunction, IRP_MN_COMPLETE) )
1127         {
1128
1129             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1130                           AFS_TRACE_LEVEL_VERBOSE,
1131                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1132                           &pFcb->NPFcb->SectionObjectResource,
1133                           PsGetCurrentThread()));
1134
1135             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1136                               TRUE);
1137
1138             bReleaseSectionObject = TRUE;
1139
1140             __try
1141             {
1142
1143                 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1144                               AFS_TRACE_LEVEL_VERBOSE,
1145                               "AFSCommonRead (%p) IRP_MN_COMPLETE being processed\n",
1146                               Irp));
1147
1148                 CcMdlReadComplete(pIrpSp->FileObject, Irp->MdlAddress);
1149
1150                 //
1151                 // Mdl is now Deallocated
1152                 //
1153
1154                 Irp->MdlAddress = NULL;
1155
1156                 try_return( ntStatus = STATUS_SUCCESS );
1157             }
1158             __except( EXCEPTION_EXECUTE_HANDLER)
1159             {
1160
1161                 ntStatus = GetExceptionCode();
1162
1163                 AFSDbgTrace(( 0,
1164                               0,
1165                               "EXCEPTION - AFSCommonRead CcMdlReadComplete failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1166                               pFcb->ObjectInformation->FileId.Cell,
1167                               pFcb->ObjectInformation->FileId.Volume,
1168                               pFcb->ObjectInformation->FileId.Vnode,
1169                               pFcb->ObjectInformation->FileId.Unique,
1170                               ntStatus));
1171
1172                 try_return( ntStatus);
1173             }
1174         }
1175
1176         //
1177         // If we get a non cached IO for a cached file we should do a purge.
1178         // For now we will just promote to cached
1179         //
1180         if (NULL != pFileObject->SectionObjectPointer->DataSectionObject && !bPagingIo)
1181         {
1182
1183             bNonCachedIo = FALSE;
1184         }
1185
1186         //
1187         // We acquire the main/paging resource first to synchronize
1188         // against size checks.
1189         //
1190
1191         if( bPagingIo)
1192         {
1193
1194             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1195                           AFS_TRACE_LEVEL_VERBOSE,
1196                           "AFSCommonRead Acquiring Fcb PagingIo lock %p SHARED %08lX\n",
1197                           &pFcb->NPFcb->PagingResource,
1198                           PsGetCurrentThread()));
1199
1200             AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1201                               TRUE);
1202
1203             bReleasePaging = TRUE;
1204
1205             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1206                           AFS_TRACE_LEVEL_VERBOSE,
1207                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1208                           &pFcb->NPFcb->SectionObjectResource,
1209                           PsGetCurrentThread()));
1210
1211             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1212                               TRUE);
1213
1214             bReleaseSectionObject = TRUE;
1215
1216         }
1217         else
1218         {
1219
1220             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1221                           AFS_TRACE_LEVEL_VERBOSE,
1222                           "AFSCommonRead Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
1223                           &pFcb->NPFcb->SectionObjectResource,
1224                           PsGetCurrentThread()));
1225
1226             AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1227                               TRUE);
1228
1229             bReleaseSectionObject = TRUE;
1230
1231             //
1232             // Check the BR locks
1233             //
1234
1235             if( !FsRtlCheckLockForReadAccess( &pFcb->Specific.File.FileLock,
1236                                               Irp))
1237             {
1238
1239                 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1240                               AFS_TRACE_LEVEL_ERROR,
1241                               "AFSCommonRead (%p) Request failed due to lock conflict\n",
1242                               Irp));
1243
1244                 try_return( ntStatus = STATUS_FILE_LOCK_CONFLICT);
1245             }
1246         }
1247
1248         if( BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED) ||
1249             BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1250         {
1251
1252             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1253                           AFS_TRACE_LEVEL_ERROR,
1254                           "AFSCommonRead (%p) Request failed due to file deleted\n",
1255                           Irp));
1256
1257             try_return( ntStatus = STATUS_FILE_DELETED);
1258         }
1259
1260         //
1261         // If the read starts beyond End of File, return EOF.
1262         //
1263
1264         if( liStartingByte.QuadPart >= pFcb->Header.FileSize.QuadPart)
1265         {
1266
1267             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1268                           AFS_TRACE_LEVEL_VERBOSE,
1269                           "AFSCommonRead (%p) Request beyond EOF %I64X\n",
1270                           Irp,
1271                           pFcb->Header.FileSize.QuadPart));
1272
1273             try_return( ntStatus = STATUS_END_OF_FILE);
1274         }
1275
1276         //
1277         //
1278
1279         if( liStartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
1280         {
1281
1282             ulByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - liStartingByte.QuadPart);
1283
1284             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1285                           AFS_TRACE_LEVEL_VERBOSE,
1286                           "AFSCommonRead (%p) Truncated read request to %08lX\n",
1287                           Irp,
1288                           ulByteCount));
1289         }
1290
1291         //
1292         // Is this Fcb valid???
1293         //
1294
1295         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID))
1296         {
1297
1298             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1299                           AFS_TRACE_LEVEL_ERROR,
1300                           "AFSCommonRead (%p) Failing request due to INVALID fcb\n",
1301                           Irp));
1302
1303             Irp->IoStatus.Information = 0;
1304
1305             try_return( ntStatus = STATUS_FILE_DELETED);
1306         }
1307
1308         //
1309         // If this is an cached IO
1310         //
1311         if( (!bPagingIo && !bNonCachedIo))
1312         {
1313             //
1314             // This is a top level irp. Init the caching if it has not yet
1315             // been initialzed for this FO
1316             //
1317
1318             if( pFileObject->PrivateCacheMap == NULL)
1319             {
1320
1321                 __try
1322                 {
1323
1324                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1325                                   AFS_TRACE_LEVEL_VERBOSE,
1326                                   "AFSCommonRead Initialize caching on Fcb %p FO %p\n",
1327                                   pFcb,
1328                                   pFileObject));
1329
1330                     CcInitializeCacheMap( pFileObject,
1331                                           (PCC_FILE_SIZES)&pFcb->Header.AllocationSize,
1332                                           FALSE,
1333                                           AFSLibCacheManagerCallbacks,
1334                                           pFcb);
1335
1336                     CcSetReadAheadGranularity( pFileObject,
1337                                                pDeviceExt->Specific.RDR.MaximumRPCLength);
1338
1339                     CcSetDirtyPageThreshold( pFileObject,
1340                                              AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength / 4096);
1341                 }
1342                 __except( EXCEPTION_EXECUTE_HANDLER)
1343                 {
1344
1345                     ntStatus = GetExceptionCode();
1346
1347                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1348                                   AFS_TRACE_LEVEL_ERROR,
1349                                   "AFSCommonRead (%p) Exception thrown while initializing cache map Status %08lX\n",
1350                                   Irp,
1351                                   ntStatus));
1352                 }
1353
1354                 if( !NT_SUCCESS( ntStatus))
1355                 {
1356
1357                     try_return( ntStatus);
1358                 }
1359             }
1360
1361             //
1362             // And if this is MDL operation, deal with it now (yes we
1363             // could post, but we are almost certainly posted
1364             // already and we don't want to grow and SVA for it..)
1365             //
1366
1367             if( BooleanFlagOn( pIrpSp->MinorFunction, IRP_MN_MDL))
1368             {
1369                 __try
1370                 {
1371
1372                     CcMdlRead( pFileObject,
1373                                &liStartingByte,
1374                                ulByteCount,
1375                                &Irp->MdlAddress,
1376                                &Irp->IoStatus);
1377
1378                     ntStatus = Irp->IoStatus.Status;
1379                 }
1380                 __except( EXCEPTION_EXECUTE_HANDLER)
1381                 {
1382                     ntStatus = GetExceptionCode();
1383
1384                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1385                                   AFS_TRACE_LEVEL_ERROR,
1386                                   "AFSCommonRead (%p) Exception thrown during mdl read Status %08lX\n",
1387                                   Irp,
1388                                   ntStatus));
1389                 }
1390
1391                 if( !NT_SUCCESS( ntStatus))
1392                 {
1393
1394                     AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1395                                   AFS_TRACE_LEVEL_ERROR,
1396                                   "AFSCommonRead (%p) Failed to process MDL read Status %08lX\n",
1397                                   Irp,
1398                                   ntStatus));
1399
1400                     if( Irp->IoStatus.Information > 0)
1401                     {
1402
1403                         CcMdlReadComplete(pFileObject, Irp->MdlAddress);
1404
1405                         //
1406                         // Mdl is now Deallocated
1407                         //
1408
1409                         Irp->MdlAddress = NULL;
1410                     }
1411
1412                     try_return( ntStatus);
1413                 }
1414
1415                 //
1416                 // Update the CBO if this is a sync read
1417                 //
1418
1419                 if( BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
1420                 {
1421
1422                     pFileObject->CurrentByteOffset.QuadPart = liStartingByte.QuadPart + ulByteCount;
1423                 }
1424
1425                 try_return( ntStatus);
1426             }
1427         }
1428
1429         //
1430         // The called request completes the IRP for us.
1431         //
1432
1433         bCompleteIrp = FALSE;
1434
1435         if( !bPagingIo &&
1436             !bNonCachedIo)
1437         {
1438
1439             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1440                           AFS_TRACE_LEVEL_VERBOSE,
1441                           "AFSCommonRead (%p) Processing CACHED request Offset %I64X Len %08lX\n",
1442                           Irp,
1443                           liStartingByte.QuadPart,
1444                           ulByteCount));
1445
1446             ntStatus = AFSCachedRead( DeviceObject, Irp, liStartingByte, ulByteCount);
1447         }
1448         else
1449         {
1450
1451             if( bReleasePaging)
1452             {
1453
1454                 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1455
1456                 bReleasePaging = FALSE;
1457             }
1458
1459             if( bReleaseSectionObject)
1460             {
1461
1462                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1463                               AFS_TRACE_LEVEL_VERBOSE,
1464                               "AFSCommonRead Releasing Fcb SectionObject lock %p SHARED %08lX\n",
1465                               &pFcb->NPFcb->SectionObjectResource,
1466                               PsGetCurrentThread()));
1467
1468                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1469
1470                 bReleaseSectionObject = FALSE;
1471             }
1472
1473             if( bReleaseMain)
1474             {
1475
1476                 AFSReleaseResource( &pFcb->NPFcb->Resource);
1477
1478                 bReleaseMain = FALSE;
1479             }
1480
1481             AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1482                           AFS_TRACE_LEVEL_VERBOSE,
1483                           "AFSCommonRead (%p) Processing NON-CACHED request Offset %I64X Len %08lX\n",
1484                           Irp,
1485                           liStartingByte.QuadPart,
1486                           ulByteCount));
1487
1488             if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
1489             {
1490
1491                 ntStatus = AFSNonCachedReadDirect( DeviceObject, Irp,  liStartingByte);
1492             }
1493             else
1494             {
1495                 ntStatus = AFSNonCachedRead( DeviceObject, Irp,  liStartingByte);
1496             }
1497         }
1498
1499 try_exit:
1500
1501         AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1502                       AFS_TRACE_LEVEL_VERBOSE,
1503                       "AFSCommonRead (%p) Process complete Status %08lX\n",
1504                       Irp,
1505                       ntStatus));
1506
1507         if( bReleasePaging)
1508         {
1509
1510             AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1511         }
1512
1513         if( bReleaseSectionObject)
1514         {
1515
1516             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1517                           AFS_TRACE_LEVEL_VERBOSE,
1518                           "AFSCommonRead (exit) Releasing Fcb SectionObject lock %p SHARED %08lX\n",
1519                           &pFcb->NPFcb->SectionObjectResource,
1520                           PsGetCurrentThread()));
1521
1522             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1523         }
1524
1525         if( bReleaseMain)
1526         {
1527
1528             AFSReleaseResource( &pFcb->NPFcb->Resource);
1529         }
1530
1531         if( bCompleteIrp)
1532         {
1533
1534             AFSCompleteRequest( Irp, ntStatus);
1535         }
1536
1537         ObDereferenceObject( pFileObject);
1538     }
1539
1540     return ntStatus;
1541 }
1542
1543 NTSTATUS
1544 AFSIOCtlRead( IN PDEVICE_OBJECT DeviceObject,
1545               IN PIRP Irp)
1546 {
1547
1548     UNREFERENCED_PARAMETER(DeviceObject);
1549     NTSTATUS ntStatus = STATUS_SUCCESS;
1550     AFSPIOCtlIORequestCB stIORequestCB;
1551     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1552     AFSFcb *pFcb = NULL;
1553     AFSCcb *pCcb = NULL;
1554     AFSPIOCtlIOResultCB stIOResultCB;
1555     ULONG ulBytesReturned = 0;
1556     AFSFileID   stParentFID;
1557
1558     __Enter
1559     {
1560
1561         RtlZeroMemory( &stIORequestCB,
1562                        sizeof( AFSPIOCtlIORequestCB));
1563
1564         if( pIrpSp->Parameters.Read.Length == 0)
1565         {
1566
1567             //
1568             // Nothing to do in this case
1569             //
1570
1571             try_return( ntStatus);
1572         }
1573
1574         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1575
1576         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1577
1578         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1579                       AFS_TRACE_LEVEL_VERBOSE,
1580                       "AFSIOCtlRead Acquiring Fcb lock %p SHARED %08lX\n",
1581                       &pFcb->NPFcb->Resource,
1582                       PsGetCurrentThread()));
1583
1584         AFSAcquireShared( &pFcb->NPFcb->Resource,
1585                           TRUE);
1586
1587         //
1588         // Get the parent fid to pass to the cm
1589         //
1590
1591         RtlZeroMemory( &stParentFID,
1592                        sizeof( AFSFileID));
1593
1594         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1595         {
1596
1597             //
1598             // The parent directory FID of the node
1599             //
1600
1601             stParentFID = pFcb->ObjectInformation->ParentFileId;
1602         }
1603
1604         //
1605         // Set the control block up
1606         //
1607
1608         stIORequestCB.RequestId = pCcb->RequestID;
1609
1610         if( pFcb->ObjectInformation->VolumeCB != NULL)
1611         {
1612             stIORequestCB.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1613         }
1614
1615         //
1616         // Lock down the buffer
1617         //
1618
1619         stIORequestCB.MappedBuffer = AFSMapToService( Irp,
1620                                                       pIrpSp->Parameters.Read.Length);
1621
1622         if( stIORequestCB.MappedBuffer == NULL)
1623         {
1624
1625             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1626         }
1627
1628         stIORequestCB.BufferLength = pIrpSp->Parameters.Read.Length;
1629
1630         stIOResultCB.BytesProcessed = 0;
1631
1632         ulBytesReturned = sizeof( AFSPIOCtlIOResultCB);
1633
1634         //
1635         // Issue the request to the service
1636         //
1637
1638         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_READ,
1639                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1640                                       &pCcb->AuthGroup,
1641                                       NULL,
1642                                       &stParentFID,
1643                                       NULL,
1644                                       0,
1645                                       (void *)&stIORequestCB,
1646                                       sizeof( AFSPIOCtlIORequestCB),
1647                                       &stIOResultCB,
1648                                       &ulBytesReturned);
1649
1650         if( !NT_SUCCESS( ntStatus))
1651         {
1652
1653             try_return( ntStatus);
1654         }
1655
1656         //
1657         // Update the length read
1658         //
1659
1660         Irp->IoStatus.Information = stIOResultCB.BytesProcessed;
1661
1662 try_exit:
1663
1664         if( stIORequestCB.MappedBuffer != NULL)
1665         {
1666
1667             AFSUnmapServiceMappedBuffer( stIORequestCB.MappedBuffer,
1668                                          Irp->MdlAddress);
1669         }
1670
1671         if( pFcb != NULL)
1672         {
1673
1674             AFSReleaseResource( &pFcb->NPFcb->Resource);
1675         }
1676     }
1677
1678     return ntStatus;
1679 }
1680
1681 NTSTATUS
1682 AFSShareRead( IN PDEVICE_OBJECT DeviceObject,
1683               IN PIRP Irp)
1684 {
1685
1686     UNREFERENCED_PARAMETER(DeviceObject);
1687     NTSTATUS ntStatus = STATUS_SUCCESS;
1688     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1689     AFSFcb *pFcb = NULL;
1690     AFSCcb *pCcb = NULL;
1691     ULONG ulBytesReturned = 0;
1692     void *pBuffer = NULL;
1693     AFSPipeIORequestCB stIoRequest;
1694
1695     __Enter
1696     {
1697
1698         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1699
1700         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1701
1702         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
1703                       AFS_TRACE_LEVEL_VERBOSE,
1704                       "AFSShareRead On pipe %wZ Length %08lX\n",
1705                       &pCcb->DirectoryCB->NameInformation.FileName,
1706                       pIrpSp->Parameters.Read.Length));
1707
1708         if( pIrpSp->Parameters.Read.Length == 0)
1709         {
1710
1711             //
1712             // Nothing to do in this case
1713             //
1714
1715             try_return( ntStatus);
1716         }
1717
1718         AFSAcquireShared( &pFcb->NPFcb->Resource,
1719                           TRUE);
1720
1721         //
1722         // Retrieve the buffer for the read request
1723         //
1724
1725         pBuffer = AFSLockSystemBuffer( Irp,
1726                                        pIrpSp->Parameters.Read.Length);
1727
1728         if( pBuffer == NULL)
1729         {
1730
1731             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
1732                           AFS_TRACE_LEVEL_ERROR,
1733                           "AFSShareRead Failed to map buffer on pipe %wZ\n",
1734                           &pCcb->DirectoryCB->NameInformation.FileName));
1735
1736             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1737         }
1738
1739         RtlZeroMemory( &stIoRequest,
1740                        sizeof( AFSPipeIORequestCB));
1741
1742         stIoRequest.RequestId = pCcb->RequestID;
1743
1744         stIoRequest.RootId = pFcb->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1745
1746         stIoRequest.BufferLength = pIrpSp->Parameters.Read.Length;
1747
1748         ulBytesReturned = pIrpSp->Parameters.Read.Length;
1749
1750         //
1751         // Issue the open request to the service
1752         //
1753
1754         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_READ,
1755                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1756                                       &pCcb->AuthGroup,
1757                                       &pCcb->DirectoryCB->NameInformation.FileName,
1758                                       NULL,
1759                                       NULL,
1760                                       0,
1761                                       (void *)&stIoRequest,
1762                                       sizeof( AFSPipeIORequestCB),
1763                                       pBuffer,
1764                                       &ulBytesReturned);
1765
1766         if( !NT_SUCCESS( ntStatus) &&
1767             ntStatus != STATUS_BUFFER_OVERFLOW)
1768         {
1769
1770             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1771                           AFS_TRACE_LEVEL_ERROR,
1772                           "AFSShareRead (%p) Failed service read Status %08lX\n",
1773                           Irp,
1774                           ntStatus));
1775
1776             try_return( ntStatus);
1777         }
1778
1779         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
1780                       AFS_TRACE_LEVEL_VERBOSE,
1781                       "AFSShareRead Completed on pipe %wZ Length read %08lX Status %08lX\n",
1782                       &pCcb->DirectoryCB->NameInformation.FileName,
1783                       ulBytesReturned,
1784                       ntStatus));
1785
1786         Irp->IoStatus.Information = ulBytesReturned;
1787
1788 try_exit:
1789
1790         if( pFcb != NULL)
1791         {
1792
1793             AFSReleaseResource( &pFcb->NPFcb->Resource);
1794         }
1795     }
1796
1797     return ntStatus;
1798 }