From 35be05171dcce5e35b9db880f7f00a74b2de9895 Mon Sep 17 00:00:00 2001 From: Shashank Kumar <75466339+datacore-skumar@users.noreply.github.com> Date: Fri, 18 Mar 2022 15:21:18 +0530 Subject: [PATCH] IOCTL to fetch IOPS and read/write bytes of a zpool --- include/os/windows/zfs/sys/zfs_windows.h | 2 ++ include/sys/zfs_ioctl.h | 3 ++ module/os/windows/zfs/zfs_ioctl_os.c | 41 +++++++++++++++++++++++ module/os/windows/zfs/zfs_vnops_windows.c | 4 +++ 4 files changed, 50 insertions(+) diff --git a/include/os/windows/zfs/sys/zfs_windows.h b/include/os/windows/zfs/sys/zfs_windows.h index ddc3f28c6361..ec416dd38d76 100644 --- a/include/os/windows/zfs/sys/zfs_windows.h +++ b/include/os/windows/zfs/sys/zfs_windows.h @@ -186,5 +186,7 @@ extern NTSTATUS ioctl_query_stable_guid(PDEVICE_OBJECT, PIRP, PIO_STACK_LOCATION); extern NTSTATUS zpool_get_size_stats(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +extern NTSTATUS zpool_get_iops_thrput(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp); #endif diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h index e5db57e39ba1..1a83506b4c16 100644 --- a/include/sys/zfs_ioctl.h +++ b/include/sys/zfs_ioctl.h @@ -536,6 +536,8 @@ typedef struct { uint64_t alloc; } zpool_size_stats; +#define ZPOOL_GET_IOPS_THRPUT_STATS CTL_CODE(ZFSIOCTL_TYPE, 0xFFE, METHOD_BUFFERED, FILE_ANY_ACCESS) + typedef struct { uint64_t total; @@ -577,6 +579,7 @@ typedef struct { unsigned __int64 vsx_disk_histo_write_time; unsigned __int64 vsx_disk_histo_write_count; unsigned __int64 dp_dirty_total_io; // zpool only + char zpool_name[MAXNAMELEN]; } zpool_perf_counters; typedef struct { diff --git a/module/os/windows/zfs/zfs_ioctl_os.c b/module/os/windows/zfs/zfs_ioctl_os.c index f09445dec67a..2fe118d8ff97 100644 --- a/module/os/windows/zfs/zfs_ioctl_os.c +++ b/module/os/windows/zfs/zfs_ioctl_os.c @@ -88,6 +88,47 @@ zfs_vfs_ref(zfsvfs_t **zfvp) return (error); } +NTSTATUS zpool_get_iops_thrput(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(zpool_perf_counters)) { + Irp->IoStatus.Information = sizeof(zpool_perf_counters); + return STATUS_BUFFER_TOO_SMALL; + } + + zpool_perf_counters* perf = (zpool_perf_counters*)Irp->AssociatedIrp.SystemBuffer; + if (!perf) + return STATUS_INVALID_PARAMETER; + + perf->zpool_name[MAXNAMELEN - 1] = '\0'; + + // If 'zpool/zvol' name is provided, truncating it to zpool name only + char* slash = strchr(perf->zpool_name, '/'); + if (slash) + *slash = '\0'; + + mutex_enter(&spa_namespace_lock); + spa_t* spa; + if ((spa = spa_lookup(perf->zpool_name)) == NULL) { + mutex_exit(&spa_namespace_lock); + return STATUS_NOT_FOUND; + } + vdev_stat_t vs; + spa_config_enter(spa, SCL_ALL, FTAG, RW_READER); + vdev_get_stats(spa->spa_root_vdev, &vs); + spa_config_exit(spa, SCL_ALL, FTAG); + mutex_exit(&spa_namespace_lock); + + perf->read_iops = vs.vs_ops[ZIO_TYPE_READ]; + perf->write_iops = vs.vs_ops[ZIO_TYPE_WRITE]; + perf->read_bytes = vs.vs_bytes[ZIO_TYPE_READ] / (1024 * 1024); + perf->write_bytes = vs.vs_bytes[ZIO_TYPE_WRITE] / (1024 * 1024); + perf->total_iops = vs.vs_ops[ZIO_TYPE_READ] + vs.vs_ops[ZIO_TYPE_WRITE]; + perf->total_bytes = (vs.vs_bytes[ZIO_TYPE_READ] + vs.vs_bytes[ZIO_TYPE_WRITE]) / (1024 * 1024); + + Irp->IoStatus.Information = sizeof(zpool_perf_counters); + return STATUS_SUCCESS; +} + NTSTATUS NTAPI ZFSinPerfCallBack(PCW_CALLBACK_TYPE Type, PPCW_CALLBACK_INFORMATION Info, PVOID Context) diff --git a/module/os/windows/zfs/zfs_vnops_windows.c b/module/os/windows/zfs/zfs_vnops_windows.c index 10ea683defe2..d5cd1f2e7d97 100644 --- a/module/os/windows/zfs/zfs_vnops_windows.c +++ b/module/os/windows/zfs/zfs_vnops_windows.c @@ -4660,6 +4660,10 @@ _Function_class_(DRIVER_DISPATCH) Status = zpool_get_size_stats(DeviceObject, Irp, IrpSp); break; + case ZPOOL_GET_IOPS_THRPUT_STATS: + dprintf("ZPOOL_GET_IOPS_THRPUT_STATS\n"); + Status = zpool_get_iops_thrput(DeviceObject, Irp, IrpSp); + break; default: dprintf("**** unknown Windows IOCTL: 0x%lx\n", cmd);