|
@@ -128,6 +128,7 @@ int ft_queue_status(struct se_cmd *se_cmd)
|
|
|
struct fc_lport *lport;
|
|
|
struct fc_exch *ep;
|
|
|
size_t len;
|
|
|
+ int rc;
|
|
|
|
|
|
if (cmd->aborted)
|
|
|
return 0;
|
|
@@ -137,9 +138,10 @@ int ft_queue_status(struct se_cmd *se_cmd)
|
|
|
len = sizeof(*fcp) + se_cmd->scsi_sense_length;
|
|
|
fp = fc_frame_alloc(lport, len);
|
|
|
if (!fp) {
|
|
|
- /* XXX shouldn't just drop it - requeue and retry? */
|
|
|
- return 0;
|
|
|
+ se_cmd->scsi_status = SAM_STAT_TASK_SET_FULL;
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
+
|
|
|
fcp = fc_frame_payload_get(fp, len);
|
|
|
memset(fcp, 0, len);
|
|
|
fcp->resp.fr_status = se_cmd->scsi_status;
|
|
@@ -170,7 +172,18 @@ int ft_queue_status(struct se_cmd *se_cmd)
|
|
|
fc_fill_fc_hdr(fp, FC_RCTL_DD_CMD_STATUS, ep->did, ep->sid, FC_TYPE_FCP,
|
|
|
FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ, 0);
|
|
|
|
|
|
- lport->tt.seq_send(lport, cmd->seq, fp);
|
|
|
+ rc = lport->tt.seq_send(lport, cmd->seq, fp);
|
|
|
+ if (rc) {
|
|
|
+ pr_info_ratelimited("%s: Failed to send response frame %p, "
|
|
|
+ "xid <0x%x>\n", __func__, fp, ep->xid);
|
|
|
+ /*
|
|
|
+ * Generate a TASK_SET_FULL status to notify the initiator
|
|
|
+ * to reduce it's queue_depth after the se_cmd response has
|
|
|
+ * been re-queued by target-core.
|
|
|
+ */
|
|
|
+ se_cmd->scsi_status = SAM_STAT_TASK_SET_FULL;
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
lport->tt.exch_done(cmd->seq);
|
|
|
return 0;
|
|
|
}
|