diff options
author | mav <mav@FreeBSD.org> | 2014-11-20 01:55:12 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-11-20 01:55:12 +0000 |
commit | 6414b04c27c11b1fb58b7605fde9797ffe3dfa32 (patch) | |
tree | b3e695871eabeae5b0f9c125f54622c300f3baf5 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | |
parent | 3f382b8a2d8301dde56a5e8b9bde1a25c1bcca19 (diff) | |
download | FreeBSD-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/contrib/opensolaris/uts/common/fs/zfs/zvol.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | 54 |
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; } |