diff options
author | Nicholas Bellinger <nab@daterainc.com> | 2013-08-25 16:10:57 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-09-09 14:29:32 -0700 |
commit | 8cefe07b5e9c2b0212ad6809a219e4489807a746 (patch) | |
tree | 7396ced8cbb14370c506479a307a38790e41a7be /drivers/target | |
parent | 200939940e040fa11609956a09c78a5782310c61 (diff) | |
download | linux-8cefe07b5e9c2b0212ad6809a219e4489807a746.tar.bz2 |
target: Do memory allocation for bidi commands using target_alloc_sgl
This patch updates transport_generic_new_cmd() to call target_alloc_sgl()
for SGL + page memory allocation for se_cmd->t_bidi_data_sg.
It also adds the special case for SCF_COMPARE_AND_WRITE to calculate a
different bidi_length based upon se_cmd->t_task_nolb.
Reported-by: Christoph Hellwig <hch@lst.de>
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_transport.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 607bc3d2bb40..c974e1373c77 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2149,6 +2149,23 @@ transport_generic_new_cmd(struct se_cmd *cmd) cmd->data_length) { bool zero_flag = !(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB); + if ((cmd->se_cmd_flags & SCF_BIDI) || + (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) { + u32 bidi_length; + + if (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) + bidi_length = cmd->t_task_nolb * + cmd->se_dev->dev_attrib.block_size; + else + bidi_length = cmd->data_length; + + ret = target_alloc_sgl(&cmd->t_bidi_data_sg, + &cmd->t_bidi_data_nents, + bidi_length, zero_flag); + if (ret < 0) + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } + ret = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents, cmd->data_length, zero_flag); if (ret < 0) |