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