ReactOS 0.4.15-dev-8021-g7ce96fd
fspdisp.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 FspDisp.c
8
9Abstract:
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
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
39VOID
43 )
44
45/*++
46
47Routine 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
54Arguments:
55
56
57 Context - Supplies the thread id.
58
59Return 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
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,
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
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,
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
451PVOID
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
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_CONTEXT_FLAG_IN_FSP
Definition: cdstruc.h:1219
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
IRP_CONTEXT * PIRP_CONTEXT
Definition: cdstruc.h:1211
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS FatCommonQueryEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:250
NTSTATUS FatCommonSetEa(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: ea.c:659
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
PVOID FatRemoveOverflowEntry(IN PVOLUME_DEVICE_OBJECT VolDo)
Definition: fspdisp.c:452
#define Dbg
Definition: fspdisp.c:32
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
WORKER_THREAD_ROUTINE FatFspDispatch
Definition: fatprocs.h:2380
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1566
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
Status
Definition: gdiplustypes.h:25
#define _In_
Definition: ms_sal.h:308
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:83
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
Definition: cdstruc.h:498
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#define IRP_MJ_QUERY_EA
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MJ_SET_EA
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
#define NT_ASSERT
Definition: rtlfuncs.h:3310
unsigned char UCHAR
Definition: xmlstorage.h:181