[PATCH 17/21] tcm_fc: Avoid that closing a session triggers an endless loop

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Avoid that if an initiator closes a session that the tcm_fc
driver keeps logging the following message forever:

ft_queue_status: Failed to send response frame ..., xid <0x...>

Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx>
---
 drivers/target/tcm_fc/tcm_fc.h   |  1 +
 drivers/target/tcm_fc/tfc_cmd.c  | 23 ++++++++++++++++-------
 drivers/target/tcm_fc/tfc_sess.c |  2 +-
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 25f368d..15a2249 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -138,6 +138,7 @@ extern unsigned int ft_debug_logging;
 /*
  * Session ops.
  */
+struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id);
 void ft_sess_put(struct ft_sess *);
 int ft_sess_shutdown(struct se_session *);
 void ft_sess_close(struct se_session *);
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 152caec..840dac3 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -126,6 +126,7 @@ int ft_queue_status(struct se_cmd *se_cmd)
 	struct fcp_resp_with_ext *fcp;
 	struct fc_lport *lport;
 	struct fc_exch *ep;
+	struct ft_sess *sess;
 	size_t len;
 	int rc;
 
@@ -175,13 +176,21 @@ int ft_queue_status(struct se_cmd *se_cmd)
 	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;
+		sess = ft_sess_get(lport, cmd->sess->port_id);
+		if (sess)
+			ft_sess_put(sess);
+		if (sess == cmd->sess) {
+			/*
+			 * 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;
+		} else {
+			/* Session has been closed. */
+			return 0;
+		}
 	}
 	lport->tt.exch_done(cmd->seq);
 	return 0;
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index df4d252..a39a81f 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -167,7 +167,7 @@ static u32 ft_sess_hash(u32 port_id)
  * Sessions and hash lists are RCU-protected.
  * A reference is taken which must be eventually freed.
  */
-static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id)
+struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id)
 {
 	struct ft_tport *tport;
 	struct hlist_head *head;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux