diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 00efb255..7dd23953 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -73,17 +73,14 @@ static NTSTATUS FspFsvolCleanup( Request->Req.Cleanup.UserContext2 = UserContext2; Request->Req.Cleanup.Delete = DeletePending; + return FSP_STATUS_IOQ_POST_BEST_EFFORT; + /* * Note that it is still possible for this request to not be delivered, * if the volume device Ioq is stopped. But such failures are benign * from our perspective, because they mean that the file system is going * away and should correctly tear things down. */ - - if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, 0)) - return STATUS_PENDING; - else - return STATUS_SUCCESS; } VOID FspFsvolCleanupComplete( diff --git a/src/sys/create.c b/src/sys/create.c index 6309f99b..2e00a273 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -312,7 +312,7 @@ static NTSTATUS FspFsvolCreate( RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, SecurityDescriptor, SecurityDescriptorSize); - return STATUS_PENDING; + return FSP_STATUS_IOQ_POST; } NTSTATUS FspFsvolCreatePrepare( @@ -380,8 +380,7 @@ NTSTATUS FspFsvolCreatePrepare( /* repost the IRP to retry later */ FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(IrpSp->DeviceObject); - if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result)) - Result = STATUS_PENDING; + FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result); return Result; } @@ -593,8 +592,7 @@ VOID FspFsvolCreateComplete( * Note that it is still possible for this request to not be delivered, * if the volume device Ioq is stopped or if the IRP is canceled. */ - if (FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result)) - Result = STATUS_PENDING; + FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result); } else { diff --git a/src/sys/debug.c b/src/sys/debug.c index 90638cdc..229bc2d7 100644 --- a/src/sys/debug.c +++ b/src/sys/debug.c @@ -16,12 +16,16 @@ const char *NtStatusSym(NTSTATUS Status) { // cygwin: sed -n '/_WAIT_0/!s/^#define[ \t]*\(STATUS_[^ \t]*\).*NTSTATUS.*$/SYM(\1)/p' #include "ntstatus.i" + case FSP_STATUS_IOQ_POST: + return "FSP_STATUS_IOQ_POST"; + case FSP_STATUS_IOQ_POST_BEST_EFFORT: + return "FSP_STATUS_IOQ_POST_BEST_EFFORT"; default: return "NTSTATUS:Unknown"; } } -const char *IrpMajorFunctionSym(UCHAR MajorFunction) +const char *IrpMajorFunctionSym(UCHAR MajorFunction) { switch (MajorFunction) { diff --git a/src/sys/driver.h b/src/sys/driver.h index 60a87fa6..73c8e7ca 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -25,11 +25,16 @@ #define FSP_FSVRT_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)" /* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */ +/* private NTSTATUS codes */ +#define FSP_STATUS_PRIVATE_BIT (0x20000000) +#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000) +#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001) + /* misc macros */ #define FSP_ALLOC_INTERNAL_TAG 'IpsF' #define FSP_ALLOC_EXTERNAL_TAG 'XpsF' #define FSP_IO_INCREMENT IO_NETWORK_INCREMENT - + /* DEBUGLOG */ #if DBG #define DEBUGLOG(fmt, ...) \ @@ -111,28 +116,33 @@ extern __declspec(selectany) int fsp_bp = 1; } while (0,0) #define FSP_LEAVE_MJ(fmt, ...) \ FSP_LEAVE_( \ - FSP_DEBUGLOG_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ - Irp, \ - (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ - Irp->RequestorMode == KernelMode ? 'K' : 'U',\ - IrpMajorFunctionSym(IrpSp->MajorFunction),\ - IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction),\ - __VA_ARGS__, \ - NtStatusSym(Result), \ - (LONGLONG)Irp->IoStatus.Information);\ - if (STATUS_PENDING == Result) \ + if (STATUS_PENDING != Result) \ { \ - if (0 == (IrpSp->Control & SL_PENDING_RETURNED))\ + ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\ + FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\ + FSP_DEBUGLOG_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ + Irp, \ + (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ + Irp->RequestorMode == KernelMode ? 'K' : 'U',\ + IrpMajorFunctionSym(IrpSp->MajorFunction),\ + IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction),\ + __VA_ARGS__, \ + NtStatusSym(Result), \ + (LONGLONG)Irp->IoStatus.Information);\ + if (FSP_STATUS_PRIVATE_BIT & Result)\ { \ - /* if the IRP has not been marked pending already */\ FSP_FSVOL_DEVICE_EXTENSION *fsp_leave_FsvolDeviceExtension =\ FspFsvolDeviceExtension(DeviceObject);\ - if (!FspIoqPostIrp(fsp_leave_FsvolDeviceExtension->Ioq, Irp, &Result))\ + if (!FspIoqPostIrpEx(fsp_leave_FsvolDeviceExtension->Ioq, Irp,\ + FSP_STATUS_IOQ_POST_BEST_EFFORT == Result, &Result))\ + {\ + DEBUGLOG("FspIoqPostIrpEx = %s", NtStatusSym(Result));\ FspIopCompleteIrp(Irp, Result);\ + }\ } \ + else \ + FspIopCompleteIrpEx(Irp, Result, fsp_device_release);\ } \ - else \ - FspIopCompleteIrpEx(Irp, Result, fsp_device_release);\ ); \ return Result #define FSP_ENTER_IOC(...) \ @@ -141,17 +151,20 @@ extern __declspec(selectany) int fsp_bp = 1; FSP_ENTER_NOCRIT_(__VA_ARGS__) #define FSP_LEAVE_IOC(fmt, ...) \ FSP_LEAVE_NOCRIT_( \ - FSP_DEBUGLOG_NOCRIT_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ - Irp, \ - (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ - Irp->RequestorMode == KernelMode ? 'K' : 'U',\ - IrpMajorFunctionSym(IrpSp->MajorFunction),\ - IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction),\ - __VA_ARGS__, \ - NtStatusSym(Result), \ - (LONGLONG)Irp->IoStatus.Information);\ if (STATUS_PENDING != Result) \ + { \ + ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result));\ + FSP_DEBUGLOG_NOCRIT_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ + Irp, \ + (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ + Irp->RequestorMode == KernelMode ? 'K' : 'U',\ + IrpMajorFunctionSym(IrpSp->MajorFunction),\ + IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MinorFunction),\ + __VA_ARGS__, \ + NtStatusSym(Result), \ + (LONGLONG)Irp->IoStatus.Information);\ FspIopCompleteIrp(Irp, Result);\ + } \ ) #define FSP_ENTER_BOOL(...) \ BOOLEAN Result = TRUE; FSP_ENTER_(__VA_ARGS__) diff --git a/src/sys/iop.c b/src/sys/iop.c index c707f535..79fb057f 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -214,6 +214,7 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease) PAGED_CODE(); ASSERT(STATUS_PENDING != Result); + ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result)); if (0 != FspIrpRequest(Irp)) { diff --git a/src/sys/ioq.c b/src/sys/ioq.c index a55abbc0..b46465fa 100644 --- a/src/sys/ioq.c +++ b/src/sys/ioq.c @@ -384,10 +384,17 @@ BOOLEAN FspIoqPostIrpEx(FSP_IOQ *Ioq, PIRP Irp, BOOLEAN BestEffort, NTSTATUS *PR QueryInterruptTimeInSec() + Ioq->IrpTimeout; Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, (PVOID)BestEffort); if (NT_SUCCESS(Result)) + { + if (0 != PResult) + *PResult = STATUS_PENDING; return TRUE; - if (0 != PResult) - *PResult = Result; - return FALSE; + } + else + { + if (0 != PResult) + *PResult = Result; + return FALSE; + } } PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp, PLARGE_INTEGER Timeout) diff --git a/src/sys/volume.c b/src/sys/volume.c index 732e8260..6833247d 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -644,8 +644,10 @@ NTSTATUS FspVolumeWork( Request->Hint = 0; FspIrpRequest(Irp) = 0; } - else - Result = STATUS_PENDING; + + DEBUGLOG("%s = %s", + IoctlCodeSym(BestEffort ? FSP_FSCTL_WORK_BEST_EFFORT : FSP_FSCTL_WORK), + NtStatusSym(Result)); return Result; }