Skip to content

Commit acda24c

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger: "Here are the outstanding target pending fixes for v3.12-rc7. This includes a number of EXTENDED_COPY related fixes as a result of Thomas and Doug's continuing testing and feedback. Also included is an important vhost/scsi fix that addresses a long standing issue where the 'write' parameter for get_user_pages_fast() was incorrectly set for virtio-scsi WRITEs -> DMA_TO_DEVICE, and not for virtio-scsi READs -> DMA_FROM_DEVICE. This resulted in random userspace segfaults and other unpleasantness on KVM host, and unfortunately has been an issue since the initial merge of vhost/scsi in v3.6. This patch is CC'ed to stable, along with two other less critical items" * git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: vhost/scsi: Fix incorrect usage of get_user_pages_fast write parameter target/pscsi: fix return value check target: Fail XCOPY for non matching source + destination block_size target: Generate failure for XCOPY I/O with non-zero scsi_status target: Add missing XCOPY I/O operation sense_buffer iser-target: check device before dereferencing its variable target: Return an error for WRITE SAME with ANCHOR==1 target: Fix assignment of LUN in tracepoints target: Reject EXTENDED_COPY when emulate_3pc is disabled target: Allow non zero ListID in EXTENDED_COPY parameter list target: Make target_do_xcopy failures return INVALID_PARAMETER_LIST
2 parents 63e6560 + 60a01f5 commit acda24c

File tree

6 files changed

+50
-24
lines changed

6 files changed

+50
-24
lines changed

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ isert_connect_release(struct isert_conn *isert_conn)
594594

595595
pr_debug("Entering isert_connect_release(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
596596

597-
if (device->use_frwr)
597+
if (device && device->use_frwr)
598598
isert_conn_free_frwr_pool(isert_conn);
599599

600600
if (isert_conn->conn_qp) {

drivers/target/target_core_pscsi.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ static int pscsi_pmode_enable_hba(struct se_hba *hba, unsigned long mode_flag)
134134
* pSCSI Host ID and enable for phba mode
135135
*/
136136
sh = scsi_host_lookup(phv->phv_host_id);
137-
if (IS_ERR(sh)) {
137+
if (!sh) {
138138
pr_err("pSCSI: Unable to locate SCSI Host for"
139139
" phv_host_id: %d\n", phv->phv_host_id);
140-
return PTR_ERR(sh);
140+
return -EINVAL;
141141
}
142142

143143
phv->phv_lld_host = sh;
@@ -515,10 +515,10 @@ static int pscsi_configure_device(struct se_device *dev)
515515
sh = phv->phv_lld_host;
516516
} else {
517517
sh = scsi_host_lookup(pdv->pdv_host_id);
518-
if (IS_ERR(sh)) {
518+
if (!sh) {
519519
pr_err("pSCSI: Unable to locate"
520520
" pdv_host_id: %d\n", pdv->pdv_host_id);
521-
return PTR_ERR(sh);
521+
return -EINVAL;
522522
}
523523
}
524524
} else {

drivers/target/target_core_sbc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
263263
sectors, cmd->se_dev->dev_attrib.max_write_same_len);
264264
return TCM_INVALID_CDB_FIELD;
265265
}
266+
/* We always have ANC_SUP == 0 so setting ANCHOR is always an error */
267+
if (flags[0] & 0x10) {
268+
pr_warn("WRITE SAME with ANCHOR not supported\n");
269+
return TCM_INVALID_CDB_FIELD;
270+
}
266271
/*
267272
* Special case for WRITE_SAME w/ UNMAP=1 that ends up getting
268273
* translated into block discard requests within backend code.

drivers/target/target_core_xcopy.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op
8282
mutex_lock(&g_device_mutex);
8383
list_for_each_entry(se_dev, &g_device_list, g_dev_node) {
8484

85+
if (!se_dev->dev_attrib.emulate_3pc)
86+
continue;
87+
8588
memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN);
8689
target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]);
8790

@@ -357,6 +360,7 @@ struct xcopy_pt_cmd {
357360
struct se_cmd se_cmd;
358361
struct xcopy_op *xcopy_op;
359362
struct completion xpt_passthrough_sem;
363+
unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER];
360364
};
361365

362366
static struct se_port xcopy_pt_port;
@@ -675,7 +679,8 @@ static int target_xcopy_issue_pt_cmd(struct xcopy_pt_cmd *xpt_cmd)
675679

676680
pr_debug("target_xcopy_issue_pt_cmd(): SCSI status: 0x%02x\n",
677681
se_cmd->scsi_status);
678-
return 0;
682+
683+
return (se_cmd->scsi_status) ? -EINVAL : 0;
679684
}
680685

681686
static int target_xcopy_read_source(
@@ -708,7 +713,7 @@ static int target_xcopy_read_source(
708713
(unsigned long long)src_lba, src_sectors, length);
709714

710715
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length,
711-
DMA_FROM_DEVICE, 0, NULL);
716+
DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]);
712717
xop->src_pt_cmd = xpt_cmd;
713718

714719
rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0],
@@ -768,7 +773,7 @@ static int target_xcopy_write_destination(
768773
(unsigned long long)dst_lba, dst_sectors, length);
769774

770775
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length,
771-
DMA_TO_DEVICE, 0, NULL);
776+
DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]);
772777
xop->dst_pt_cmd = xpt_cmd;
773778

774779
rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, dst_dev, &cdb[0],
@@ -884,30 +889,42 @@ static void target_xcopy_do_work(struct work_struct *work)
884889

885890
sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
886891
{
892+
struct se_device *dev = se_cmd->se_dev;
887893
struct xcopy_op *xop = NULL;
888894
unsigned char *p = NULL, *seg_desc;
889895
unsigned int list_id, list_id_usage, sdll, inline_dl, sa;
896+
sense_reason_t ret = TCM_INVALID_PARAMETER_LIST;
890897
int rc;
891898
unsigned short tdll;
892899

900+
if (!dev->dev_attrib.emulate_3pc) {
901+
pr_err("EXTENDED_COPY operation explicitly disabled\n");
902+
return TCM_UNSUPPORTED_SCSI_OPCODE;
903+
}
904+
893905
sa = se_cmd->t_task_cdb[1] & 0x1f;
894906
if (sa != 0x00) {
895907
pr_err("EXTENDED_COPY(LID4) not supported\n");
896908
return TCM_UNSUPPORTED_SCSI_OPCODE;
897909
}
898910

911+
xop = kzalloc(sizeof(struct xcopy_op), GFP_KERNEL);
912+
if (!xop) {
913+
pr_err("Unable to allocate xcopy_op\n");
914+
return TCM_OUT_OF_RESOURCES;
915+
}
916+
xop->xop_se_cmd = se_cmd;
917+
899918
p = transport_kmap_data_sg(se_cmd);
900919
if (!p) {
901920
pr_err("transport_kmap_data_sg() failed in target_do_xcopy\n");
921+
kfree(xop);
902922
return TCM_OUT_OF_RESOURCES;
903923
}
904924

905925
list_id = p[0];
906-
if (list_id != 0x00) {
907-
pr_err("XCOPY with non zero list_id: 0x%02x\n", list_id);
908-
goto out;
909-
}
910-
list_id_usage = (p[1] & 0x18);
926+
list_id_usage = (p[1] & 0x18) >> 3;
927+
911928
/*
912929
* Determine TARGET DESCRIPTOR LIST LENGTH + SEGMENT DESCRIPTOR LIST LENGTH
913930
*/
@@ -920,13 +937,6 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
920937
goto out;
921938
}
922939

