diff options
author | Nicholas Bellinger <nab@daterainc.com> | 2013-08-19 14:34:17 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-09-09 14:29:26 -0700 |
commit | a6b0133c19af1ab268ed1f4414efa2782896a870 (patch) | |
tree | ad55c8b08d283a8cf1fa2b3ae6d9a8b0b02b8677 /drivers/target/target_core_transport.c | |
parent | 1c68cc1626341665a8bd1d2c7dfffd7fc852a79c (diff) | |
download | lwn-a6b0133c19af1ab268ed1f4414efa2782896a870.tar.gz lwn-a6b0133c19af1ab268ed1f4414efa2782896a870.zip |
target: Add return for se_cmd->transport_complete_callback
This patch adds a sense_reason_t return to ->transport_complete_callback(),
and updates target_complete_ok_work() to invoke the call if necessary to
transport_send_check_condition_and_sense() during the failure case.
Also update xdreadwrite_callback() to use this return value.
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/target_core_transport.c')
-rw-r--r-- | drivers/target/target_core_transport.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 98ec7110873b..53d1d756f7f5 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1904,10 +1904,24 @@ static void target_complete_ok_work(struct work_struct *work) } /* * Check for a callback, used by amongst other things - * XDWRITE_READ_10 emulation. + * XDWRITE_READ_10 and COMPARE_AND_WRITE emulation. */ - if (cmd->transport_complete_callback) - cmd->transport_complete_callback(cmd); + if (cmd->transport_complete_callback) { + sense_reason_t rc; + + rc = cmd->transport_complete_callback(cmd); + if (!rc) + return; + + ret = transport_send_check_condition_and_sense(cmd, + rc, 0); + if (ret == -EAGAIN || ret == -ENOMEM) + goto queue_full; + + transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + } switch (cmd->data_direction) { case DMA_FROM_DEVICE: |