diff options
author | Nicholas Bellinger <nab@daterainc.com> | 2013-08-20 02:57:30 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-09-09 17:29:28 -0400 |
commit | a82a9538dd30471e6428a2d55e91e986c439866b (patch) | |
tree | 439d70dae8fd42cc19922a31d1ac2a6ecf9c32fb /drivers/target | |
parent | 818b571ca053e19be336de1cc75c01dd5445e969 (diff) |
target: Allow sbc_ops->execute_rw() to accept SGLs + data_direction
COMPARE_AND_WRITE expects to be able to send down a DMA_FROM_DEVICE
to obtain the necessary READ payload for comparision against the
first half of the WRITE payload containing the verify user data.
Currently virtual backends expect to internally reference SGLs,
SGL nents, and data_direction, so change IBLOCK, FILEIO and RD
sbc_ops->execute_rw() to accept this values as function parameters.
Also add default sbc_execute_rw() handler for the typical case for
cmd->execute_rw() submission using cmd->t_data_sg, cmd->t_data_nents,
and cmd->data_direction).
v2 Changes:
- Add SCF_COMPARE_AND_WRITE command flag
- Use sbc_execute_rw() for normal cmd->execute_rw() submission
with expected se_cmd members.
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Martin Petersen <martin.petersen@oracle.com>
Cc: Chris Mason <chris.mason@fusionio.com>
Cc: James Bottomley <JBottomley@Parallels.com>
Cc: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_file.c | 6 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 6 | ||||
-rw-r--r-- | drivers/target/target_core_rd.c | 6 | ||||
-rw-r--r-- | drivers/target/target_core_sbc.c | 37 |
4 files changed, 33 insertions, 22 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index bc3245dfcdf7..c5448a5d8b73 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -547,11 +547,9 @@ fd_execute_unmap(struct se_cmd *cmd) | |||
547 | } | 547 | } |
548 | 548 | ||
549 | static sense_reason_t | 549 | static sense_reason_t |
550 | fd_execute_rw(struct se_cmd *cmd) | 550 | fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, |
551 | enum dma_data_direction data_direction) | ||
551 | { | 552 | { |
552 | struct scatterlist *sgl = cmd->t_data_sg; | ||
553 | u32 sgl_nents = cmd->t_data_nents; | ||
554 | enum dma_data_direction data_direction = cmd->data_direction; | ||
555 | struct se_device *dev = cmd->se_dev; | 553 | struct se_device *dev = cmd->se_dev; |
556 | int ret = 0; | 554 | int ret = 0; |
557 | 555 | ||
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 0a460f3350eb..81464eb59f0c 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -587,11 +587,9 @@ static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b) | |||
587 | } | 587 | } |
588 | 588 | ||
589 | static sense_reason_t | 589 | static sense_reason_t |
590 | iblock_execute_rw(struct se_cmd *cmd) | 590 | iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, |
591 | enum dma_data_direction data_direction) | ||
591 | { | 592 | { |
592 | struct scatterlist *sgl = cmd->t_data_sg; | ||
593 | u32 sgl_nents = cmd->t_data_nents; | ||
594 | enum dma_data_direction data_direction = cmd->data_direction; | ||
595 | struct se_device *dev = cmd->se_dev; | 593 | struct se_device *dev = cmd->se_dev; |
596 | struct iblock_req *ibr; | 594 | struct iblock_req *ibr; |
597 | struct bio *bio; | 595 | struct bio *bio; |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 51127d15d5c5..958d17ad1c90 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -280,11 +280,9 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | static sense_reason_t | 282 | static sense_reason_t |
283 | rd_execute_rw(struct se_cmd *cmd) | 283 | rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, |
284 | enum dma_data_direction data_direction) | ||
284 | { | 285 | { |
285 | struct scatterlist *sgl = cmd->t_data_sg; | ||
286 | u32 sgl_nents = cmd->t_data_nents; | ||
287 | enum dma_data_direction data_direction = cmd->data_direction; | ||
288 | struct se_device *se_dev = cmd->se_dev; | 286 | struct se_device *se_dev = cmd->se_dev; |
289 | struct rd_dev *dev = RD_DEV(se_dev); | 287 | struct rd_dev *dev = RD_DEV(se_dev); |
290 | struct rd_dev_sg_table *table; | 288 | struct rd_dev_sg_table *table; |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index be5234abb76c..5569b3697103 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -337,6 +337,13 @@ out: | |||
337 | return ret; | 337 | return ret; |
338 | } | 338 | } |
339 | 339 | ||
340 | static sense_reason_t | ||
341 | sbc_execute_rw(struct se_cmd *cmd) | ||
342 | { | ||
343 | return cmd->execute_rw(cmd, cmd->t_data_sg, cmd->t_data_nents, | ||
344 | cmd->data_direction); | ||
345 | } | ||
346 | |||
340 | sense_reason_t | 347 | sense_reason_t |
341 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | 348 | sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) |
342 | { | 349 | { |
@@ -351,31 +358,36 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
351 | sectors = transport_get_sectors_6(cdb); | 358 | sectors = transport_get_sectors_6(cdb); |
352 | cmd->t_task_lba = transport_lba_21(cdb); | 359 | cmd->t_task_lba = transport_lba_21(cdb); |
353 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 360 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
354 | cmd->execute_cmd = ops->execute_rw; | 361 | cmd->execute_rw = ops->execute_rw; |
362 | cmd->execute_cmd = sbc_execute_rw; | ||
355 | break; | 363 | break; |
356 | case READ_10: | 364 | case READ_10: |
357 | sectors = transport_get_sectors_10(cdb); | 365 | sectors = transport_get_sectors_10(cdb); |
358 | cmd->t_task_lba = transport_lba_32(cdb); | 366 | cmd->t_task_lba = transport_lba_32(cdb); |
359 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 367 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
360 | cmd->execute_cmd = ops->execute_rw; | 368 | cmd->execute_rw = ops->execute_rw; |
369 | cmd->execute_cmd = sbc_execute_rw; | ||
361 | break; | 370 | break; |
362 | case READ_12: | 371 | case READ_12: |
363 | sectors = transport_get_sectors_12(cdb); | 372 | sectors = transport_get_sectors_12(cdb); |
364 | cmd->t_task_lba = transport_lba_32(cdb); | 373 | cmd->t_task_lba = transport_lba_32(cdb); |
365 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 374 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
366 | cmd->execute_cmd = ops->execute_rw; | 375 | cmd->execute_rw = ops->execute_rw; |
376 | cmd->execute_cmd = sbc_execute_rw; | ||
367 | break; | 377 | break; |
368 | case READ_16: | 378 | case READ_16: |
369 | sectors = transport_get_sectors_16(cdb); | 379 | sectors = transport_get_sectors_16(cdb); |
370 | cmd->t_task_lba = transport_lba_64(cdb); | 380 | cmd->t_task_lba = transport_lba_64(cdb); |
371 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 381 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
372 | cmd->execute_cmd = ops->execute_rw; | 382 | cmd->execute_rw = ops->execute_rw; |
383 | cmd->execute_cmd = sbc_execute_rw; | ||
373 | break; | 384 | break; |
374 | case WRITE_6: | 385 | case WRITE_6: |
375 | sectors = transport_get_sectors_6(cdb); | 386 | sectors = transport_get_sectors_6(cdb); |
376 | cmd->t_task_lba = transport_lba_21(cdb); | 387 | cmd->t_task_lba = transport_lba_21(cdb); |
377 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 388 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
378 | cmd->execute_cmd = ops->execute_rw; | 389 | cmd->execute_rw = ops->execute_rw; |
390 | cmd->execute_cmd = sbc_execute_rw; | ||
379 | break; | 391 | break; |
380 | case WRITE_10: | 392 | case WRITE_10: |
381 | case WRITE_VERIFY: | 393 | case WRITE_VERIFY: |
@@ -384,7 +396,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
384 | if (cdb[1] & 0x8) | 396 | if (cdb[1] & 0x8) |
385 | cmd->se_cmd_flags |= SCF_FUA; | 397 | cmd->se_cmd_flags |= SCF_FUA; |
386 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 398 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
387 | cmd->execute_cmd = ops->execute_rw; | 399 | cmd->execute_rw = ops->execute_rw; |
400 | cmd->execute_cmd = sbc_execute_rw; | ||
388 | break; | 401 | break; |
389 | case WRITE_12: | 402 | case WRITE_12: |
390 | sectors = transport_get_sectors_12(cdb); | 403 | sectors = transport_get_sectors_12(cdb); |
@@ -392,7 +405,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
392 | if (cdb[1] & 0x8) | 405 | if (cdb[1] & 0x8) |
393 | cmd->se_cmd_flags |= SCF_FUA; | 406 | cmd->se_cmd_flags |= SCF_FUA; |
394 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 407 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
395 | cmd->execute_cmd = ops->execute_rw; | 408 | cmd->execute_rw = ops->execute_rw; |
409 | cmd->execute_cmd = sbc_execute_rw; | ||
396 | break; | 410 | break; |
397 | case WRITE_16: | 411 | case WRITE_16: |
398 | sectors = transport_get_sectors_16(cdb); | 412 | sectors = transport_get_sectors_16(cdb); |
@@ -400,7 +414,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
400 | if (cdb[1] & 0x8) | 414 | if (cdb[1] & 0x8) |
401 | cmd->se_cmd_flags |= SCF_FUA; | 415 | cmd->se_cmd_flags |= SCF_FUA; |
402 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; | 416 | cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; |
403 | cmd->execute_cmd = ops->execute_rw; | 417 | cmd->execute_rw = ops->execute_rw; |
418 | cmd->execute_cmd = sbc_execute_rw; | ||
404 | break; | 419 | break; |
405 | case XDWRITEREAD_10: | 420 | case XDWRITEREAD_10: |
406 | if (cmd->data_direction != DMA_TO_DEVICE || | 421 | if (cmd->data_direction != DMA_TO_DEVICE || |
@@ -414,7 +429,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
414 | /* | 429 | /* |
415 | * Setup BIDI XOR callback to be run after I/O completion. | 430 | * Setup BIDI XOR callback to be run after I/O completion. |
416 | */ | 431 | */ |
417 | cmd->execute_cmd = ops->execute_rw; | 432 | cmd->execute_rw = ops->execute_rw; |
433 | cmd->execute_cmd = sbc_execute_rw; | ||
418 | cmd->transport_complete_callback = &xdreadwrite_callback; | 434 | cmd->transport_complete_callback = &xdreadwrite_callback; |
419 | if (cdb[1] & 0x8) | 435 | if (cdb[1] & 0x8) |
420 | cmd->se_cmd_flags |= SCF_FUA; | 436 | cmd->se_cmd_flags |= SCF_FUA; |
@@ -437,7 +453,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
437 | * Setup BIDI XOR callback to be run during after I/O | 453 | * Setup BIDI XOR callback to be run during after I/O |
438 | * completion. | 454 | * completion. |
439 | */ | 455 | */ |
440 | cmd->execute_cmd = ops->execute_rw; | 456 | cmd->execute_rw = ops->execute_rw; |
457 | cmd->execute_cmd = sbc_execute_rw; | ||
441 | cmd->transport_complete_callback = &xdreadwrite_callback; | 458 | cmd->transport_complete_callback = &xdreadwrite_callback; |
442 | if (cdb[1] & 0x8) | 459 | if (cdb[1] & 0x8) |
443 | cmd->se_cmd_flags |= SCF_FUA; | 460 | cmd->se_cmd_flags |= SCF_FUA; |