From 46fa75a74debb74773357f3035f434b6fd968d29 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Fri, 26 Feb 2016 14:02:36 -0800 Subject: [PATCH] sys: consolidate Timeout functionality (ioq.c not included) --- src/sys/device.c | 10 ++++------ src/sys/driver.h | 41 +++++++++++++++++++++++++++++++++++++---- src/sys/file.c | 23 +++++++++++------------ src/sys/meta.c | 4 ++-- 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/sys/device.c b/src/sys/device.c index f0ed8e48..b0275d6c 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -327,7 +327,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) FsvolDeviceExtension->InitDoneIoq = 1; /* create our security meta cache */ - MetaTimeout.QuadPart = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL; + MetaTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout); /* convert millis to nanos */ Result = FspMetaCacheCreate( FspFsvolDeviceSecurityCacheCapacity, FspFsvolDeviceSecurityCacheItemSizeMax, &MetaTimeout, @@ -761,8 +761,7 @@ BOOLEAN FspFsvolTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I BOOLEAN Result; KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql); - if (0 < FsvolDeviceExtension->InfoExpirationTime && - KeQueryInterruptTime() < FsvolDeviceExtension->InfoExpirationTime) + if (FspExpirationTimeValid(FsvolDeviceExtension->InfoExpirationTime)) { VolumeInfoNp = FsvolDeviceExtension->VolumeInfo; Result = TRUE; @@ -785,12 +784,11 @@ VOID FspFsvolSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_I FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSCTL_VOLUME_INFO VolumeInfoNp = *VolumeInfo; KIRQL Irql; - UINT64 FileInfoTimeout = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL; KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql); FsvolDeviceExtension->VolumeInfo = VolumeInfoNp; - FsvolDeviceExtension->InfoExpirationTime = 0 != FileInfoTimeout ? - KeQueryInterruptTime() + FileInfoTimeout : 0; + FsvolDeviceExtension->InfoExpirationTime = FspExpirationTimeFromMillis( + FsvolDeviceExtension->VolumeParams.FileInfoTimeout); KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql); } diff --git a/src/sys/driver.h b/src/sys/driver.h index 4f590d93..9dc38d13 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -326,6 +326,39 @@ ULONG FspHashMixPointer(PVOID Pointer) #endif } +/* timeouts */ +#define FspTimeoutInfinity32 ((UINT32)-1L) +#define FspTimeoutInfinity64 ((UINT64)-1LL) +static inline +UINT64 FspTimeoutFromMillis(UINT32 Millis) +{ + /* if Millis is 0 or -1 then sign-extend else 10000ULL * Millis */ + return 1 >= Millis + 1 ? (INT64)(INT32)Millis : 10000ULL * Millis; +} +static inline +UINT64 FspExpirationTimeFromMillis(UINT32 Millis) +{ + /* if Millis is 0 or -1 then sign-extend else KeQueryInterruptTime() + 10000ULL * Millis */ + return 1 >= Millis + 1 ? (INT64)(INT32)Millis : KeQueryInterruptTime() + 10000ULL * Millis; +} +static inline +UINT64 FspExpirationTimeFromTimeout(UINT64 Timeout) +{ + /* if Timeout is 0 or -1 then Timeout else KeQueryInterruptTime() + Timeout */ + return 1 >= Timeout + 1 ? Timeout : KeQueryInterruptTime() + Timeout; +} +static inline +BOOLEAN FspExpirationTimeValid(UINT64 ExpirationTime) +{ + /* if ExpirationTime is 0 or -1 then ExpirationTime else KeQueryInterruptTime() < ExpirationTime */ + return 1 >= ExpirationTime + 1 ? (0 != ExpirationTime) : (KeQueryInterruptTime() < ExpirationTime); +} +static inline +BOOLEAN FspExpirationTimeValid2(UINT64 ExpirationTime, UINT64 CurrentTime) +{ + return CurrentTime < ExpirationTime; +} + /* utility */ PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); @@ -704,9 +737,9 @@ VOID FspFileNodeDereference(FSP_FILE_NODE *FileNode) FspFileNodeDelete(FileNode); } VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); -BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); +BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); -BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); +BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); @@ -728,9 +761,9 @@ BOOLEAN FspFileNodeTrySetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); #define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F) -#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F) +#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE) #define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F) -#define FspFileNodeTryAcquireExclusive(N,F) FspFileNodeTryAcquireExclusiveF(N, FspFileNodeAcquire ## F) +#define FspFileNodeTryAcquireExclusive(N,F) FspFileNodeTryAcquireExclusiveF(N, FspFileNodeAcquire ## F, FALSE) #define FspFileNodeSetOwner(N,F,P) FspFileNodeSetOwnerF(N, FspFileNodeAcquire ## F, P) #define FspFileNodeRelease(N,F) FspFileNodeReleaseF(N, FspFileNodeAcquire ## F) #define FspFileNodeReleaseOwner(N,F,P) FspFileNodeReleaseOwnerF(N, FspFileNodeAcquire ## F, P) diff --git a/src/sys/file.c b/src/sys/file.c index 56070473..fa174034 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -10,9 +10,9 @@ NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, ULONG ExtraSize, FSP_FILE_NODE **PFileNode); VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode); VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); -BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); +BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); -BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); +BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner); @@ -135,7 +135,7 @@ VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags) ExAcquireResourceSharedLite(FileNode->Header.PagingIoResource, TRUE); } -BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags) +BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait) { PAGED_CODE(); @@ -143,14 +143,14 @@ BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags) if (Flags & FspFileNodeAcquireMain) { - Result = ExAcquireResourceSharedLite(FileNode->Header.Resource, FALSE); + Result = ExAcquireResourceSharedLite(FileNode->Header.Resource, Wait); if (!Result) return FALSE; } if (Flags & FspFileNodeAcquirePgio) { - Result = ExAcquireResourceSharedLite(FileNode->Header.PagingIoResource, FALSE); + Result = ExAcquireResourceSharedLite(FileNode->Header.PagingIoResource, Wait); if (!Result) { if (Flags & FspFileNodeAcquireMain) @@ -173,7 +173,7 @@ VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags) ExAcquireResourceExclusiveLite(FileNode->Header.PagingIoResource, TRUE); } -BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags) +BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait) { PAGED_CODE(); @@ -181,14 +181,14 @@ BOOLEAN FspFileNodeTryAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags) if (Flags & FspFileNodeAcquireMain) { - Result = ExAcquireResourceExclusiveLite(FileNode->Header.Resource, FALSE); + Result = ExAcquireResourceExclusiveLite(FileNode->Header.Resource, Wait); if (!Result) return FALSE; } if (Flags & FspFileNodeAcquirePgio) { - Result = ExAcquireResourceExclusiveLite(FileNode->Header.PagingIoResource, FALSE); + Result = ExAcquireResourceExclusiveLite(FileNode->Header.PagingIoResource, Wait); if (!Result) { if (Flags & FspFileNodeAcquireMain) @@ -418,7 +418,7 @@ BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO * BOOLEAN Result; - if (0 < FileNode->InfoExpirationTime && KeQueryInterruptTime() < FileNode->InfoExpirationTime) + if (FspExpirationTimeValid(FileNode->InfoExpirationTime)) { FileInfo->AllocationSize = FileNode->Header.AllocationSize.QuadPart; FileInfo->FileSize = FileNode->Header.FileSize.QuadPart; @@ -444,7 +444,6 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); - UINT64 FileInfoTimeout = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL; UINT64 AllocationSize = FileInfo->AllocationSize > FileInfo->FileSize ? FileInfo->AllocationSize : FileInfo->FileSize; UINT64 AllocationUnit; @@ -462,8 +461,8 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, FileNode->LastAccessTime = FileInfo->LastAccessTime; FileNode->LastWriteTime = FileInfo->LastWriteTime; FileNode->ChangeTime = FileInfo->ChangeTime; - FileNode->InfoExpirationTime = 0 != FileInfoTimeout ? - KeQueryInterruptTime() + FileInfoTimeout : 0; + FileNode->InfoExpirationTime = FspExpirationTimeFromMillis( + FsvolDeviceExtension->VolumeParams.FileInfoTimeout); FileNode->InfoChangeNumber++; if (0 != CcFileObject) diff --git a/src/sys/meta.c b/src/sys/meta.c index 98147b80..4520d5ca 100644 --- a/src/sys/meta.c +++ b/src/sys/meta.c @@ -86,7 +86,7 @@ static inline FSP_META_CACHE_ITEM *FspMetaCacheRemoveExpiredItemAtDpcLevel(FSP_M if (Head == Entry) return 0; FSP_META_CACHE_ITEM *Item = CONTAINING_RECORD(Entry, FSP_META_CACHE_ITEM, ListEntry); - if (Item->ExpirationTime > ExpirationTime) + if (!FspExpirationTimeValid2(Item->ExpirationTime, ExpirationTime)) return 0; ULONG HashIndex = Item->ItemIndex % MetaCache->ItemBucketCount; for (FSP_META_CACHE_ITEM **P = (PVOID)&MetaCache->ItemBuckets[HashIndex]; *P; P = &(*P)->DictNext) @@ -203,7 +203,7 @@ UINT64 FspMetaCacheAddItem(FSP_META_CACHE *MetaCache, PCVOID Buffer, ULONG Size) RtlZeroMemory(Item, sizeof *Item); RtlZeroMemory(ItemBuffer, sizeof *ItemBuffer); Item->ItemBuffer = ItemBuffer; - Item->ExpirationTime = KeQueryInterruptTime() + MetaCache->MetaTimeout; + Item->ExpirationTime = FspExpirationTimeFromTimeout(MetaCache->MetaTimeout); Item->RefCount = 1; ItemBuffer->Item = Item; ItemBuffer->Size = Size;