mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: statistics: implement FSCTL_FILESYSTEM_GET_STATISTICS
This commit is contained in:
parent
c8206751d2
commit
168acb1a1f
@ -177,6 +177,7 @@
|
||||
<ClCompile Include="..\..\src\sys\read.c" />
|
||||
<ClCompile Include="..\..\src\sys\security.c" />
|
||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||
<ClCompile Include="..\..\src\sys\statistics.c" />
|
||||
<ClCompile Include="..\..\src\sys\util.c" />
|
||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||
<ClCompile Include="..\..\src\sys\volume.c" />
|
||||
|
@ -95,6 +95,9 @@
|
||||
<ClCompile Include="..\..\src\sys\name.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\statistics.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\sys\driver.h">
|
||||
|
@ -364,6 +364,12 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||
InitializeListHead(&FsvolDeviceExtension->NotifyList);
|
||||
FsvolDeviceExtension->InitDoneNotify = 1;
|
||||
|
||||
/* create file system statistics */
|
||||
Result = FspStatisticsCreate(&FsvolDeviceExtension->Statistics);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
FsvolDeviceExtension->InitDoneStat = 1;
|
||||
|
||||
/* initialize our context table */
|
||||
ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
||||
ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
||||
@ -408,6 +414,10 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
||||
if (FsvolDeviceExtension->InitDoneTimer)
|
||||
IoStopTimer(DeviceObject);
|
||||
|
||||
/* delete the file system statistics */
|
||||
if (FsvolDeviceExtension->InitDoneStat)
|
||||
FspStatisticsDelete(FsvolDeviceExtension->Statistics);
|
||||
|
||||
/* uninitialize the FSRTL Notify mechanism */
|
||||
if (FsvolDeviceExtension->InitDoneNotify)
|
||||
{
|
||||
|
@ -176,6 +176,8 @@ NTSTATUS DriverEntry(
|
||||
|
||||
static VOID FspDriverMultiVersionInitialize(VOID)
|
||||
{
|
||||
FspProcessorCount = KeQueryActiveProcessorCount(0);
|
||||
|
||||
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
|
||||
|
||||
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7))
|
||||
@ -216,5 +218,6 @@ PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||
|
||||
ULONG FspProcessorCount;
|
||||
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
||||
ULONG FspMvMdlMappingNoWrite = 0;
|
||||
|
@ -949,6 +949,21 @@ VOID FspWqPostIrpWorkItem(PIRP Irp);
|
||||
#define FspWqRepostIrpWorkItem(I, RW, RF)\
|
||||
FspWqCreateAndPostIrpWorkItem(I, RW, RF, TRUE)
|
||||
|
||||
/* file system statistics */
|
||||
typedef struct
|
||||
{
|
||||
FILESYSTEM_STATISTICS Base;
|
||||
FAT_STATISTICS Specific; /* pretend that we are FAT when it comes to stats */
|
||||
/* align to 64 bytes */
|
||||
__declspec(align(64)) UINT8 EndOfStruct[];
|
||||
} FSP_STATISTICS;
|
||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics);
|
||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics);
|
||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength);
|
||||
#define FspStatistics(S) (&(S)[KeGetCurrentProcessorNumber() % FspProcessorCount])
|
||||
#define FspStatisticsInc(S,F) ((S)->F++)
|
||||
#define FspStatisticsAdd(S,F,V) ((S)->F += (V))
|
||||
|
||||
/* device management */
|
||||
enum
|
||||
{
|
||||
@ -990,7 +1005,7 @@ typedef struct
|
||||
{
|
||||
FSP_DEVICE_EXTENSION Base;
|
||||
UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1,
|
||||
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1;
|
||||
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
|
||||
PDEVICE_OBJECT FsctlDeviceObject;
|
||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||
HANDLE MupHandle;
|
||||
@ -1016,6 +1031,7 @@ typedef struct
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||
PNOTIFY_SYNC NotifySync;
|
||||
LIST_ENTRY NotifyList;
|
||||
FSP_STATISTICS *Statistics;
|
||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||
static inline
|
||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||
@ -1083,6 +1099,8 @@ VOID FspDeviceGlobalUnlock(VOID)
|
||||
extern ERESOURCE FspDeviceGlobalResource;
|
||||
ExReleaseResourceLite(&FspDeviceGlobalResource);
|
||||
}
|
||||
#define FspFsvolDeviceStatistics(DeviceObject)\
|
||||
FspStatistics(FspFsvolDeviceExtension(DeviceObject)->Statistics)
|
||||
#define FspFsvolDeviceStoppedStatus(DeviceObject)\
|
||||
STATUS_VOLUME_DISMOUNTED
|
||||
//(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\
|
||||
@ -1486,6 +1504,7 @@ extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
||||
extern ERESOURCE FspDeviceGlobalResource;
|
||||
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
|
||||
extern const GUID FspMainFileOpenEcpGuid;
|
||||
extern ULONG FspProcessorCount;
|
||||
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
||||
extern ULONG FspMvMdlMappingNoWrite;
|
||||
|
||||
|
@ -31,6 +31,8 @@ static IO_COMPLETION_ROUTINE FspFsvolFileSystemControlOplockCompletion;
|
||||
static WORKER_THREAD_ROUTINE FspFsvolFileSystemControlOplockCompletionWork;
|
||||
static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolFileSystemControlGetStatistics(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspFsvolFileSystemControl(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
|
||||
@ -45,6 +47,7 @@ FSP_DRIVER_DISPATCH FspFileSystemControl;
|
||||
// !#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletion)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletionWork)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlQueryPersistentVolumeState)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlGetStatistics)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControl)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlComplete)
|
||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlRequestFini)
|
||||
@ -513,6 +516,23 @@ static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolFileSystemControlGetStatistics(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
ULONG Length = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
||||
|
||||
Result = FspStatisticsCopy(FsvolDeviceExtension->Statistics, Buffer, &Length);
|
||||
|
||||
Irp->IoStatus.Information = Length;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsvolFileSystemControl(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -549,6 +569,9 @@ static NTSTATUS FspFsvolFileSystemControl(
|
||||
case FSCTL_QUERY_PERSISTENT_VOLUME_STATE:
|
||||
Result = FspFsvolFileSystemControlQueryPersistentVolumeState(FsvolDeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
case FSCTL_FILESYSTEM_GET_STATISTICS:
|
||||
Result = FspFsvolFileSystemControlGetStatistics(FsvolDeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -281,6 +281,28 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference)
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
||||
|
||||
/*
|
||||
* HACK:
|
||||
*
|
||||
* We update the Create statistics here to avoid doing it in multiple places.
|
||||
*/
|
||||
if (IRP_MJ_CREATE == IrpSp->MajorFunction)
|
||||
{
|
||||
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject);
|
||||
|
||||
if (FspFsvolDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind)
|
||||
{
|
||||
FSP_STATISTICS *Statistics = FspStatistics(
|
||||
((FSP_FSVOL_DEVICE_EXTENSION *)DeviceExtension)->Statistics);
|
||||
|
||||
FspStatisticsInc(Statistics, Specific.CreateHits);
|
||||
if (STATUS_SUCCESS == Result)
|
||||
FspStatisticsInc(Statistics, Specific.SuccessfulCreates);
|
||||
else
|
||||
FspStatisticsInc(Statistics, Specific.FailedCreates);
|
||||
}
|
||||
}
|
||||
else
|
||||
/*
|
||||
* HACK:
|
||||
*
|
||||
|
@ -324,6 +324,20 @@ static NTSTATUS FspFsvolReadNonCached(
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||
|
||||
FSP_STATISTICS *Statistics = FspFsvolDeviceStatistics(FsvolDeviceObject);
|
||||
if (PagingIo)
|
||||
{
|
||||
FspStatisticsInc(Statistics, Base.UserFileReads);
|
||||
FspStatisticsAdd(Statistics, Base.UserFileReadBytes, ReadLength);
|
||||
FspStatisticsInc(Statistics, Base.UserDiskReads);
|
||||
}
|
||||
else
|
||||
{
|
||||
FspStatisticsInc(Statistics, Specific.NonCachedReads);
|
||||
FspStatisticsAdd(Statistics, Specific.NonCachedReadBytes, ReadLength);
|
||||
FspStatisticsInc(Statistics, Specific.NonCachedDiskReads);
|
||||
}
|
||||
|
||||
return FSP_STATUS_IOQ_POST;
|
||||
}
|
||||
|
||||
|
84
src/sys/statistics.c
Normal file
84
src/sys/statistics.c
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file sys/statistics.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
*
|
||||
* You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License version 3 as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* Licensees holding a valid commercial license may use this file in
|
||||
* accordance with the commercial license agreement provided with the
|
||||
* software.
|
||||
*/
|
||||
|
||||
#include <sys/driver.h>
|
||||
|
||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics);
|
||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics);
|
||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength);
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FspStatisticsCreate)
|
||||
#pragma alloc_text(PAGE, FspStatisticsDelete)
|
||||
#pragma alloc_text(PAGE, FspStatisticsCopy)
|
||||
#endif
|
||||
|
||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics)
|
||||
{
|
||||
*PStatistics = FspAllocNonPaged(sizeof(FSP_STATISTICS) * FspProcessorCount);
|
||||
if (0 == *PStatistics)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlZeroMemory(*PStatistics, sizeof(FSP_STATISTICS) * FspProcessorCount);
|
||||
for (ULONG Index = 0; FspProcessorCount > Index; Index++)
|
||||
{
|
||||
FSP_STATISTICS *Statistics = PStatistics[Index];
|
||||
|
||||
/* pretend that we are FAT when it comes to stats */
|
||||
Statistics->Base.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
|
||||
Statistics->Base.Version = 1;
|
||||
Statistics->Base.SizeOfCompleteStructure = sizeof(FSP_STATISTICS);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics)
|
||||
{
|
||||
FspFree(Statistics);
|
||||
}
|
||||
|
||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
ULONG StatLength;
|
||||
|
||||
if (0 == Buffer)
|
||||
{
|
||||
*PLength = 0;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (sizeof(FILESYSTEM_STATISTICS) > *PLength)
|
||||
{
|
||||
*PLength = 0;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
StatLength = sizeof(FSP_STATISTICS) * FspProcessorCount;
|
||||
if (*PLength >= StatLength)
|
||||
{
|
||||
*PLength = StatLength;
|
||||
Result = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
Result = STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
RtlCopyMemory(Buffer, Statistics, *PLength);
|
||||
|
||||
return Result;
|
||||
}
|
@ -394,6 +394,20 @@ static NTSTATUS FspFsvolWriteNonCached(
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||
|
||||
FSP_STATISTICS *Statistics = FspFsvolDeviceStatistics(FsvolDeviceObject);
|
||||
if (PagingIo)
|
||||
{
|
||||
FspStatisticsInc(Statistics, Base.UserFileWrites);
|
||||
FspStatisticsAdd(Statistics, Base.UserFileWriteBytes, WriteLength);
|
||||
FspStatisticsInc(Statistics, Base.UserDiskWrites);
|
||||
}
|
||||
else
|
||||
{
|
||||
FspStatisticsInc(Statistics, Specific.NonCachedWrites);
|
||||
FspStatisticsAdd(Statistics, Specific.NonCachedWriteBytes, WriteLength);
|
||||
FspStatisticsInc(Statistics, Specific.NonCachedDiskWrites);
|
||||
}
|
||||
|
||||
return FSP_STATUS_IOQ_POST;
|
||||
}
|
||||
|
||||
|
@ -379,8 +379,8 @@ rem call :__ifstest %1 /d %2 /g ChangeNotification /z /v
|
||||
rem if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
||||
call :__ifstest %1 /d %2 /g ReadWrite /z /v
|
||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
||||
rem call :__ifstest %1 /d %2 /g SectionsCaching /z /v
|
||||
rem if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
||||
call :__ifstest %1 /d %2 /g SectionsCaching /z /v
|
||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
||||
rem call :__ifstest %1 /d %2 /g ReparsePoints /z /v
|
||||
rem if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
||||
rem call :__ifstest %1 /d %2 /g StreamEnhancements /z /v
|
||||
|
Loading…
x
Reference in New Issue
Block a user