Skip to content

Commit

Permalink
Merge pull request #4 from DataCoreSoftware/ZFS-774
Browse files Browse the repository at this point in the history
Adding zpool API to retrieve allocated and total size of a zpool
  • Loading branch information
datacore-rm authored Sep 17, 2021
2 parents d7f4c09 + 437de6a commit b12868d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 24 deletions.
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 @@ -184,5 +184,7 @@ extern NTSTATUS ioctl_mountdev_query_stable_guid(PDEVICE_OBJECT, PIRP,
PIO_STACK_LOCATION);
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);

#endif
20 changes: 16 additions & 4 deletions include/sys/zfs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,18 @@ typedef struct zfs_useracct {
uint64_t zu_space;
} zfs_useracct_t;

#define ZPOOL_GET_SIZE_STATS CTL_CODE(ZFSIOCTL_TYPE, 0xFFF, \
METHOD_BUFFERED, FILE_ANY_ACCESS)

// Input/Output for IOCTL - ZPOOL_GET_SIZE_STATS
typedef struct {
uint8_t targetid;
uint8_t lun;
char zpool_name[MAXNAMELEN];
uint64_t size;
uint64_t alloc;
} zpool_size_stats;

typedef struct
{
uint64_t total;
Expand Down Expand Up @@ -597,9 +609,9 @@ typedef struct {
uint64_t arcstat_l2_write_bytes;
uint64_t arcstat_l2_access_ps;

/*
* ZIL and SLOG counters
*/
/*
* ZIL and SLOG counters
*/
uint64_t zil_commit_count;
uint64_t zil_commit_writer_count;
uint64_t zil_itx_count;
Expand Down Expand Up @@ -636,7 +648,7 @@ extern void zfs_unmount_snap(const char *);
extern void zfs_destroy_unmount_origin(const char *);
extern int getzfsvfs_impl(struct objset *, struct zfsvfs **);
extern int getzfsvfs(const char *, struct zfsvfs **);
extern void latency_stats(uint64_t* histo, unsigned int buckets,
extern void latency_stats(uint64_t *histo, unsigned int buckets,
stat_pair* lat);

enum zfsdev_state_type {
Expand Down
48 changes: 30 additions & 18 deletions module/os/windows/zfs/zfs_vnops_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ zfs_find_dvp_vp(zfsvfs_t *zfsvfs, char *filename, int finalpartmaynotexist,
zp->z_size, '!FSZ');
zfs_uio_t uio;
struct iovec iov = { rpb, zp->z_size };
zfs_uio_iovec_init(&uio, &iov, 1, 0, UIO_SYSSPACE, zp->z_size, 0);
zfs_uio_iovec_init(&uio, &iov, 1, 0,
UIO_SYSSPACE, zp->z_size, 0);
zfs_readlink(vp, &uio, NULL);
VN_RELE(vp);

Expand Down Expand Up @@ -2379,11 +2380,13 @@ zfswin_insert_xattrname(struct vnode *vp, char *xattrname, uint8_t *outbuffer,
iov.iov_len = roomforvalue;

zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, 0, UIO_SYSSPACE, roomforvalue, 0);
zfs_uio_iovec_init(&uio, &iov, 1, 0,
UIO_SYSSPACE, roomforvalue, 0);

zfs_read(VTOZ(vp), &uio, 0, NULL);
// Consume as many bytes as we read
*spaceused += roomforvalue - zfs_uio_resid(&uio);
*spaceused += roomforvalue -
zfs_uio_resid(&uio);
// Set the valuelen, should this be the full
// value or what we would need?
// That is how the names work.
Expand Down Expand Up @@ -2626,7 +2629,8 @@ get_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp,
iov.iov_len = size;

zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, 0, UIO_SYSSPACE, size, 0);
zfs_uio_iovec_init(&uio, &iov, 1, 0, UIO_SYSSPACE,
size, 0);
err = zfs_readlink(vp, &uio, NULL);

if (outlen < zp->z_size)
Expand Down Expand Up @@ -2990,13 +2994,14 @@ query_directory_FileFullDirectoryInformation(PDEVICE_OBJECT DeviceObject,
// Did last call complete listing?
if (zccb->dir_eof)
return (STATUS_NO_MORE_FILES);
struct iovec iov;
struct iovec iov;
void *SystemBuffer = MapUserBuffer(Irp);
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = IrpSp->Parameters.QueryDirectory.Length;
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = IrpSp->Parameters.QueryDirectory.Length;

zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, zccb->uio_offset, UIO_SYSSPACE, IrpSp->Parameters.QueryDirectory.Length, 0);
zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, zccb->uio_offset, UIO_SYSSPACE,
IrpSp->Parameters.QueryDirectory.Length, 0);

// Grab the root zp
zmo = DeviceObject->DeviceExtension;
Expand Down Expand Up @@ -3057,7 +3062,8 @@ query_directory_FileFullDirectoryInformation(PDEVICE_OBJECT DeviceObject,

// Set correct buffer size returned.
Irp->IoStatus.Information =
IrpSp->Parameters.QueryDirectory.Length - zfs_uio_resid(&uio);
IrpSp->Parameters.QueryDirectory.Length -
zfs_uio_resid(&uio);

dprintf("dirlist information in %d out size %d\n",
IrpSp->Parameters.QueryDirectory.Length,
Expand Down Expand Up @@ -3439,9 +3445,9 @@ fs_read(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
} // !nocache


struct iovec iov;
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = bufferLength;
struct iovec iov;
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = bufferLength;

zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, byteOffset.QuadPart, UIO_SYSSPACE, bufferLength, 0);
Expand Down Expand Up @@ -3680,12 +3686,13 @@ fs_write(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
}
}

struct iovec iov;
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = bufferLength;
struct iovec iov;
iov.iov_base = (void *)SystemBuffer;
iov.iov_len = bufferLength;

zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, byteOffset.QuadPart, UIO_SYSSPACE, bufferLength, 0);
zfs_uio_t uio;
zfs_uio_iovec_init(&uio, &iov, 1, byteOffset.QuadPart, UIO_SYSSPACE,
bufferLength, 0);

// dprintf("%s: offset %llx size %lx\n", __func__,
// byteOffset.QuadPart, bufferLength);
Expand Down Expand Up @@ -4542,6 +4549,11 @@ _Function_class_(DRIVER_DISPATCH)
Status = spl_kstat_write(DeviceObject, Irp,
IrpSp);
break;
case ZPOOL_GET_SIZE_STATS:
dprintf("ZPOOL_GET_SIZE_STATS\n");
Status = zpool_get_size_stats(DeviceObject,
Irp, IrpSp);
break;
default:
dprintf("**** unknown Windows IOCTL: 0x%lx\n",
cmd);
Expand Down
4 changes: 2 additions & 2 deletions module/os/windows/zfs/zfs_windows_zvol_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ wzvol_lock_target(zvol_state_t *zv)
return (FALSE);
}