923-
xop = kzalloc(sizeof(struct xcopy_op), GFP_KERNEL);
924-
if (!xop) {
925-
pr_err("Unable to allocate xcopy_op\n");
926-
goto out;
927-
}
928-
xop->xop_se_cmd = se_cmd;
929-
930940
pr_debug("Processing XCOPY with list_id: 0x%02x list_id_usage: 0x%02x"
931941
" tdll: %hu sdll: %u inline_dl: %u\n", list_id, list_id_usage,
932942
tdll, sdll, inline_dl);
@@ -935,6 +945,17 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
935945
if (rc <= 0)
936946
goto out;
937947

948+
if (xop->src_dev->dev_attrib.block_size !=
949+
xop->dst_dev->dev_attrib.block_size) {
950+
pr_err("XCOPY: Non matching src_dev block_size: %u + dst_dev"
951+
" block_size: %u currently unsupported\n",
952+
xop->src_dev->dev_attrib.block_size,
953+
xop->dst_dev->dev_attrib.block_size);
954+
xcopy_pt_undepend_remotedev(xop);
955+
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
956+
goto out;
957+
}
958+
938959
pr_debug("XCOPY: Processed %d target descriptors, length: %u\n", rc,
939960
rc * XCOPY_TARGET_DESC_LEN);
940961
seg_desc = &p[16];
@@ -957,7 +978,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
957978
if (p)
958979
transport_kunmap_data_sg(se_cmd);
959980
kfree(xop);
960-
return TCM_INVALID_CDB_FIELD;
981+
return ret;
961982
}
962983

963984
static sense_reason_t target_rcr_operating_parameters(struct se_cmd *se_cmd)

drivers/vhost/scsi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
10561056
if (data_direction != DMA_NONE) {
10571057
ret = vhost_scsi_map_iov_to_sgl(cmd,
10581058
&vq->iov[data_first], data_num,
1059-
data_direction == DMA_TO_DEVICE);
1059+
data_direction == DMA_FROM_DEVICE);
10601060
if (unlikely(ret)) {
10611061
vq_err(vq, "Failed to map iov to sgl\n");
10621062
goto err_free;

include/trace/events/target.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ TRACE_EVENT(target_sequencer_start,
144144
),
145145

146146
TP_fast_assign(
147-
__entry->unpacked_lun = cmd->se_lun->unpacked_lun;
147+
__entry->unpacked_lun = cmd->orig_fe_lun;
148148
__entry->opcode = cmd->t_task_cdb[0];
149149
__entry->data_length = cmd->data_length;
150150
__entry->task_attribute = cmd->sam_task_attr;
@@ -182,7 +182,7 @@ TRACE_EVENT(target_cmd_complete,
182182
),
183183

184184
TP_fast_assign(
185-
__entry->unpacked_lun = cmd->se_lun->unpacked_lun;
185+
__entry->unpacked_lun = cmd->orig_fe_lun;
186186
__entry->opcode = cmd->t_task_cdb[0];
187187
__entry->data_length = cmd->data_length;
188188
__entry->task_attribute = cmd->sam_task_attr;

0 commit comments

Comments
 (0)