sys: IRP_MJ_READ, IRP_MJ_WRITE: fix paging I/O sizes

This commit is contained in:
Bill Zissimopoulos 2016-04-13 18:00:02 -07:00
parent 49f9f13806
commit 41296044e6
6 changed files with 34 additions and 27 deletions

View File

@ -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
{ {

View File

@ -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,

View File

@ -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))

View File

@ -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;

View 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;

View File

@ -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);