scsi: target: Fix sense key for invalid EXTENDED COPY request

TCM fails to pass the following tests in libiscsi:

  SCSI.ExtendedCopy.DescrType
  SCSI.ExtendedCopy.DescrLimits
  SCSI.ExtendedCopy.ParamHdr
  SCSI.ExtendedCopy.ValidSegDescr
  SCSI.ExtendedCopy.ValidTgtDescr

The xcopy code always returns the same NOT READY sense key for all detected
errors. Change the sense key for invalid requests to ILLEGAL REQUEST, and
for aborted transfers to COPY ABORTED.

Link: https://lore.kernel.org/r/20210803145410.80147-3-s.samoylenko@yadro.com
Fixes: d877d7275b ("target: Fix a deadlock between the XCOPY code and iSCSI session shutdown")
Reviewed-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: Konstantin Shelekhin <k.shelekhin@yadro.com>
Signed-off-by: Sergey Samoylenko <s.samoylenko@yadro.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Sergey Samoylenko 2021-08-03 17:54:10 +03:00 committed by Martin K. Petersen
parent 44678553ad
commit 0394b5048e
1 changed files with 15 additions and 11 deletions

View File

@ -674,12 +674,16 @@ static void target_xcopy_do_work(struct work_struct *work)
unsigned int max_sectors; unsigned int max_sectors;
int rc = 0; int rc = 0;
unsigned short nolb, max_nolb, copied_nolb = 0; unsigned short nolb, max_nolb, copied_nolb = 0;
sense_reason_t sense_rc;
if (target_parse_xcopy_cmd(xop) != TCM_NO_SENSE) sense_rc = target_parse_xcopy_cmd(xop);
if (sense_rc != TCM_NO_SENSE)
goto err_free; goto err_free;
if (WARN_ON_ONCE(!xop->src_dev) || WARN_ON_ONCE(!xop->dst_dev)) if (WARN_ON_ONCE(!xop->src_dev) || WARN_ON_ONCE(!xop->dst_dev)) {
sense_rc = TCM_INVALID_PARAMETER_LIST;
goto err_free; goto err_free;
}
src_dev = xop->src_dev; src_dev = xop->src_dev;
dst_dev = xop->dst_dev; dst_dev = xop->dst_dev;
@ -762,20 +766,20 @@ static void target_xcopy_do_work(struct work_struct *work)
return; return;
out: out:
/*
* The XCOPY command was aborted after some data was transferred.
* Terminate command with CHECK CONDITION status, with the sense key
* set to COPY ABORTED.
*/
sense_rc = TCM_COPY_TARGET_DEVICE_NOT_REACHABLE;
xcopy_pt_undepend_remotedev(xop); xcopy_pt_undepend_remotedev(xop);
target_free_sgl(xop->xop_data_sg, xop->xop_data_nents); target_free_sgl(xop->xop_data_sg, xop->xop_data_nents);
err_free: err_free:
kfree(xop); kfree(xop);
/* pr_warn_ratelimited("target_xcopy_do_work: rc: %d, sense: %u, XCOPY operation failed\n",
* Don't override an error scsi status if it has already been set rc, sense_rc);
*/ target_complete_cmd_with_sense(ec_cmd, SAM_STAT_CHECK_CONDITION, sense_rc);
if (ec_cmd->scsi_status == SAM_STAT_GOOD) {
pr_warn_ratelimited("target_xcopy_do_work: rc: %d, Setting X-COPY"
" CHECK_CONDITION -> sending response\n", rc);
ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
}
target_complete_cmd(ec_cmd, ec_cmd->scsi_status);
} }
/* /*