diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-06-17 18:40:54 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-07-16 20:34:41 -0400 |
commit | 6f974e8ce7b3f661910a49c7c2ba095631f341e9 (patch) | |
tree | 5698f1ed849b92eec547571594a68183c592b590 /drivers/target | |
parent | ad67f0d9e63ca94661e06a145f05a9302368a826 (diff) |
target: move write_same to struct spc_ops
Add spc_ops->execute_write_same() caller for ->execute_cmd() setup,
and update IBLOCK backends to use it.
(nab: add export of spc_get_write_same_sectors symbol)
(roland: Carry forward: Fix range calculation in WRITE SAME emulation
when num blocks == 0)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_iblock.c | 18 | ||||
-rw-r--r-- | drivers/target/target_core_sbc.c | 52 |
2 files changed, 36 insertions, 34 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 863c962e5021..ee70cc9f6a64 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -327,6 +327,23 @@ static int iblock_do_discard(struct se_device *dev, sector_t lba, u32 range) | |||
327 | return blkdev_issue_discard(bd, lba, range, GFP_KERNEL, barrier); | 327 | return blkdev_issue_discard(bd, lba, range, GFP_KERNEL, barrier); |
328 | } | 328 | } |
329 | 329 | ||
330 | static int iblock_execute_write_same(struct se_cmd *cmd) | ||
331 | { | ||
332 | struct iblock_dev *ibd = cmd->se_dev->dev_ptr; | ||
333 | int ret; | ||
334 | |||
335 | ret = blkdev_issue_discard(ibd->ibd_bd, cmd->t_task_lba, | ||
336 | spc_get_write_same_sectors(cmd), GFP_KERNEL, | ||
337 | 0); | ||
338 | if (ret < 0) { | ||
339 | pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); | ||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | target_complete_cmd(cmd, GOOD); | ||
344 | return 0; | ||
345 | } | ||
346 | |||
330 | enum { | 347 | enum { |
331 | Opt_udev_path, Opt_readonly, Opt_force, Opt_err | 348 | Opt_udev_path, Opt_readonly, Opt_force, Opt_err |
332 | }; | 349 | }; |
@@ -669,6 +686,7 @@ static void iblock_bio_done(struct bio *bio, int err) | |||
669 | static struct spc_ops iblock_spc_ops = { | 686 | static struct spc_ops iblock_spc_ops = { |
670 | .execute_rw = iblock_execute_rw, | 687 | .execute_rw = iblock_execute_rw, |
671 | .execute_sync_cache = iblock_execute_sync_cache, | 688 | .execute_sync_cache = iblock_execute_sync_cache, |
689 | .execute_write_same = iblock_execute_write_same, | ||
672 | }; | 690 | }; |
673 | 691 | ||
674 | static int iblock_parse_cdb(struct se_cmd *cmd) | 692 | static int iblock_parse_cdb(struct se_cmd *cmd) |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 377c5105e270..146ca372489b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -156,24 +156,9 @@ err: | |||
156 | return ret; | 156 | return ret; |
157 | } | 157 | } |
158 | 158 | ||
159 | /* | 159 | int spc_get_write_same_sectors(struct se_cmd *cmd) |
160 | * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. | ||
161 | * Note this is not used for TCM/pSCSI passthrough | ||
162 | */ | ||
163 | static int sbc_emulate_write_same(struct se_cmd *cmd) | ||
164 | { | 160 | { |
165 | struct se_device *dev = cmd->se_dev; | ||
166 | sector_t range; | ||
167 | sector_t lba = cmd->t_task_lba; | ||
168 | u32 num_blocks; | 161 | u32 num_blocks; |
169 | int ret; | ||
170 | |||
171 | if (!dev->transport->do_discard) { | ||
172 | pr_err("WRITE_SAME emulation not supported" | ||
173 | " for: %s\n", dev->transport->name); | ||
174 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
175 | return -ENOSYS; | ||
176 | } | ||
177 | 162 | ||
178 | if (cmd->t_task_cdb[0] == WRITE_SAME) | 163 | if (cmd->t_task_cdb[0] == WRITE_SAME) |
179 | num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); | 164 | num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); |
@@ -186,23 +171,13 @@ static int sbc_emulate_write_same(struct se_cmd *cmd) | |||
186 | * Use the explicit range when non zero is supplied, otherwise calculate | 171 | * Use the explicit range when non zero is supplied, otherwise calculate |
187 | * the remaining range based on ->get_blocks() - starting LBA. | 172 | * the remaining range based on ->get_blocks() - starting LBA. |
188 | */ | 173 | */ |
189 | if (num_blocks != 0) | 174 | if (num_blocks) |
190 | range = num_blocks; | 175 | return num_blocks; |
191 | else | ||
192 | range = (dev->transport->get_blocks(dev) - lba) + 1; | ||
193 | 176 | ||
194 | pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", | 177 | return cmd->se_dev->transport->get_blocks(cmd->se_dev) - |
195 | (unsigned long long)lba, (unsigned long long)range); | 178 | cmd->t_task_lba + 1; |
196 | |||
197 | ret = dev->transport->do_discard(dev, lba, range); | ||
198 | if (ret < 0) { | ||
199 | pr_debug("blkdev_issue_discard() failed for WRITE_SAME\n"); | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | target_complete_cmd(cmd, GOOD); | ||
204 | return 0; | ||
205 | } | 179 | } |
180 | EXPORT_SYMBOL(spc_get_write_same_sectors); | ||
206 | 181 | ||
207 | static int sbc_emulate_verify(struct se_cmd *cmd) | 182 | static int sbc_emulate_verify(struct se_cmd *cmd) |
208 | { | 183 | { |
@@ -488,6 +463,9 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
488 | cmd->se_cmd_flags |= SCF_FUA; | 463 | cmd->se_cmd_flags |= SCF_FUA; |
489 | break; | 464 | break; |
490 | case WRITE_SAME_32: | 465 | case WRITE_SAME_32: |
466 | if (!ops->execute_write_same) | ||
467 | goto out_unsupported_cdb; | ||
468 | |||
491 | sectors = transport_get_sectors_32(cdb); | 469 | sectors = transport_get_sectors_32(cdb); |
492 | if (!sectors) { | 470 | if (!sectors) { |
493 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" | 471 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not" |
@@ -500,7 +478,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
500 | 478 | ||
501 | if (sbc_write_same_supported(dev, &cdb[10]) < 0) | 479 | if (sbc_write_same_supported(dev, &cdb[10]) < 0) |
502 | goto out_unsupported_cdb; | 480 | goto out_unsupported_cdb; |
503 | cmd->execute_cmd = sbc_emulate_write_same; | 481 | cmd->execute_cmd = ops->execute_write_same; |
504 | break; | 482 | break; |
505 | default: | 483 | default: |
506 | pr_err("VARIABLE_LENGTH_CMD service action" | 484 | pr_err("VARIABLE_LENGTH_CMD service action" |
@@ -559,6 +537,9 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
559 | cmd->execute_cmd = sbc_emulate_unmap; | 537 | cmd->execute_cmd = sbc_emulate_unmap; |
560 | break; | 538 | break; |
561 | case WRITE_SAME_16: | 539 | case WRITE_SAME_16: |
540 | if (!ops->execute_write_same) | ||
541 | goto out_unsupported_cdb; | ||
542 | |||
562 | sectors = transport_get_sectors_16(cdb); | 543 | sectors = transport_get_sectors_16(cdb); |
563 | if (!sectors) { | 544 | if (!sectors) { |
564 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 545 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
@@ -570,9 +551,12 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
570 | 551 | ||
571 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 552 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) |
572 | goto out_unsupported_cdb; | 553 | goto out_unsupported_cdb; |
573 | cmd->execute_cmd = sbc_emulate_write_same; | 554 | cmd->execute_cmd = ops->execute_write_same; |
574 | break; | 555 | break; |
575 | case WRITE_SAME: | 556 | case WRITE_SAME: |
557 | if (!ops->execute_write_same) | ||
558 | goto out_unsupported_cdb; | ||
559 | |||
576 | sectors = transport_get_sectors_10(cdb); | 560 | sectors = transport_get_sectors_10(cdb); |
577 | if (!sectors) { | 561 | if (!sectors) { |
578 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); | 562 | pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n"); |
@@ -588,7 +572,7 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) | |||
588 | */ | 572 | */ |
589 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) | 573 | if (sbc_write_same_supported(dev, &cdb[1]) < 0) |
590 | goto out_unsupported_cdb; | 574 | goto out_unsupported_cdb; |
591 | cmd->execute_cmd = sbc_emulate_write_same; | 575 | cmd->execute_cmd = ops->execute_write_same; |
592 | break; | 576 | break; |
593 | case VERIFY: | 577 | case VERIFY: |
594 | size = 0; | 578 | size = 0; |