Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a99bcdce authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target fixes from Nicholas Bellinger:
 "The highlights include:

   - Fix iscsi-target payload memory leak during
     ISCSI_FLAG_TEXT_CONTINUE (Varun Prakash)

   - Fix tcm_qla2xxx incorrect use of tcm_qla2xxx_free_cmd during ABORT
     (Pascal de Bruijn + Himanshu Madhani + nab)

   - Fix iscsi-target long-standing issue with parallel delete of a
     single network portal across multiple target instances (Gary Guo +
     nab)

   - Fix target dynamic se_node GPF during uncached shutdown regression
     (Justin Maggard + nab)"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  target: Fix node_acl demo-mode + uncached dynamic shutdown regression
  iscsi-target: Fix iscsi_np reset hung task during parallel delete
  qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)
  cxgbit: fix sg_nents calculation
  iscsi-target: fix invalid flags in text response
  iscsi-target: fix memory leak in iscsit_setup_text_cmd()
  cxgbit: add missing __kfree_skb()
  tcmu: free old string on reconfig
  tcmu: Fix possible to/from address overflow when doing the memcpy
parents 043cd07c 6f48655f
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
{
	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
	unsigned long flags;

	/*
	 * Ensure that the complete FCP WRITE payload has been received.
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
	 */
	cmd->cmd_in_wq = 0;

	spin_lock_irqsave(&cmd->cmd_lock, flags);
	cmd->data_work = 1;
	if (cmd->aborted) {
		cmd->data_work_free = 1;
		spin_unlock_irqrestore(&cmd->cmd_lock, flags);

		tcm_qla2xxx_free_cmd(cmd);
		return;
	}
	spin_unlock_irqrestore(&cmd->cmd_lock, flags);

	cmd->qpair->tgt_counters.qla_core_ret_ctio++;
	if (!cmd->write_data_transferred) {
		/*
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
	qlt_xmit_tm_rsp(mcmd);
}

#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
	struct qla_tgt_cmd *cmd = container_of(se_cmd,
				struct qla_tgt_cmd, se_cmd);
	unsigned long flags;

	if (qlt_abort_cmd(cmd))
		return;

	spin_lock_irqsave(&cmd->cmd_lock, flags);
	if ((cmd->state == QLA_TGT_STATE_NEW)||
	    ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
		DATA_WORK_NOT_FREE(cmd))) {
		cmd->data_work_free = 1;
		spin_unlock_irqrestore(&cmd->cmd_lock, flags);
		/*
		 * cmd has not reached fw, Use this trigger to free it.
		 */
		tcm_qla2xxx_free_cmd(cmd);
		return;
	}
	spin_unlock_irqrestore(&cmd->cmd_lock, flags);
	return;

}

static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
+12 −4
Original line number Diff line number Diff line
@@ -1510,11 +1510,13 @@ cxgbit_pass_open_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)

	if (!cnp) {
		pr_info("%s stid %d lookup failure\n", __func__, stid);
		return;
		goto rel_skb;
	}

	cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
	cxgbit_put_cnp(cnp);
rel_skb:
	__kfree_skb(skb);
}

static void
@@ -1530,11 +1532,13 @@ cxgbit_close_listsrv_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)

	if (!cnp) {
		pr_info("%s stid %d lookup failure\n", __func__, stid);
		return;
		goto rel_skb;
	}

	cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
	cxgbit_put_cnp(cnp);
rel_skb:
	__kfree_skb(skb);
}

static void
@@ -1819,12 +1823,16 @@ static void cxgbit_set_tcb_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
	struct tid_info *t = lldi->tids;

	csk = lookup_tid(t, tid);
	if (unlikely(!csk))
	if (unlikely(!csk)) {
		pr_err("can't find connection for tid %u.\n", tid);
	else
		goto rel_skb;
	} else {
		cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status);
	}

	cxgbit_put_csk(csk);
rel_skb:
	__kfree_skb(skb);
}

static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb)
+7 −5
Original line number Diff line number Diff line
@@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,

static void
cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
		      unsigned int nents)
		      unsigned int nents, u32 skip)
{
	struct skb_seq_state st;
	const u8 *buf;
@@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
		}

		consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf,
						 buf_len, consumed);
						 buf_len, skip + consumed);
	}
}

@@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
		struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0];
		u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE));

		cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents);
		cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0);
	}

	cmd->write_data_done += pdu_cb->dlen;
@@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
		  cmd->se_cmd.data_length);

	if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) {
		u32 skip = data_offset % PAGE_SIZE;

		sg_off = data_offset / PAGE_SIZE;
		sg_start = &cmd->se_cmd.t_data_sg[sg_off];
		sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE));
		sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE));

		cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents);
		cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip);
	}

check_payload:
+4 −2
Original line number Diff line number Diff line
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
		return 0;
	}
	np->np_thread_state = ISCSI_NP_THREAD_RESET;
	atomic_inc(&np->np_reset_count);

	if (np->np_thread) {
		spin_unlock_bh(&np->np_thread_lock);
@@ -2167,6 +2168,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
	cmd->data_direction	= DMA_NONE;
	kfree(cmd->text_in_ptr);
	cmd->text_in_ptr	= NULL;

	return 0;
@@ -3487,9 +3489,9 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
		return text_length;

	if (completed) {
		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
		hdr->flags = ISCSI_FLAG_CMD_FINAL;
	} else {
		hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
		hdr->flags = ISCSI_FLAG_TEXT_CONTINUE;
		cmd->read_data_done += text_length;
		if (cmd->targ_xfer_tag == 0xFFFFFFFF)
			cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
+5 −2
Original line number Diff line number Diff line
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
	flush_signals(current);

	spin_lock_bh(&np->np_thread_lock);
	if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
	if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
		np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
		spin_unlock_bh(&np->np_thread_lock);
		complete(&np->np_restart_comp);
		return 1;
	} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
		spin_unlock_bh(&np->np_thread_lock);
		goto exit;
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
		goto exit;
	} else if (rc < 0) {
		spin_lock_bh(&np->np_thread_lock);
		if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
		if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
			np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
			spin_unlock_bh(&np->np_thread_lock);
			complete(&np->np_restart_comp);
			iscsit_put_transport(conn->conn_transport);
Loading