static inline void
void
wzvol_unlock_target(zvol_state_t *zv)
{
wzvolContext* zvc = (pwzvolContext)zv->zv_zso->zso_target_context;
Expand Down Expand Up @@ -222,7 +222,7 @@ wzvol_assign_targetid(zvol_state_t *zv)
* note: find_target will lock the zv's remove lock. caller
* is responsible to unlock_target if a non-NULL zv pointer is returned
*/
static inline zvol_state_t *
zvol_state_t *
wzvol_find_target(uint8_t targetid, uint8_t lun)
{
wzvolContext *zv_targets = STOR_wzvolDriverInfo.zvContextArray;
Expand Down
67 changes: 67 additions & 0 deletions module/os/windows/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,3 +1035,70 @@ zvol_fini(void)
zvol_fini_impl();
taskq_destroy(zvol_taskq);
}

/* Returns 1 on failure; Returns 0 on success */
int
fetch_zpool_stats(zpool_size_stats *zstats) {
int ret = 1;

// If 'zpool/zvol' name is provided, truncating it to zpool name only
char *slash = strchr(zstats->zpool_name, '/');
if (slash)
*slash = '\0';

mutex_enter(&spa_namespace_lock);
spa_t *spa;
if ((spa = spa_lookup(zstats->zpool_name)) != NULL) {
mutex_enter(&spa->spa_props_lock);
metaslab_class_t *mc = spa_normal_class(spa);

zstats->alloc = metaslab_class_get_alloc(mc);
zstats->alloc +=
metaslab_class_get_alloc(spa_special_class(spa));
zstats->alloc +=
metaslab_class_get_alloc(spa_dedup_class(spa));

zstats->size = metaslab_class_get_space(mc);
zstats->size +=
metaslab_class_get_space(spa_special_class(spa));
zstats->size += metaslab_class_get_space(spa_dedup_class(spa));
mutex_exit(&spa->spa_props_lock);
ret = 0;
}
mutex_exit(&spa_namespace_lock);
return (ret);
}

extern zvol_state_t *wzvol_find_target(uint8_t targetid, uint8_t lun);
extern void wzvol_unlock_target(zvol_state_t *zv);

NTSTATUS
zpool_get_size_stats(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof (zpool_size_stats)) {
Irp->IoStatus.Information = sizeof (zpool_size_stats);
return (STATUS_BUFFER_TOO_SMALL);
}

zpool_size_stats *zpool_stats =
(zpool_size_stats *)Irp->AssociatedIrp.SystemBuffer;
if (!zpool_stats)
return (STATUS_INVALID_PARAMETER);

zvol_state_t *zv = NULL;
zv = wzvol_find_target(zpool_stats->targetid, zpool_stats->lun);
if (zv == NULL)
return (STATUS_INVALID_PARAMETER);

size_t len = sizeof (zpool_stats->zpool_name);
strncpy_s(zpool_stats->zpool_name, len, zv->zv_name, len - 1);
wzvol_unlock_target(zv);

if (fetch_zpool_stats(zpool_stats))
return (STATUS_NOT_FOUND);

Irp->IoStatus.Information = sizeof (zpool_size_stats);
return (STATUS_SUCCESS);
}

0 comments on commit b12868d

Please sign in to comment.