diff --git a/src/sys/driver.h b/src/sys/driver.h index 4fbc644f..e9ae2c2c 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -155,9 +155,9 @@ extern __declspec(selectany) int fsp_dt = 1; } \ fsp_device_deref = TRUE; \ } while (0,0) -#define FSP_LEAVE_MJ_COND(COND, fmt, ...)\ +#define FSP_LEAVE_MJ(fmt, ...) \ FSP_LEAVE_( \ - if (COND) \ + if (STATUS_PENDING != Result) \ { \ ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\ @@ -187,8 +187,6 @@ extern __declspec(selectany) int fsp_dt = 1; IoSetTopLevelIrp(fsp_top_level_irp);\ ); \ return Result -#define FSP_LEAVE_MJ(fmt, ...) \ - FSP_LEAVE_MJ_COND(STATUS_PENDING != Result, fmt, __VA_ARGS__) #define FSP_ENTER_IOC(...) \ NTSTATUS Result = STATUS_SUCCESS; \ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ @@ -954,8 +952,7 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size); BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, ULONG DirInfoChangeNumber); VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); -NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, - PBOOLEAN PIrpRelinquished); +NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, diff --git a/src/sys/file.c b/src/sys/file.c index b971150e..ea0fcb79 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -48,8 +48,7 @@ BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG S static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action); -NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, - PBOOLEAN PIrpRelinquished); +NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); @@ -88,6 +87,7 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, // !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo) // !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo) #pragma alloc_text(PAGE, FspFileNodeNotifyChange) +#pragma alloc_text(PAGE, FspFileNodeProcessLockIrp) #pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp) #pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescDelete) @@ -940,29 +940,26 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, 0, Filter, Action); } -NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp, - PBOOLEAN PIrpRelinquished) +NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp) { PAGED_CODE(); - NTSTATUS Result; - - FspFileNodeAcquireShared(FileNode, Main); - FspFileNodeSetOwner(FileNode, Main, Irp); + IoMarkIrpPending(Irp); + FspFileNodeSetOwnerF(FileNode, FspIrpFlags(Irp), Irp); try { - Result = FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode); - *PIrpRelinquished = TRUE; + FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode); } except (EXCEPTION_EXECUTE_HANDLER) { - FspFileNodeReleaseOwner(FileNode, Main, Irp); - Result = GetExceptionCode(); - *PIrpRelinquished = FALSE; + Irp->IoStatus.Status = GetExceptionCode(); + Irp->IoStatus.Information = 0; + + FspFileNodeCompleteLockIrp(FileNode, Irp); } - return Result; + return STATUS_PENDING; } static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp) @@ -972,7 +969,7 @@ static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp) FSP_FILE_NODE *FileNode = Context; NTSTATUS Result = Irp->IoStatus.Status; - FspFileNodeReleaseOwner(FileNode, Main, Irp); + FspFileNodeReleaseOwnerF(FileNode, FspIrpFlags(Irp), Irp); DEBUGLOGIRP(Irp, Result); diff --git a/src/sys/lockctl.c b/src/sys/lockctl.c index acd084c4..f7f056e2 100644 --- a/src/sys/lockctl.c +++ b/src/sys/lockctl.c @@ -6,21 +6,46 @@ #include +static NTSTATUS FspFsvolLockControlRetry( + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, + BOOLEAN CanWait); static NTSTATUS FspFsvolLockControl( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, - PBOOLEAN PIrpRelinquished); + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete; FSP_DRIVER_DISPATCH FspLockControl; #ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, FspFsvolLockControlRetry) #pragma alloc_text(PAGE, FspFsvolLockControl) #pragma alloc_text(PAGE, FspFsvolLockControlComplete) #pragma alloc_text(PAGE, FspLockControl) #endif +static NTSTATUS FspFsvolLockControlRetry( + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, + BOOLEAN CanWait) +{ + PAGED_CODE(); + + NTSTATUS Result; + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + BOOLEAN Success; + + /* try to acquire the FileNode shared Main */ + Success = DEBUGTEST(90, TRUE) && + FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait); + if (!Success) + return FspWqRepostIrpWorkItem(Irp, FspFsvolLockControlRetry, 0); + + /* let the FSRTL package handle this one! */ + Result = FspFileNodeProcessLockIrp(FileNode, Irp); + + return Result; +} + static NTSTATUS FspFsvolLockControl( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, - PBOOLEAN PIrpRelinquished) + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PAGED_CODE(); @@ -36,8 +61,7 @@ static NTSTATUS FspFsvolLockControl( if (FileNode->IsDirectory) return STATUS_INVALID_PARAMETER; - /* let the FSRTL package handle this one! */ - Result = FspFileNodeProcessLockIrp(FileNode, Irp, PIrpRelinquished); + Result = FspFsvolLockControlRetry(FsvolDeviceObject, Irp, IrpSp, IoIsOperationSynchronous(Irp)); return Result; } @@ -59,20 +83,17 @@ NTSTATUS FspFsvolLockControlComplete( NTSTATUS FspLockControl( PDEVICE_OBJECT DeviceObject, PIRP Irp) { - BOOLEAN IrpRelinquished = FALSE; - FSP_ENTER_MJ(PAGED_CODE()); switch (FspDeviceExtension(DeviceObject)->Kind) { case FspFsvolDeviceExtensionKind: - FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp, &IrpRelinquished)); + FSP_RETURN(Result = FspFsvolLockControl(DeviceObject, Irp, IrpSp)); default: FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); } - FSP_LEAVE_MJ_COND(!IrpRelinquished && STATUS_PENDING != Result, - "FileObject=%p, " + FSP_LEAVE_MJ("FileObject=%p, " "Key=%#lx, ByteOffset=%#lx:%#lx, Length=%ld", IrpSp->FileObject, IrpSp->Parameters.LockControl.Key,