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