aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-06-17 18:40:54 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-07-16 20:34:41 -0400
commit6f974e8ce7b3f661910a49c7c2ba095631f341e9 (patch)
tree5698f1ed849b92eec547571594a68183c592b590 /drivers/target
parentad67f0d9e63ca94661e06a145f05a9302368a826 (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.c18
-rw-r--r--drivers/target/target_core_sbc.c52
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
330static 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
330enum { 347enum {
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)
669static struct spc_ops iblock_spc_ops = { 686static 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
674static int iblock_parse_cdb(struct se_cmd *cmd) 692static 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/* 159int 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 */
163static 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}
180EXPORT_SYMBOL(spc_get_write_same_sectors);
206 181
207static int sbc_emulate_verify(struct se_cmd *cmd) 182static 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;