diff options
author | mav <mav@FreeBSD.org> | 2014-05-08 07:00:45 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-05-08 07:00:45 +0000 |
commit | 2d5dc4736b59caac5805f2d92e46374abedecf49 (patch) | |
tree | c75899a669ba98fd8ca7a2f96c817567197fb91c /sys/cam/ctl/ctl_backend_ramdisk.c | |
parent | 246a5ae3a0e73281e07ad2f26b1e62374f1bccf3 (diff) | |
download | FreeBSD-src-2d5dc4736b59caac5805f2d92e46374abedecf49.zip FreeBSD-src-2d5dc4736b59caac5805f2d92e46374abedecf49.tar.gz |
MFC r264274, r264279, r264283, r264296, r264297:
Add support for SCSI UNMAP commands to CTL.
This patch adds support for three new SCSI commands: UNMAP, WRITE SAME(10)
and WRITE SAME(16). WRITE SAME commands support both normal write mode
and UNMAP flag. To properly report UNMAP capabilities this patch also adds
support for reporting two new VPD pages: Block limits and Logical Block
Provisioning.
UNMAP support can be enabled per-LUN by adding "-o unmap=on" to `ctladm
create` command line or "option unmap on" to lun sections of /etc/ctl.conf.
At this moment UNMAP supported for ramdisks and device-backed block LUNs.
It was tested to work great with ZFS ZVOLs. For file-backed LUNs UNMAP
support is unfortunately missing due to absence of respective VFS KPI.
Sponsored by: iXsystems, Inc
Diffstat (limited to 'sys/cam/ctl/ctl_backend_ramdisk.c')
-rw-r--r-- | sys/cam/ctl/ctl_backend_ramdisk.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index 191e8e4..272a0a2 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -491,7 +491,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, struct ctl_lun_create_params *params; uint32_t blocksize; char tmpstr[32]; - int i, retval; + int i, retval, unmap; retval = 0; params = &req->reqdata.create; @@ -546,19 +546,27 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, be_lun->softc = softc; + unmap = 0; for (i = 0; i < req->num_be_args; i++) { - struct ctl_be_lun_option *opt; - - opt = malloc(sizeof(*opt), M_RAMDISK, M_WAITOK); - opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_RAMDISK, M_WAITOK); - strcpy(opt->name, req->kern_be_args[i].kname); - opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_RAMDISK, M_WAITOK); - strcpy(opt->value, req->kern_be_args[i].kvalue); - STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links); + if (strcmp(req->kern_be_args[i].kname, "unmap") == 0 && + strcmp(req->kern_be_args[i].kvalue, "on") == 0) { + unmap = 1; + } else { + struct ctl_be_lun_option *opt; + + opt = malloc(sizeof(*opt), M_RAMDISK, M_WAITOK); + opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_RAMDISK, M_WAITOK); + strcpy(opt->name, req->kern_be_args[i].kname); + opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_RAMDISK, M_WAITOK); + strcpy(opt->value, req->kern_be_args[i].kvalue); + STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links); + } } be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED; be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; + if (unmap) + be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP; be_lun->ctl_be_lun.be_lun = be_lun; if (params->flags & CTL_LUN_FLAG_ID_REQ) { @@ -882,6 +890,12 @@ ctl_backend_ramdisk_config_write(union ctl_io *io) ctl_config_write_done(io); break; } + case WRITE_SAME_10: + case WRITE_SAME_16: + case UNMAP: + ctl_set_success(&io->scsiio); + ctl_config_write_done(io); + break; default: ctl_set_invalid_opcode(&io->scsiio); ctl_config_write_done(io); |