From c70089a176e5ba86a8e7fc99d760c4f707722d3e Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 27 Sep 2017 18:01:17 -0700 Subject: [PATCH] sys: FSP_FILE_DESC: DirectoryNoMoreFiles optimization --- src/sys/dirctl.c | 17 +++++++++++++++++ src/sys/driver.h | 2 +- src/sys/file.c | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sys/dirctl.c b/src/sys/dirctl.c index 59e4d851..f08e1171 100644 --- a/src/sys/dirctl.c +++ b/src/sys/dirctl.c @@ -339,6 +339,10 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache( if (0 != *PDestLen) FileDesc->DirectoryHasSuchFile = TRUE; FileDesc->DirInfoCacheHint = (ULONG)((PUINT8)DirInfo - DirInfoBgn); + + if (DirInfoEnd >= (PUINT8)DirInfo + sizeof(DirInfo->Size) && + sizeof(FSP_FSCTL_DIR_INFO) > DirInfo->Size) + FileDesc->DirectoryNoMoreFiles = TRUE; } } else if (STATUS_NO_MORE_FILES == Result && !FileDesc->DirectoryHasSuchFile) @@ -361,6 +365,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace( BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive; PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern; UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker; + PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize; ASSERT(DirInfo == DestBuf); FSP_FSCTL_STATIC_ASSERT( @@ -381,6 +386,10 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace( { if (0 != *PDestLen) FileDesc->DirectoryHasSuchFile = TRUE; + + if (DirInfoEnd >= (PUINT8)DirInfo + sizeof(DirInfo->Size) && + sizeof(FSP_FSCTL_DIR_INFO) > DirInfo->Size) + FileDesc->DirectoryNoMoreFiles = TRUE; } } else if (STATUS_NO_MORE_FILES == Result && !FileDesc->DirectoryHasSuchFile) @@ -529,6 +538,14 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( return Result; } + /* check if the FileDesc has already seen the "End Of Directory" mark */ + if (FileDesc->DirectoryNoMoreFiles) + { + FspFileNodeRelease(FileNode, Full); + return !FileDesc->DirectoryHasSuchFile ? + STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES; + } + /* see if the required information is still in the cache and valid! */ if (FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize)) { diff --git a/src/sys/driver.h b/src/sys/driver.h index 8b37875d..c681cffb 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1267,7 +1267,7 @@ typedef struct DidSetMetadata:1, DidSetFileAttributes:1, DidSetReparsePoint:1, DidSetSecurity:1, DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1, - DirectoryHasSuchFile:1; + DirectoryHasSuchFile:1, DirectoryNoMoreFiles:1; UNICODE_STRING DirectoryPattern; UNICODE_STRING DirectoryMarker; UINT64 DirInfo; diff --git a/src/sys/file.c b/src/sys/file.c index bc60a64a..cf1806bd 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -2121,6 +2121,7 @@ NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc, FileDesc->DirectoryPattern = DirectoryPattern; FileDesc->DirectoryHasSuchFile = FALSE; + FileDesc->DirectoryNoMoreFiles = FALSE; if (0 != FileDesc->DirectoryMarker.Buffer) { @@ -2133,6 +2134,7 @@ NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc, ASSERT(0 == FileName || 0 == FileName->Length); FileDesc->DirectoryHasSuchFile = FALSE; + FileDesc->DirectoryNoMoreFiles = FALSE; if (0 != FileDesc->DirectoryMarker.Buffer) { @@ -2149,6 +2151,7 @@ NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc, return Result; FileDesc->DirectoryHasSuchFile = FALSE; + FileDesc->DirectoryNoMoreFiles = FALSE; } return STATUS_SUCCESS;