mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: IRP_MJ_READ, IRP_MJ_WRITE: fix paging I/O sizes
This commit is contained in:
parent
49f9f13806
commit
41296044e6
@ -206,6 +206,7 @@ typedef struct
|
|||||||
UINT64 Offset;
|
UINT64 Offset;
|
||||||
UINT32 Length;
|
UINT32 Length;
|
||||||
UINT32 Key;
|
UINT32 Key;
|
||||||
|
UINT32 ConstrainedIo:1;
|
||||||
} Write;
|
} Write;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo);
|
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
NTSTATUS (*Write)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*Write)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length, BOOLEAN WriteToEndOfFile,
|
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||||
|
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
|
||||||
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo);
|
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
@ -449,6 +449,7 @@ FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
Request->Req.Write.Offset,
|
Request->Req.Write.Offset,
|
||||||
Request->Req.Write.Length,
|
Request->Req.Write.Length,
|
||||||
(UINT64)-1LL == Request->Req.Write.Offset,
|
(UINT64)-1LL == Request->Req.Write.Offset,
|
||||||
|
0 != Request->Req.Write.ConstrainedIo,
|
||||||
&BytesTransferred,
|
&BytesTransferred,
|
||||||
&FileInfo);
|
&FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
|
@ -220,8 +220,9 @@ static NTSTATUS FspFsvolReadNonCached(
|
|||||||
if (FlagOn(IrpSp->MinorFunction, IRP_MN_MDL))
|
if (FlagOn(IrpSp->MinorFunction, IRP_MN_MDL))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* if this is a recursive read (cache) see if we can optimize it away! */
|
/* if this is a Paging I/O see if we can optimize it away! */
|
||||||
if (FlagOn(FspIrpTopFlags(Irp), FspFileNodeAcquireMain) && /* if TopLevelIrp has acquired Main */
|
if (PagingIo && /* if this is Paging I/O */
|
||||||
|
FlagOn(FspIrpTopFlags(Irp), FspFileNodeAcquireMain) && /* and TopLevelIrp has acquired Main */
|
||||||
FspFileNodeTryGetFileInfo(FileNode, &FileInfo) && /* and the cached FileSize is valid */
|
FspFileNodeTryGetFileInfo(FileNode, &FileInfo) && /* and the cached FileSize is valid */
|
||||||
(UINT64)ReadOffset.QuadPart >= FileInfo.FileSize) /* and the ReadOffset is past EOF */
|
(UINT64)ReadOffset.QuadPart >= FileInfo.FileSize) /* and the ReadOffset is past EOF */
|
||||||
return STATUS_END_OF_FILE;
|
return STATUS_END_OF_FILE;
|
||||||
|
@ -276,23 +276,13 @@ static NTSTATUS FspFsvolWriteNonCached(
|
|||||||
if (FspIoqStopped(FspFsvolDeviceExtension(FsvolDeviceObject)->Ioq))
|
if (FspIoqStopped(FspFsvolDeviceExtension(FsvolDeviceObject)->Ioq))
|
||||||
return FspFsvolDeviceStoppedStatus(FsvolDeviceObject);
|
return FspFsvolDeviceStoppedStatus(FsvolDeviceObject);
|
||||||
|
|
||||||
/* if we are called by the lazy writer we must constrain writes */
|
/* if this is a Paging I/O see if we can optimize it away! */
|
||||||
if (FlagOn(FspIrpTopFlags(Irp), FspFileNodeAcquireMain) && /* if TopLevelIrp has acquired Main */
|
if (PagingIo && /* if this is Paging I/O */
|
||||||
FileNode->Tls.LazyWriteThread == PsGetCurrentThread()) /* and this is a lazy writer thread */
|
FlagOn(FspIrpTopFlags(Irp), FspFileNodeAcquireMain) && /* and TopLevelIrp has acquired Main */
|
||||||
{
|
FspFileNodeTryGetFileInfo(FileNode, &FileInfo) && /* and the cached FileSize is valid */
|
||||||
ASSERT(PagingIo);
|
(UINT64)WriteOffset.QuadPart >= FileInfo.FileSize) /* and the WriteOffset is past EOF */
|
||||||
ASSERT(FspTimeoutInfinity32 ==
|
|
||||||
FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.FileInfoTimeout);
|
|
||||||
|
|
||||||
FspFileNodeGetFileInfo(FileNode, &FileInfo);
|
|
||||||
|
|
||||||
if ((UINT64)WriteOffset.QuadPart >= FileInfo.FileSize)
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
if (WriteLength > (ULONG)(FileInfo.FileSize - WriteOffset.QuadPart))
|
|
||||||
WriteLength = (ULONG)(FileInfo.FileSize - WriteOffset.QuadPart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* probe and lock the user buffer */
|
/* probe and lock the user buffer */
|
||||||
Result = FspLockUserBuffer(Irp, WriteLength, IoReadAccess);
|
Result = FspLockUserBuffer(Irp, WriteLength, IoReadAccess);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -348,6 +338,7 @@ static NTSTATUS FspFsvolWriteNonCached(
|
|||||||
Request->Req.Write.Offset = WriteOffset.QuadPart;
|
Request->Req.Write.Offset = WriteOffset.QuadPart;
|
||||||
Request->Req.Write.Length = WriteLength;
|
Request->Req.Write.Length = WriteLength;
|
||||||
Request->Req.Write.Key = WriteKey;
|
Request->Req.Write.Key = WriteKey;
|
||||||
|
Request->Req.Write.ConstrainedIo = !!PagingIo;
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
@ -482,17 +482,29 @@ static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
PVOID FileNode0, PVOID Buffer, UINT64 Offset, ULONG Length, BOOLEAN WriteToEndOfFile,
|
PVOID FileNode0, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||||
|
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
|
||||||
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
|
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||||
UINT64 EndOffset;
|
UINT64 EndOffset;
|
||||||
|
|
||||||
|
if (ConstrainedIo)
|
||||||
|
{
|
||||||
|
if (Offset >= FileNode->FileInfo.FileSize)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
EndOffset = Offset + Length;
|
||||||
|
if (EndOffset > FileNode->FileInfo.FileSize)
|
||||||
|
EndOffset = FileNode->FileInfo.FileSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (WriteToEndOfFile)
|
if (WriteToEndOfFile)
|
||||||
Offset = FileNode->FileInfo.FileSize;
|
Offset = FileNode->FileInfo.FileSize;
|
||||||
EndOffset = Offset + Length;
|
EndOffset = Offset + Length;
|
||||||
if (EndOffset > FileNode->FileInfo.FileSize)
|
if (EndOffset > FileNode->FileInfo.FileSize)
|
||||||
SetFileSize(FileSystem, Request, FileNode, EndOffset, FileInfo);
|
SetFileSize(FileSystem, Request, FileNode, EndOffset, FileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy((PUINT8)FileNode->FileData + Offset, Buffer, EndOffset - Offset);
|
memcpy((PUINT8)FileNode->FileData + Offset, Buffer, EndOffset - Offset);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user