ReactOS  0.4.13-dev-39-g8b6696f
fspdisp.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  FspDisp.c
8 
9 Abstract:
10 
11  This module implements the main dispatch procedure/thread for the Fat
12  Fsp
13 
14 
15 --*/
16 
17 #include "fatprocs.h"
18 
19 //
20 // Internal support routine, spinlock wrapper.
21 //
22 
23 PVOID
26  );
27 
28 //
29 // Define our local debug trace level
30 //
31 
32 #define Dbg (DEBUG_TRACE_FSP_DISPATCHER)
33 
34 #ifdef ALLOC_PRAGMA
35 #pragma alloc_text(PAGE, FatFspDispatch)
36 #endif
37 
38 
39 VOID
40 NTAPI
43  )
44 
45 /*++
46 
47 Routine Description:
48 
49  This is the main FSP thread routine that is executed to receive
50  and dispatch IRP requests. Each FSP thread begins its execution here.
51  There is one thread created at system initialization time and subsequent
52  threads created as needed.
53 
54 Arguments:
55 
56 
57  Context - Supplies the thread id.
58 
59 Return Value:
60 
61  None - This routine never exits
62 
63 --*/
64 
65 {
67 
68 
69  PIRP Irp;
70  PIRP_CONTEXT IrpContext;
72  BOOLEAN VcbDeleted;
73  BOOLEAN ExceptionCompletedIrp = FALSE;
74 
76 
77  UCHAR MajorFunction = 0;
78 
79  PAGED_CODE();
80 
81  IrpContext = (PIRP_CONTEXT)Context;
82 
83  Irp = IrpContext->OriginatingIrp;
84 
86 
87  //
88  // Now because we are the Fsp we will force the IrpContext to
89  // indicate true on Wait.
90  //
91 
93 
94  //
95  // If this request has an associated volume device object, remember it.
96  //
97 
98  if ( IrpSp->FileObject != NULL ) {
99 
102  DeviceObject );
103  } else {
104 
105  VolDo = NULL;
106  }
107 
108  //
109  // Now case on the function code. For each major function code,
110  // either call the appropriate FSP routine or case on the minor
111  // function and then call the FSP routine. The FSP routine that
112  // we call is responsible for completing the IRP, and not us.
113  // That way the routine can complete the IRP and then continue
114  // post processing as required. For example, a read can be
115  // satisfied right away and then read can be done.
116  //
117  // We'll do all of the work within an exception handler that
118  // will be invoked if ever some underlying operation gets into
119  // trouble (e.g., if FatReadSectorsSync has trouble).
120  //
121 
122  while ( TRUE ) {
123 
124  ExceptionCompletedIrp = FALSE;
125 
126  DebugTrace(0, Dbg, "FatFspDispatch: Irp = %p\n", Irp);
127 
128  //
129  // If this Irp was top level, note it in our thread local storage.
130  //
131 
133 
134  if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) ) {
135 
137 
138  } else {
139 
141  }
142 
143  MajorFunction = IrpContext->MajorFunction;
144 
145  _SEH2_TRY {
146 
147  switch ( MajorFunction ) {
148 
149  //
150  // For Create Operation,
151  //
152 
153  case IRP_MJ_CREATE:
154 
155  Status = FatCommonCreate( IrpContext, Irp );
156  break;
157 
158  //
159  // For close operations. We do a little kludge here in case
160  // this close causes a volume to go away. It will NULL the
161  // VolDo local variable so that we will not try to look at
162  // the overflow queue.
163  //
164 
165  case IRP_MJ_CLOSE:
166 
167  {
168  PVCB Vcb;
169  PFCB Fcb;
170  PCCB Ccb;
172 
173  //
174  // Extract and decode the file object
175  //
176 
178 
179  //
180  // Do the close. We have a slightly different format
181  // for this call because of the async closes.
182  //
183 
184  Status = FatCommonClose( Vcb,
185  Fcb,
186  Ccb,
187  TypeOfOpen,
188  TRUE,
189  TRUE,
190  &VcbDeleted );
191 
192  //
193  // If the VCB was deleted, do not try to access it later.
194  //
195 
196  if (VcbDeleted) {
197 
198  VolDo = NULL;
199  }
200 
202 
203  FatCompleteRequest( IrpContext, Irp, Status );
204 
205  break;
206  }
207 
208  //
209  // For read operations
210  //
211 
212  case IRP_MJ_READ:
213 
214  (VOID) FatCommonRead( IrpContext, Irp );
215  break;
216 
217  //
218  // For write operations,
219  //
220 
221  case IRP_MJ_WRITE:
222 
223  (VOID) FatCommonWrite( IrpContext, Irp );
224  break;
225 
226  //
227  // For Query Information operations,
228  //
229 
231 
232  (VOID) FatCommonQueryInformation( IrpContext, Irp );
233  break;
234 
235  //
236  // For Set Information operations,
237  //
238 
240 
241  (VOID) FatCommonSetInformation( IrpContext, Irp );
242  break;
243 
244  //
245  // For Query EA operations,
246  //
247 
248  case IRP_MJ_QUERY_EA:
249 
250  (VOID) FatCommonQueryEa( IrpContext, Irp );
251  break;
252 
253  //
254  // For Set EA operations,
255  //
256 
257  case IRP_MJ_SET_EA:
258 
259  (VOID) FatCommonSetEa( IrpContext, Irp );
260  break;
261 
262  //
263  // For Flush buffers operations,
264  //
265 
267 
268  (VOID) FatCommonFlushBuffers( IrpContext, Irp );
269  break;
270 
271  //
272  // For Query Volume Information operations,
273  //
274 
276 
277  (VOID) FatCommonQueryVolumeInfo( IrpContext, Irp );
278  break;
279 
280  //
281  // For Set Volume Information operations,
282  //
283 
285 
286  (VOID) FatCommonSetVolumeInfo( IrpContext, Irp );
287  break;
288 
289  //
290  // For File Cleanup operations,
291  //
292 
293  case IRP_MJ_CLEANUP:
294 
295  (VOID) FatCommonCleanup( IrpContext, Irp );
296  break;
297 
298  //
299  // For Directory Control operations,
300  //
301 
303 
304  (VOID) FatCommonDirectoryControl( IrpContext, Irp );
305  break;
306 
307  //
308  // For File System Control operations,
309  //
310 
312 
313  (VOID) FatCommonFileSystemControl( IrpContext, Irp );
314  break;
315 
316  //
317  // For Lock Control operations,
318  //
319 
320  case IRP_MJ_LOCK_CONTROL:
321 
322  (VOID) FatCommonLockControl( IrpContext, Irp );
323  break;
324 
325  //
326  // For Device Control operations,
327  //
328 
330 
331  (VOID) FatCommonDeviceControl( IrpContext, Irp );
332  break;
333 
334  //
335  // For the Shutdown operation,
336  //
337 
338  case IRP_MJ_SHUTDOWN:
339 
340  (VOID) FatCommonShutdown( IrpContext, Irp );
341  break;
342 
343  //
344  // For plug and play operations.
345  //
346 
347  case IRP_MJ_PNP:
348 
349  //
350  // I don't believe this should ever occur, but allow for the unexpected.
351  //
352 
353  (VOID) FatCommonPnp( IrpContext, Irp );
354  break;
355 
356  //
357  // For any other major operations, return an invalid
358  // request.
359  //
360 
361  default:
362 
364  break;
365 
366  }
367 
369 
370  //
371  // We had some trouble trying to perform the requested
372  // operation, so we'll abort the I/O request with
373  // the error status that we get back from the
374  // execption code.
375  //
376 
377  (VOID) FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
378  ExceptionCompletedIrp = TRUE;
379  } _SEH2_END;
380 
382 
384 
385 
386  if (MajorFunction == IRP_MJ_CREATE && !ExceptionCompletedIrp && Status != STATUS_PENDING) {
387 
388  //
389  // Creates are completed here. IrpContext is also freed here.
390  //
391 
392  FatCompleteRequest( IrpContext, Irp, Status );
393  }
394 
395  //
396  // If there are any entries on this volume's overflow queue, service
397  // them.
398  //
399 
400  if ( VolDo != NULL ) {
401 
402  PVOID Entry;
403 
404  //
405  // We have a volume device object so see if there is any work
406  // left to do in its overflow queue.
407  //
408 
409  Entry = FatRemoveOverflowEntry( VolDo );
410 
411  //
412  // There wasn't an entry, break out of the loop and return to
413  // the Ex Worker thread.
414  //
415 
416  if ( Entry == NULL ) {
417 
418  break;
419  }
420 
421  //
422  // Extract the IrpContext, Irp, and IrpSp, and loop.
423  //
424 
425  IrpContext = CONTAINING_RECORD( Entry,
426  IRP_CONTEXT,
427  WorkQueueItem.List );
428 
430 
431  Irp = IrpContext->OriginatingIrp;
432 
434 
435  continue;
436 
437  } else {
438 
439  break;
440  }
441  }
442 
443  return;
444 }
445 
446 
447 //
448 // Internal support routine, spinlock wrapper.
449 //
450 
451 PVOID
454  )
455 {
456  PVOID Entry;
457  KIRQL SavedIrql;
458 
459  KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql );
460 
461  if (VolDo->OverflowQueueCount > 0) {
462 
463  //
464  // There is overflow work to do in this volume so we'll
465  // decrement the Overflow count, dequeue the IRP, and release
466  // the Event
467  //
468 
469  VolDo->OverflowQueueCount -= 1;
470 
471  Entry = RemoveHeadList( &VolDo->OverflowQueue );
472 
473  } else {
474 
475  VolDo->PostedRequestCount -= 1;
476 
477  Entry = NULL;
478  }
479 
480  KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );
481 
482  return Entry;
483 }
484 
485 
#define Dbg
Definition: fspdisp.c:32
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FsRtlEnterFileSystem
#define IRP_MJ_FLUSH_BUFFERS
struct _Entry Entry
Definition: kefuncs.h:640
#define FsRtlExitFileSystem
IRP_CONTEXT * PIRP_CONTEXT
Definition: cdstruc.h:1217
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
Definition: cdstruc.h:1073
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define IRP_MJ_SET_VOLUME_INFORMATION
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
Definition: cdstruc.h:504
PVOID FatRemoveOverflowEntry(IN PVOLUME_DEVICE_OBJECT VolDo)
Definition: fspdisp.c:452
#define PAGED_CODE()
Definition: video.h:57
NTSTATUS FatCommonSetEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:659
_SEH2_TRY
Definition: create.c:4250
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IRP_MJ_SET_EA
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
NTSTATUS FatCommonQueryEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:250
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
VOID NTAPI FatFspDispatch(_In_ PVOID Context)
Definition: fspdisp.c:41
#define IRP_CONTEXT_FLAG_IN_FSP
Definition: cdstruc.h:1225
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define IRP_MJ_QUERY_EA
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define Vcb
Definition: cdprocs.h:1425
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define VOID
Definition: acefi.h:82
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1558
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2725
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
base of all file and directory entries
Definition: entries.h:82
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define NT_ASSERT
Definition: rtlfuncs.h:3312