Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

workque.c File Reference

#include "UdfProcs.h"

Go to the source code of this file.

Defines

#define BugCheckFileId   (UDFS_BUG_CHECK_WORKQUE)
#define Dbg   (UDFS_DEBUG_LEVEL_WORKQUE)
#define FSP_PER_DEVICE_THRESHOLD   (2)

Functions

VOID UdfAddToWorkque (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfFsdPostRequest (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
VOID UdfPrePostIrp (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
VOID UdfOplockComplete (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)


Define Documentation

#define BugCheckFileId   (UDFS_BUG_CHECK_WORKQUE)
 

Definition at line 28 of file workque.c.

#define Dbg   (UDFS_DEBUG_LEVEL_WORKQUE)
 

Definition at line 34 of file workque.c.

#define FSP_PER_DEVICE_THRESHOLD   (2)
 

Definition at line 41 of file workque.c.

Referenced by UdfAddToWorkque().


Function Documentation

VOID UdfAddToWorkque IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 316 of file workque.c.

References CriticalWorkQueue, _IO_STACK_LOCATION::DeviceObject, ExInitializeWorkItem, ExQueueWorkItem(), _IO_STACK_LOCATION::FileObject, FSP_PER_DEVICE_THRESHOLD, IoGetCurrentIrpStackLocation, Irp, KeAcquireSpinLock, KeReleaseSpinLock(), NULL, _VOLUME_DEVICE_OBJECT::OverflowQueue, _VOLUME_DEVICE_OBJECT::OverflowQueueCount, _VOLUME_DEVICE_OBJECT::OverflowQueueSpinLock, _VOLUME_DEVICE_OBJECT::PostedRequestCount, and UdfFspDispatch().

Referenced by UdfFsdPostRequest(), and UdfOplockComplete().

00323 : 00324 00325 This routine is called to acually store the posted Irp to the Fsp 00326 workque. 00327 00328 Arguments: 00329 00330 IrpContext - Pointer to the IrpContext to be queued to the Fsp 00331 00332 Irp - I/O Request Packet. 00333 00334 Return Value: 00335 00336 None. 00337 00338 --*/ 00339 00340 { 00341 PVOLUME_DEVICE_OBJECT Vdo; 00342 KIRQL SavedIrql; 00343 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00344 00345 // 00346 // Check if this request has an associated file object, and thus volume 00347 // device object. 00348 // 00349 00350 if (IrpSp->FileObject != NULL) { 00351 00352 00353 Vdo = CONTAINING_RECORD( IrpSp->DeviceObject, 00354 VOLUME_DEVICE_OBJECT, 00355 DeviceObject ); 00356 00357 // 00358 // Check to see if this request should be sent to the overflow 00359 // queue. If not, then send it off to an exworker thread. 00360 // 00361 00362 KeAcquireSpinLock( &Vdo->OverflowQueueSpinLock, &SavedIrql ); 00363 00364 if (Vdo->PostedRequestCount > FSP_PER_DEVICE_THRESHOLD) { 00365 00366 // 00367 // We cannot currently respond to this IRP so we'll just enqueue it 00368 // to the overflow queue on the volume. 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 // We are going to send this Irp to an ex worker thread so up 00384 // the count. 00385 // 00386 00387 Vdo->PostedRequestCount += 1; 00388 00389 KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql ); 00390 } 00391 } 00392 00393 // 00394 // Send it off..... 00395 // 00396 00397 ExInitializeWorkItem( &IrpContext->WorkQueueItem, 00398 UdfFspDispatch, 00399 IrpContext ); 00400 00401 ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue ); 00402 00403 return; 00404 }

NTSTATUS UdfFsdPostRequest IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 61 of file workque.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, Irp, PAGED_CODE, UdfAddToWorkque(), and UdfPrePostIrp().

Referenced by UdfCommonRead(), UdfPerformVerify(), and UdfProcessException().

00068 : 00069 00070 This routine enqueues the request packet specified by IrpContext to the 00071 work queue associated with the FileSystemDeviceObject. This is a FSD 00072 routine. 00073 00074 Arguments: 00075 00076 IrpContext - Pointer to the IrpContext to be queued to the Fsp. 00077 00078 Irp - I/O Request Packet. 00079 00080 Return Value: 00081 00082 STATUS_PENDING 00083 00084 --*/ 00085 00086 { 00087 PAGED_CODE(); 00088 00089 ASSERT_IRP_CONTEXT( IrpContext ); 00090 ASSERT_IRP( Irp ); 00091 00092 // 00093 // Posting is a three step operation. First lock down any buffers 00094 // in the Irp. Next cleanup the IrpContext for the post and finally 00095 // add this to a workque. 00096 // 00097 00098 UdfPrePostIrp( IrpContext, Irp ); 00099 00100 UdfAddToWorkque( IrpContext, Irp ); 00101 00102 // 00103 // And return to our caller 00104 // 00105 00106 return STATUS_PENDING; 00107 }

VOID UdfOplockComplete IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 222 of file workque.c.

References FALSE, _IRP::IoStatus, Irp, IRP_MJ_CREATE, NULL, PAGED_CODE, UdfAddToWorkque(), UdfCompleteRequest(), UdfReleaseFcb, and UdfTeardownStructures().

Referenced by UdfCommonLockControl(), UdfCommonRead(), and UdfCompleteFcbOpen().

00229 : 00230 00231 This routine is called by the oplock package when an oplock break has 00232 completed, allowing an Irp to resume execution. If the status in 00233 the Irp is STATUS_SUCCESS, then we queue the Irp to the Fsp queue. 00234 Otherwise we complete the Irp with the status in the Irp. 00235 00236 If we are completing due to an error then check if there is any 00237 cleanup to do. 00238 00239 Arguments: 00240 00241 Irp - I/O Request Packet. 00242 00243 Return Value: 00244 00245 None. 00246 00247 --*/ 00248 00249 { 00250 BOOLEAN RemovedFcb; 00251 00252 PAGED_CODE(); 00253 00254 // 00255 // Check on the return value in the Irp. If success then we 00256 // are to post this request. 00257 // 00258 00259 if (Irp->IoStatus.Status == STATUS_SUCCESS) { 00260 00261 // 00262 // Check if there is any cleanup work to do. 00263 // 00264 00265 switch (IrpContext->MajorFunction) { 00266 00267 case IRP_MJ_CREATE : 00268 00269 // 00270 // If called from the oplock package then there is an 00271 // Fcb to possibly teardown. We will call the teardown 00272 // routine and release the Fcb if still present. The cleanup 00273 // code in create will know not to release this Fcb because 00274 // we will clear the pointer. 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 // Insert the Irp context in the workqueue. 00294 // 00295 00296 UdfAddToWorkque( IrpContext, Irp ); 00297 00298 // 00299 // Otherwise complete the request. 00300 // 00301 00302 } else { 00303 00304 UdfCompleteRequest( IrpContext, Irp, Irp->IoStatus.Status ); 00305 } 00306 00307 return; 00308 }

VOID UdfPrePostIrp IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 111 of file workque.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, FALSE, FlagOn, IoGetCurrentIrpStackLocation, IoMarkIrpPending, Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_MJ_CREATE, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_READ, IRP_MN_MDL, IRP_MN_QUERY_DIRECTORY, NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, SetFlag, TRUE, UdfCleanupIrpContext(), UdfLockUserBuffer, UdfReleaseFcb, and UdfTeardownStructures().

Referenced by UdfCommonRead(), UdfCompleteFcbOpen(), and UdfFsdPostRequest().

00118 : 00119 00120 This routine performs any neccessary work before STATUS_PENDING is 00121 returned with the Fsd thread. This routine is called within the 00122 filesystem and by the oplock package. 00123 00124 Arguments: 00125 00126 Context - Pointer to the IrpContext to be queued to the Fsp 00127 00128 Irp - I/O Request Packet. 00129 00130 Return Value: 00131 00132 None. 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 // Case on the type of the operation. 00147 // 00148 00149 switch (IrpContext->MajorFunction) { 00150 00151 case IRP_MJ_CREATE : 00152 00153 // 00154 // If called from the oplock package then there is an 00155 // Fcb to possibly teardown. We will call the teardown 00156 // routine and release the Fcb if still present. The cleanup 00157 // code in create will know not to release this Fcb because 00158 // we will clear the pointer. 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 // We need to lock the user's buffer, unless this is an MDL-read, 00179 // in which case there is no user buffer. 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 // We also need to check whether this is a query file operation. 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 // Cleanup the IrpContext for the post. 00206 // 00207 00208 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00209 UdfCleanupIrpContext( IrpContext, TRUE ); 00210 00211 // 00212 // Mark the Irp to show that we've already returned pending to the user. 00213 // 00214 00215 IoMarkIrpPending( Irp ); 00216 00217 return; 00218 }


Generated on Sat May 15 19:46:09 2004 for test by doxygen 1.3.7