00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "UdfProcs.h"
00023
00024
00025
00026
00027
00028 #define BugCheckFileId (UDFS_BUG_CHECK_WORKQUE)
00029
00030
00031
00032
00033
00034 #define Dbg (UDFS_DEBUG_LEVEL_WORKQUE)
00035
00036
00037
00038
00039
00040
00041 #define FSP_PER_DEVICE_THRESHOLD (2)
00042
00043
00044
00045
00046
00047
VOID
00048
UdfAddToWorkque (
00049 IN
PIRP_CONTEXT IrpContext,
00050 IN
PIRP Irp
00051 );
00052
00053
#ifdef ALLOC_PRAGMA
00054
#pragma alloc_text(PAGE, UdfFsdPostRequest)
00055
#pragma alloc_text(PAGE, UdfOplockComplete)
00056
#pragma alloc_text(PAGE, UdfPrePostIrp)
00057
#endif
00058
00059
00060
NTSTATUS
00061 UdfFsdPostRequest (
00062 IN
PIRP_CONTEXT IrpContext,
00063 IN
PIRP Irp
00064 )
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 {
00087
PAGED_CODE();
00088
00089
ASSERT_IRP_CONTEXT( IrpContext );
00090
ASSERT_IRP(
Irp );
00091
00092
00093
00094
00095
00096
00097
00098
UdfPrePostIrp( IrpContext,
Irp );
00099
00100
UdfAddToWorkque( IrpContext,
Irp );
00101
00102
00103
00104
00105
00106
return STATUS_PENDING;
00107 }
00108
00109
00110
VOID
00111 UdfPrePostIrp (
00112 IN
PIRP_CONTEXT IrpContext,
00113 IN
PIRP Irp
00114 )
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 {
00137
PIO_STACK_LOCATION IrpSp =
IoGetCurrentIrpStackLocation(
Irp );
00138 BOOLEAN RemovedFcb;
00139
00140
PAGED_CODE();
00141
00142
ASSERT_IRP_CONTEXT( IrpContext );
00143
ASSERT_IRP(
Irp );
00144
00145
00146
00147
00148
00149
switch (IrpContext->MajorFunction) {
00150
00151
case IRP_MJ_CREATE :
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
if ((IrpContext->TeardownFcb !=
NULL) &&
00162 *(IrpContext->TeardownFcb) !=
NULL) {
00163
00164
UdfTeardownStructures( IrpContext, *(IrpContext->TeardownFcb),
FALSE, &RemovedFcb );
00165
00166
if (!RemovedFcb) {
00167
00168
UdfReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
00169 }
00170
00171 *(IrpContext->TeardownFcb) =
NULL;
00172 IrpContext->TeardownFcb =
NULL;
00173 }
00174
00175
break;
00176
00177
00178
00179
00180
00181
00182
case IRP_MJ_READ :
00183
00184
if (!
FlagOn( IrpContext->MinorFunction,
IRP_MN_MDL )) {
00185
00186
UdfLockUserBuffer( IrpContext, IrpSp->
Parameters.Read.Length );
00187 }
00188
00189
break;
00190
00191
00192
00193
00194
00195
case IRP_MJ_DIRECTORY_CONTROL :
00196
00197
if (IrpContext->MinorFunction ==
IRP_MN_QUERY_DIRECTORY) {
00198
00199
UdfLockUserBuffer( IrpContext, IrpSp->
Parameters.QueryDirectory.Length );
00200 }
00201
00202
break;
00203 }
00204
00205
00206
00207
00208
SetFlag( IrpContext->Flags,
IRP_CONTEXT_FLAG_MORE_PROCESSING );
00209
UdfCleanupIrpContext( IrpContext,
TRUE );
00210
00211
00212
00213
00214
00215
IoMarkIrpPending(
Irp );
00216
00217
return;
00218 }
00219
00220
00221
VOID
00222 UdfOplockComplete (
00223 IN
PIRP_CONTEXT IrpContext,
00224 IN
PIRP Irp
00225 )
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 {
00250 BOOLEAN RemovedFcb;
00251
00252
PAGED_CODE();
00253
00254
00255
00256
00257
00258
00259
if (
Irp->
IoStatus.Status == STATUS_SUCCESS) {
00260
00261
00262
00263
00264
00265
switch (IrpContext->MajorFunction) {
00266
00267
case IRP_MJ_CREATE :
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
if (IrpContext->TeardownFcb !=
NULL) {
00278
00279
UdfTeardownStructures( IrpContext, *(IrpContext->TeardownFcb),
FALSE, &RemovedFcb );
00280
00281
if (!RemovedFcb) {
00282
00283
UdfReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
00284 }
00285
00286 *(IrpContext->TeardownFcb) =
NULL;
00287 IrpContext->TeardownFcb =
NULL;
00288 }
00289
00290
break;
00291 }
00292
00293
00294
00295
00296
UdfAddToWorkque( IrpContext,
Irp );
00297
00298
00299
00300
00301
00302 }
else {
00303
00304
UdfCompleteRequest( IrpContext,
Irp,
Irp->
IoStatus.Status );
00305 }
00306
00307
return;
00308 }
00309
00310
00311
00312
00313
00314
00315
VOID
00316 UdfAddToWorkque (
00317 IN
PIRP_CONTEXT IrpContext,
00318 IN
PIRP Irp
00319 )
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 {
00341
PVOLUME_DEVICE_OBJECT Vdo;
00342 KIRQL SavedIrql;
00343
PIO_STACK_LOCATION IrpSp =
IoGetCurrentIrpStackLocation(
Irp );
00344
00345
00346
00347
00348
00349
00350
if (IrpSp->
FileObject !=
NULL) {
00351
00352
00353 Vdo = CONTAINING_RECORD( IrpSp->
DeviceObject,
00354
VOLUME_DEVICE_OBJECT,
00355 DeviceObject );
00356
00357
00358
00359
00360
00361
00362
KeAcquireSpinLock( &Vdo->
OverflowQueueSpinLock, &SavedIrql );
00363
00364
if (Vdo->
PostedRequestCount >
FSP_PER_DEVICE_THRESHOLD) {
00365
00366
00367
00368
00369
00370
00371 InsertTailList( &Vdo->
OverflowQueue,
00372 &IrpContext->WorkQueueItem.List );
00373
00374 Vdo->
OverflowQueueCount += 1;
00375
00376
KeReleaseSpinLock( &Vdo->
OverflowQueueSpinLock, SavedIrql );
00377
00378
return;
00379
00380 }
else {
00381
00382
00383
00384
00385
00386
00387 Vdo->
PostedRequestCount += 1;
00388
00389
KeReleaseSpinLock( &Vdo->
OverflowQueueSpinLock, SavedIrql );
00390 }
00391 }
00392
00393
00394
00395
00396
00397
ExInitializeWorkItem( &IrpContext->WorkQueueItem,
00398
UdfFspDispatch,
00399 IrpContext );
00400
00401
ExQueueWorkItem( &IrpContext->WorkQueueItem,
CriticalWorkQueue );
00402
00403
return;
00404 }
00405
00406