diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-24 00:27:00 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-24 00:28:52 -0700 |
commit | 48502ddbfb9840803f633ff81eee507e0fdae7c5 (patch) | |
tree | d692d4a0191a51efd0273bce3c3aa5274c50f5ad | |
parent | 8a955d6dcc1840fa9cba73eb6db831c8fea19d95 (diff) | |
download | linux-stable-48502ddbfb9840803f633ff81eee507e0fdae7c5.tar.gz linux-stable-48502ddbfb9840803f633ff81eee507e0fdae7c5.tar.bz2 linux-stable-48502ddbfb9840803f633ff81eee507e0fdae7c5.zip |
target: Fail XCOPY for non matching source + destination block_size
This patch adds an explicit check + failure for XCOPY I/O to source +
destination devices with a non-matching block_size.
This limitiation is currently due to the fact that the scatterlist
memory allocated for the XCOPY READ operation is passed zero-copy
to the XCOPY WRITE operation.
Reported-by: Thomas Glanzmann <thomas@glanzmann.de>
Reported-by: Douglas Gilbert <dgilbert@interlog.com>
Cc: Thomas Glanzmann <thomas@glanzmann.de>
Cc: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_xcopy.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 0e41143fc16e..474cd44fac14 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -893,6 +893,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd) struct xcopy_op *xop = NULL; unsigned char *p = NULL, *seg_desc; unsigned int list_id, list_id_usage, sdll, inline_dl, sa; + sense_reason_t ret = TCM_INVALID_PARAMETER_LIST; int rc; unsigned short tdll; @@ -944,6 +945,17 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd) if (rc <= 0) goto out; + if (xop->src_dev->dev_attrib.block_size != + xop->dst_dev->dev_attrib.block_size) { + pr_err("XCOPY: Non matching src_dev block_size: %u + dst_dev" + " block_size: %u currently unsupported\n", + xop->src_dev->dev_attrib.block_size, + xop->dst_dev->dev_attrib.block_size); + xcopy_pt_undepend_remotedev(xop); + ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + goto out; + } + pr_debug("XCOPY: Processed %d target descriptors, length: %u\n", rc, rc * XCOPY_TARGET_DESC_LEN); seg_desc = &p[16]; @@ -966,7 +978,7 @@ out: if (p) transport_kunmap_data_sg(se_cmd); kfree(xop); - return TCM_INVALID_PARAMETER_LIST; + return ret; } static sense_reason_t target_rcr_operating_parameters(struct se_cmd *se_cmd) |