Skip to content

Commit a55da8a

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 v4.9-rc2. This includes: - Fix v4.1.y+ reference leak regression with concurrent TMR ABORT_TASK + session shutdown. (Vaibhav Tandon) - Enable tcm_fc w/ SCF_USE_CPUID to avoid host exchange timeouts (Hannes) - target/user error sense handling fixes. (Andy + MNC + HCH) - Fix iscsi-target NOP_OUT error path iscsi_cmd descriptor leak (Varun) - Two EXTENDED_COPY SCSI status fixes for ESX VAAI (Dinesh Israni + Nixon Vincent) - Revert a v4.8 residual overflow change, that breaks sg_inq with small allocation lengths. There are a number of folks stress testing the v4.1.y regression fix in their environments, and more folks doing iser-target I/O stress testing atop recent v4.x.y code. There is also one v4.2.y+ RCU conversion regression related to explicit NodeACL configfs changes, that is still being tracked down" * git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: target/tcm_fc: use CPU affinity for responses target/tcm_fc: Update debugging statements to match libfc usage target/tcm_fc: return detailed error in ft_sess_create() target/tcm_fc: print command pointer in debug message target: fix potential race window in target_sess_cmd_list_waiting() Revert "target: Fix residual overflow handling in target_complete_cmd_with_length" target: Don't override EXTENDED_COPY xcopy_pt_cmd SCSI status code target: Make EXTENDED_COPY 0xe4 failure return COPY TARGET DEVICE NOT REACHABLE target: Re-add missing SCF_ACK_KREF assignment in v4.1.y iscsi-target: fix iscsi cmd leak iscsi-target: fix spelling mistake "Unsolicitied" -> "Unsolicited" target/user: Fix comments to not refer to data ring target/user: Return an error if cmd data size is too large target/user: Use sense_reason_t in tcmu_queue_cmd_ring
2 parents e6995f2 + 1ba0158 commit a55da8a

8 files changed

Lines changed: 105 additions & 75 deletions

File tree

drivers/target/iscsi/iscsi_target.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,10 @@ int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
18041804
* Otherwise, initiator is not expecting a NOPIN is response.
18051805
* Just ignore for now.
18061806
*/
1807+
1808+
if (cmd)
1809+
iscsit_free_cmd(cmd, false);
1810+
18071811
return 0;
18081812
}
18091813
EXPORT_SYMBOL(iscsit_process_nop_out);
@@ -2982,7 +2986,7 @@ iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
29822986

29832987
pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x,"
29842988
" StatSN: 0x%08x, Length %u\n", (nopout_response) ?
2985-
"Solicitied" : "Unsolicitied", cmd->init_task_tag,
2989+
"Solicited" : "Unsolicited", cmd->init_task_tag,
29862990
cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
29872991
}
29882992
EXPORT_SYMBOL(iscsit_build_nopin_rsp);

