Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOCTL to fetch IOPS and read/write bytes of a zpool #40

Merged
merged 1 commit into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/os/windows/zfs/sys/zfs_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions include/sys/zfs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
41 changes: 41 additions & 0 deletions module/os/windows/zfs/zfs_ioctl_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions module/os/windows/zfs/zfs_vnops_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down