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/cam/ctl/ctl_backend_block.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/cam/ctl/ctl_backend_block.c')
-rw-r--r-- | sys/cam/ctl/ctl_backend_block.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index dc725a3..727811b 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -147,6 +147,8 @@ struct ctl_be_block_lun; typedef void (*cbb_dispatch_t)(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio); +typedef uint64_t (*cbb_getattr_t)(struct ctl_be_block_lun *be_lun, + const char *attrname); /* * Backend LUN structure. There is a 1:1 mapping between a block device @@ -163,6 +165,7 @@ struct ctl_be_block_lun { cbb_dispatch_t dispatch; cbb_dispatch_t lun_flush; cbb_dispatch_t unmap; + cbb_getattr_t getattr; uma_zone_t lun_zone; uint64_t size_blocks; uint64_t size_bytes; @@ -243,6 +246,8 @@ static void ctl_be_block_unmap_dev(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio); static void ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun, struct ctl_be_block_io *beio); +static uint64_t ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun, + const char *attrname); static void ctl_be_block_cw_dispatch(struct ctl_be_block_lun *be_lun, union ctl_io *io); static void ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun, @@ -275,6 +280,7 @@ static void ctl_be_block_lun_config_status(void *be_lun, static int ctl_be_block_config_write(union ctl_io *io); static int ctl_be_block_config_read(union ctl_io *io); static int ctl_be_block_lun_info(void *be_lun, struct sbuf *sb); +static uint64_t ctl_be_block_lun_attr(void *be_lun, const char *attrname); int ctl_be_block_init(void); static struct ctl_backend_driver ctl_be_block_driver = @@ -287,7 +293,8 @@ static struct ctl_backend_driver ctl_be_block_driver = .config_read = ctl_be_block_config_read, .config_write = ctl_be_block_config_write, .ioctl = ctl_be_block_ioctl, - .lun_info = ctl_be_block_lun_info + .lun_info = ctl_be_block_lun_info, + .lun_attr = ctl_be_block_lun_attr }; MALLOC_DEFINE(M_CTLBLK, "ctlblk", "Memory used for CTL block backend"); @@ -1015,6 +1022,24 @@ ctl_be_block_dispatch_dev(struct ctl_be_block_lun *be_lun, } } +static uint64_t +ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun, const char *attrname) +{ + struct ctl_be_block_devdata *dev_data = &be_lun->backend.dev; + struct diocgattr_arg arg; + int error; + + if (dev_data->csw == NULL || dev_data->csw->d_ioctl == NULL) + return (UINT64_MAX); + strlcpy(arg.name, attrname, sizeof(arg.name)); + arg.len = sizeof(arg.value.off); + error = dev_data->csw->d_ioctl(dev_data->cdev, + DIOCGATTR, (caddr_t)&arg, FREAD, curthread); + if (error != 0) + return (UINT64_MAX); + return (arg.value.off); +} + static void ctl_be_block_cw_done_ws(struct ctl_be_block_io *beio) { @@ -1650,6 +1675,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) be_lun->dispatch = ctl_be_block_dispatch_dev; be_lun->lun_flush = ctl_be_block_flush_dev; be_lun->unmap = ctl_be_block_unmap_dev; + be_lun->getattr = ctl_be_block_getattr_dev; error = VOP_GETATTR(be_lun->vn, &vattr, NOCRED); if (error) { @@ -1996,10 +2022,10 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) } num_threads = tmp_num_threads; } - unmap = 0; + unmap = (be_lun->dispatch == ctl_be_block_dispatch_zvol); value = ctl_get_opt(&be_lun->ctl_be_lun.options, "unmap"); - if (value != NULL && strcmp(value, "on") == 0) - unmap = 1; + if (value != NULL) + unmap = (strcmp(value, "on") == 0); be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED; be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; @@ -2585,6 +2611,16 @@ bailout: return (retval); } +static uint64_t +ctl_be_block_lun_attr(void *be_lun, const char *attrname) +{ + struct ctl_be_block_lun *lun = (struct ctl_be_block_lun *)be_lun; + + if (lun->getattr == NULL) + return (UINT64_MAX); + return (lun->getattr(lun, attrname)); +} + int ctl_be_block_init(void) { |