drivers/target/iscsi/iscsi_target_login.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ static int iscsi_login_zero_tsih_s2(
434434

435435
/*
436436
* Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
437-
* Immediate Data + Unsolicitied Data-OUT if necessary..
437+
* Immediate Data + Unsolicited Data-OUT if necessary..
438438
*/
439439
param = iscsi_find_param_from_key("MaxRecvDataSegmentLength",
440440
conn->param_list);
@@ -646,7 +646,7 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
646646
{
647647
struct iscsi_session *sess = conn->sess;
648648
/*
649-
* FIXME: Unsolicitied NopIN support for ISER
649+
* FIXME: Unsolicited NopIN support for ISER
650650
*/
651651
if (conn->conn_transport->transport_type == ISCSI_INFINIBAND)
652652
return;

drivers/target/target_core_transport.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -754,15 +754,7 @@ EXPORT_SYMBOL(target_complete_cmd);
754754

755755
void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
756756
{
757-
if (scsi_status != SAM_STAT_GOOD) {
758-
return;
759-
}
760-
761-
/*
762-
* Calculate new residual count based upon length of SCSI data
763-
* transferred.
764-
*/
765-
if (length < cmd->data_length) {
757+
if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) {
766758
if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
767759
cmd->residual_count += cmd->data_length - length;
768760
} else {
@@ -771,12 +763,6 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len
771763
}
772764

773765
cmd->data_length = length;
774-
} else if (length > cmd->data_length) {
775-
cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;
776-
cmd->residual_count = length - cmd->data_length;
777-
} else {
778-
cmd->se_cmd_flags &= ~(SCF_OVERFLOW_BIT | SCF_UNDERFLOW_BIT);
779-
cmd->residual_count = 0;
780766
}
781767

782768
target_complete_cmd(cmd, scsi_status);
@@ -1706,6 +1692,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
17061692
case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED:
17071693
case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED:
17081694
case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED:
1695+
case TCM_COPY_TARGET_DEVICE_NOT_REACHABLE:
17091696
break;
17101697
case TCM_OUT_OF_RESOURCES:
17111698
sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -2547,8 +2534,12 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
25472534
* fabric acknowledgement that requires two target_put_sess_cmd()
25482535
* invocations before se_cmd descriptor release.
25492536
*/
2550-
if (ack_kref)
2551-
kref_get(&se_cmd->cmd_kref);
2537+
if (ack_kref) {
2538+
if (!kref_get_unless_zero(&se_cmd->cmd_kref))
2539+
return -EINVAL;
2540+
2541+
se_cmd->se_cmd_flags |= SCF_ACK_KREF;
2542+
}
25522543

25532544
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
25542545
if (se_sess->sess_tearing_down) {
@@ -2627,7 +2618,7 @@ EXPORT_SYMBOL(target_put_sess_cmd);
26272618
*/
26282619
void target_sess_cmd_list_set_waiting(struct se_session *se_sess)
26292620
{
2630-
struct se_cmd *se_cmd;
2621+
struct se_cmd *se_cmd, *tmp_cmd;
26312622
unsigned long flags;
26322623
int rc;
26332624

@@ -2639,14 +2630,16 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess)
26392630
se_sess->sess_tearing_down = 1;
26402631
list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
26412632

2642-
list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) {
2633+
list_for_each_entry_safe(se_cmd, tmp_cmd,
2634+
&se_sess->sess_wait_list, se_cmd_list) {
26432635
rc = kref_get_unless_zero(&se_cmd->cmd_kref);
26442636
if (rc) {
26452637
se_cmd->cmd_wait_set = 1;
26462638
spin_lock(&se_cmd->t_state_lock);
26472639
se_cmd->transport_state |= CMD_T_FABRIC_STOP;
26482640
spin_unlock(&se_cmd->t_state_lock);
2649-
}
2641+
} else
2642+
list_del_init(&se_cmd->se_cmd_list);
26502643
}
26512644

26522645
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
@@ -2871,6 +2864,12 @@ static const struct sense_info sense_info_table[] = {
28712864
.ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
28722865
.add_sector_info = true,
28732866
},
2867+
[TCM_COPY_TARGET_DEVICE_NOT_REACHABLE] = {
2868+
.key = COPY_ABORTED,
2869+
.asc = 0x0d,
2870+
.ascq = 0x02, /* COPY TARGET DEVICE NOT REACHABLE */
2871+
2872+
},
28742873
[TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = {
28752874
/*
28762875
* Returning ILLEGAL REQUEST would cause immediate IO errors on

drivers/target/target_core_user.c

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ struct tcmu_dev {
9696
size_t dev_size;
9797
u32 cmdr_size;
9898
u32 cmdr_last_cleaned;
99-
/* Offset of data ring from start of mb */
99+
/* Offset of data area from start of mb */
100100
/* Must add data_off and mb_addr to get the address */
101101
size_t data_off;
102102
size_t data_size;
@@ -349,7 +349,7 @@ static inline size_t spc_bitmap_free(unsigned long *bitmap)
349349

350350
/*
351351
* We can't queue a command until we have space available on the cmd ring *and*
352-
* space available on the data ring.
352+
* space available on the data area.
353353
*
354354
* Called with ring lock held.
355355
*/
@@ -389,7 +389,8 @@ static bool is_ring_space_avail(struct tcmu_dev *udev, size_t cmd_size, size_t d
389389
return true;
390390
}
391391

392-
static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
392+
static sense_reason_t
393+
tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
393394
{
394395
struct tcmu_dev *udev = tcmu_cmd->tcmu_dev;
395396
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
@@ -405,7 +406,7 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
405406
DECLARE_BITMAP(old_bitmap, DATA_BLOCK_BITS);
406407

407408
if (test_bit(TCMU_DEV_BIT_BROKEN, &udev->flags))
408-
return -EINVAL;
409+
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
409410

410411
/*
411412
* Must be a certain minimum size for response sense info, but
@@ -432,11 +433,14 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
432433
BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents));
433434
data_length += se_cmd->t_bidi_data_sg->length;
434435
}
435-
if ((command_size > (udev->cmdr_size / 2))
436-
|| data_length > udev->data_size)
437-
pr_warn("TCMU: Request of size %zu/%zu may be too big for %u/%zu "
438-
"cmd/data ring buffers\n", command_size, data_length,
436+
if ((command_size > (udev->cmdr_size / 2)) ||
437+
data_length > udev->data_size) {
438+
pr_warn("TCMU: Request of size %zu/%zu is too big for %u/%zu "
439+
"cmd ring/data area\n", command_size, data_length,
439440
udev->cmdr_size, udev->data_size);
441+
spin_unlock_irq(&udev->cmdr_lock);
442+
return TCM_INVALID_CDB_FIELD;
443+
}
440444

441445
while (!is_ring_space_avail(udev, command_size, data_length)) {
442446
int ret;
@@ -450,7 +454,7 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
450454
finish_wait(&udev->wait_cmdr, &__wait);
451455
if (!ret) {
452456
pr_warn("tcmu: command timed out\n");
453-
return -ETIMEDOUT;
457+
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
454458
}
455459

456460
spin_lock_irq(&udev->cmdr_lock);
@@ -487,9 +491,7 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
487491

488492
bitmap_copy(old_bitmap, udev->data_bitmap, DATA_BLOCK_BITS);
489493

490-
/*
491-
* Fix up iovecs, and handle if allocation in data ring wrapped.
492-
*/
494+
/* Handle allocating space from the data area */
493495
iov = &entry->req.iov[0];
494496
iov_cnt = 0;
495497
copy_to_data_area = (se_cmd->data_direction == DMA_TO_DEVICE
@@ -526,10 +528,11 @@ static int tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
526528
mod_timer(&udev->timeout,
527529
round_jiffies_up(jiffies + msecs_to_jiffies(TCMU_TIME_OUT)));
528530

529-
return 0;
531+
return TCM_NO_SENSE;
530532
}
531533

532-
static int tcmu_queue_cmd(struct se_cmd *se_cmd)
534+
static sense_reason_t
535+
tcmu_queue_cmd(struct se_cmd *se_cmd)
533536
{
534537
struct se_device *se_dev = se_cmd->se_dev;
535538
struct tcmu_dev *udev = TCMU_DEV(se_dev);
@@ -538,10 +541,10 @@ static int tcmu_queue_cmd(struct se_cmd *se_cmd)
538541

539542
tcmu_cmd = tcmu_alloc_cmd(se_cmd);
540543
if (!tcmu_cmd)
541-
return -ENOMEM;
544+
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
542545

543546
ret = tcmu_queue_cmd_ring(tcmu_cmd);
544-
if (ret < 0) {
547+
if (ret != TCM_NO_SENSE) {
545548
pr_err("TCMU: Could not queue command\n");
546549
spin_lock_irq(&udev->commands_lock);
547550
idr_remove(&udev->commands, tcmu_cmd->cmd_id);
@@ -561,7 +564,7 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
561564
if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) {
562565
/*
563566
* cmd has been completed already from timeout, just reclaim
564-
* data ring space and free cmd
567+
* data area space and free cmd
565568
*/
566569
free_data_area(udev, cmd);
567570

@@ -1128,21 +1131,10 @@ static sector_t tcmu_get_blocks(struct se_device *dev)
11281131
dev->dev_attrib.block_size);
11291132
}
11301133

1131-
static sense_reason_t
1132-
tcmu_pass_op(struct se_cmd *se_cmd)
1133-
{
1134-
int ret = tcmu_queue_cmd(se_cmd);
1135-
1136-
if (ret != 0)
1137-
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1138-
else
1139-
return TCM_NO_SENSE;
1140-
}
1141-
11421134
static sense_reason_t
11431135
tcmu_parse_cdb(struct se_cmd *cmd)
11441136
{
1145-
return passthrough_parse_cdb(cmd, tcmu_pass_op);
1137+
return passthrough_parse_cdb(cmd, tcmu_queue_cmd);
11461138
}
11471139

11481140
static const struct target_backend_ops tcmu_ops = {

drivers/target/target_core_xcopy.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op
104104
}
105105
mutex_unlock(&g_device_mutex);
106106

107-
pr_err("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
107+
pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
108108
return -EINVAL;
109109
}
110110

@@ -185,14 +185,16 @@ static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op
185185

186186
static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
187187
struct xcopy_op *xop, unsigned char *p,
188-
unsigned short tdll)
188+
unsigned short tdll, sense_reason_t *sense_ret)
189189
{
190190
struct se_device *local_dev = se_cmd->se_dev;
191191
unsigned char *desc = p;
192192
int offset = tdll % XCOPY_TARGET_DESC_LEN, rc, ret = 0;
193193
unsigned short start = 0;
194194
bool src = true;
195195

196+
*sense_ret = TCM_INVALID_PARAMETER_LIST;
197+
196198
if (offset != 0) {
197199
pr_err("XCOPY target descriptor list length is not"
198200
" multiple of %d\n", XCOPY_TARGET_DESC_LEN);
@@ -243,9 +245,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
243245
rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, true);
244246
else
245247
rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, false);
246-
247-
if (rc < 0)
248+
/*
249+
* If a matching IEEE NAA 0x83 descriptor for the requested device
250+
* is not located on this node, return COPY_ABORTED with ASQ/ASQC
251+
* 0x0d/0x02 - COPY_TARGET_DEVICE_NOT_REACHABLE to request the
252+
* initiator to fall back to normal copy method.
253+
*/
254+
if (rc < 0) {
255+
*sense_ret = TCM_COPY_TARGET_DEVICE_NOT_REACHABLE;
248256
goto out;
257+
}
249258

250259
pr_debug("XCOPY TGT desc: Source dev: %p NAA IEEE WWN: 0x%16phN\n",
251260
xop->src_dev, &xop->src_tid_wwn[0]);
@@ -653,6 +662,7 @@ static int target_xcopy_read_source(
653662
rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0],
654663
remote_port, true);
655664
if (rc < 0) {
665+
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
656666
transport_generic_free_cmd(se_cmd, 0);
657667
return rc;
658668
}
@@ -664,6 +674,7 @@ static int target_xcopy_read_source(
664674

665675
rc = target_xcopy_issue_pt_cmd(xpt_cmd);
666676
if (rc < 0) {
677+
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
667678
transport_generic_free_cmd(se_cmd, 0);
668679
return rc;
669680
}
@@ -714,6 +725,7 @@ static int target_xcopy_write_destination(
714725
remote_port, false);
715726
if (rc < 0) {
716727
struct se_cmd *src_cmd = &xop->src_pt_cmd->se_cmd;
728+
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
717729
/*
718730
* If the failure happened before the t_mem_list hand-off in
719731
* target_xcopy_setup_pt_cmd(), Reset memory + clear flag so that
@@ -729,6 +741,7 @@ static int target_xcopy_write_destination(
729741

730742
rc = target_xcopy_issue_pt_cmd(xpt_cmd);
731743
if (rc < 0) {
744+
ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
732745
se_cmd->se_cmd_flags &= ~SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC;
733746
transport_generic_free_cmd(se_cmd, 0);
734747
return rc;
@@ -815,9 +828,14 @@ static void target_xcopy_do_work(struct work_struct *work)
815828
out:
816829
xcopy_pt_undepend_remotedev(xop);
817830
kfree(xop);
818-
819-
pr_warn("target_xcopy_do_work: Setting X-COPY CHECK_CONDITION -> sending response\n");
820-
ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
831+
/*
832+
* Don't override an error scsi status if it has already been set
833+
*/
834+
if (ec_cmd->scsi_status == SAM_STAT_GOOD) {
835+
pr_warn_ratelimited("target_xcopy_do_work: rc: %d, Setting X-COPY"
836+
" CHECK_CONDITION -> sending response\n", rc);
837+
ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
838+
}
821839
target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION);
822840
}
823841

@@ -875,7 +893,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
875893
" tdll: %hu sdll: %u inline_dl: %u\n", list_id, list_id_usage,
876894
tdll, sdll, inline_dl);
877895

878-
rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll);
896+
rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll, &ret);
879897
if (rc <= 0)
880898
goto out;
881899

drivers/target/tcm_fc/tfc_cmd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,10 +572,10 @@ static void ft_send_work(struct work_struct *work)
572572
if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
573573
&cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
574574
ntohl(fcp->fc_dl), task_attr, data_dir,
575-
TARGET_SCF_ACK_KREF))
575+
TARGET_SCF_ACK_KREF | TARGET_SCF_USE_CPUID))
576576
goto err;
577577

578-
pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
578+
pr_debug("r_ctl %x target_submit_cmd %p\n", fh->fh_r_ctl, cmd);
579579
return;
580580

581581
err:

0 commit comments

Comments
 (0)