summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-11-20 01:55:12 +0000
committermav <mav@FreeBSD.org>2014-11-20 01:55:12 +0000
commit6414b04c27c11b1fb58b7605fde9797ffe3dfa32 (patch)
treeb3e695871eabeae5b0f9c125f54622c300f3baf5 /sys/cddl
parent3f382b8a2d8301dde56a5e8b9bde1a25c1bcca19 (diff)
downloadFreeBSD-src-6414b04c27c11b1fb58b7605fde9797ffe3dfa32.zip
FreeBSD-src-6414b04c27c11b1fb58b7605fde9797ffe3dfa32.tar.gz
MFC r274154, r274163:
Add to CTL support for logical block provisioning threshold notifications. For ZVOL-backed LUNs this allows to inform initiators if storage's used or available spaces get above/below the configured thresholds. Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index 4c67f2f..0451c65 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -2460,10 +2460,38 @@ zvol_geom_start(struct bio *bp)
goto enqueue;
zvol_strategy(bp);
break;
- case BIO_GETATTR:
+ case BIO_GETATTR: {
+ spa_t *spa = dmu_objset_spa(zv->zv_objset);
+ uint64_t refd, avail, usedobjs, availobjs, val;
+
if (g_handleattr_int(bp, "GEOM::candelete", 1))
return;
+ if (strcmp(bp->bio_attribute, "blocksavail") == 0) {
+ dmu_objset_space(zv->zv_objset, &refd, &avail,
+ &usedobjs, &availobjs);
+ if (g_handleattr_off_t(bp, "blocksavail",
+ avail / DEV_BSIZE))
+ return;
+ } else if (strcmp(bp->bio_attribute, "blocksused") == 0) {
+ dmu_objset_space(zv->zv_objset, &refd, &avail,
+ &usedobjs, &availobjs);
+ if (g_handleattr_off_t(bp, "blocksused",
+ refd / DEV_BSIZE))
+ return;
+ } else if (strcmp(bp->bio_attribute, "poolblocksavail") == 0) {
+ avail = metaslab_class_get_space(spa_normal_class(spa));
+ avail -= metaslab_class_get_alloc(spa_normal_class(spa));
+ if (g_handleattr_off_t(bp, "poolblocksavail",
+ avail / DEV_BSIZE))
+ return;
+ } else if (strcmp(bp->bio_attribute, "poolblocksused") == 0) {
+ refd = metaslab_class_get_alloc(spa_normal_class(spa));
+ if (g_handleattr_off_t(bp, "poolblocksused",
+ refd / DEV_BSIZE))
+ return;
+ }
/* FALLTHROUGH */
+ }
default:
g_io_deliver(bp, EOPNOTSUPP);
break;
@@ -2862,6 +2890,30 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
case DIOCGSTRIPEOFFSET:
*(off_t *)data = 0;
break;
+ case DIOCGATTR: {
+ spa_t *spa = dmu_objset_spa(zv->zv_objset);
+ struct diocgattr_arg *arg = (struct diocgattr_arg *)data;
+ uint64_t refd, avail, usedobjs, availobjs;
+
+ if (strcmp(arg->name, "blocksavail") == 0) {
+ dmu_objset_space(zv->zv_objset, &refd, &avail,
+ &usedobjs, &availobjs);
+ arg->value.off = avail / DEV_BSIZE;
+ } else if (strcmp(arg->name, "blocksused") == 0) {
+ dmu_objset_space(zv->zv_objset, &refd, &avail,
+ &usedobjs, &availobjs);
+ arg->value.off = refd / DEV_BSIZE;
+ } else if (strcmp(arg->name, "poolblocksavail") == 0) {
+ avail = metaslab_class_get_space(spa_normal_class(spa));
+ avail -= metaslab_class_get_alloc(spa_normal_class(spa));
+ arg->value.off = avail / DEV_BSIZE;
+ } else if (strcmp(arg->name, "poolblocksused") == 0) {
+ refd = metaslab_class_get_alloc(spa_normal_class(spa));
+ arg->value.off = refd / DEV_BSIZE;
+ } else
+ error = ENOIOCTL;
+ break;
+ }
default:
error = ENOIOCTL;
}
OpenPOWER on IntegriCloud