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