Commit 025def92 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target fixes from Nicholas Bellinger:

 "There has been work in a number of different areas over the last
  weeks, including:

   - Fix target-core-user (TCMU) back-end bi-directional handling (Xiubo
     Li + Mike Christie + Ilias Tsitsimpis)

   - Fix iscsi-target TMR reference leak during session shutdown (Rob
     Millner + Chu Yuan Lin)

   - Fix target_core_fabric_configfs.c race between LUN shutdown +
     mapped LUN creation (James Shen)

   - Fix target-core unknown fabric callback queue-full errors (Potnuri
     Bharat Teja)

   - Fix iscsi-target + iser-target queue-full handling in order to
     support iw_cxgb4 RNICs. (Potnuri Bharat Teja + Sagi Grimberg)

   - Fix ALUA transition state race between multiple initiator (Mike
     Christie)

   - Drop work-around for legacy GlobalSAN initiator, to allow QLogic
     57840S + 579xx offload HBAs to work out-of-the-box in MSFT
     environments. (Martin Svec + Arun Easi)

  Note that a number are CC'ed for stable, and although the queue-full
  bug-fixes required for iser-target to work with iw_cxgb4 aren't CC'ed
  here, they'll be posted to Greg-KH separately"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  tcmu: Skip Data-Out blocks before gathering Data-In buffer for BIDI case
  iscsi-target: Drop work-around for legacy GlobalSAN initiator
  target: Fix ALUA transition state race between multiple initiators
  iser-target: avoid posting a recv buffer twice
  iser-target: Fix queue-full response handling
  iscsi-target: Propigate queue_data_in + queue_status errors
  target: Fix unknown fabric callback queue-full errors
  tcmu: Fix wrongly calculating of the base_command_size
  tcmu: Fix possible overwrite of t_data_sg's last iov[]
  target: Avoid mappedlun symlink creation during lun shutdown
  iscsi-target: Fix TMR reference leak during session shutdown
  usb: gadget: Correct usb EP argument for BOT status request
  tcmu: Allow cmd_time_out to be set to zero (disabled)
parents 06ea4c38 a5d68ba8
Loading
Loading
Loading
Loading
+47 −18
Original line number Diff line number Diff line
@@ -817,6 +817,7 @@ isert_post_recvm(struct isert_conn *isert_conn, u32 count)
		rx_wr->sg_list = &rx_desc->rx_sg;
		rx_wr->num_sge = 1;
		rx_wr->next = rx_wr + 1;
		rx_desc->in_use = false;
	}
	rx_wr--;
	rx_wr->next = NULL; /* mark end of work requests list */
@@ -835,6 +836,15 @@ isert_post_recv(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc)
	struct ib_recv_wr *rx_wr_failed, rx_wr;
	int ret;

	if (!rx_desc->in_use) {
		/*
		 * if the descriptor is not in-use we already reposted it
		 * for recv, so just silently return
		 */
		return 0;
	}

	rx_desc->in_use = false;
	rx_wr.wr_cqe = &rx_desc->rx_cqe;
	rx_wr.sg_list = &rx_desc->rx_sg;
	rx_wr.num_sge = 1;
@@ -1397,6 +1407,8 @@ isert_recv_done(struct ib_cq *cq, struct ib_wc *wc)
		return;
	}

	rx_desc->in_use = true;

	ib_dma_sync_single_for_cpu(ib_dev, rx_desc->dma_addr,
			ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);

@@ -1659,10 +1671,23 @@ isert_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc)
	ret = isert_check_pi_status(cmd, isert_cmd->rw.sig->sig_mr);
	isert_rdma_rw_ctx_destroy(isert_cmd, isert_conn);

	if (ret) {
		/*
		 * transport_generic_request_failure() expects to have
		 * plus two references to handle queue-full, so re-add
		 * one here as target-core will have already dropped
		 * it after the first isert_put_datain() callback.
		 */
		kref_get(&cmd->cmd_kref);
		transport_generic_request_failure(cmd, cmd->pi_err);
	} else {
		/*
		 * XXX: isert_put_response() failure is not retried.
		 */
		ret = isert_put_response(isert_conn->conn, isert_cmd->iscsi_cmd);
		if (ret)
		transport_send_check_condition_and_sense(cmd, cmd->pi_err, 0);
	else
		isert_put_response(isert_conn->conn, isert_cmd->iscsi_cmd);
			pr_warn_ratelimited("isert_put_response() ret: %d\n", ret);
	}
}

static void
@@ -1699,14 +1724,16 @@ isert_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)
	cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
	spin_unlock_bh(&cmd->istate_lock);

	if (ret) {
		target_put_sess_cmd(se_cmd);
		transport_send_check_condition_and_sense(se_cmd,
							 se_cmd->pi_err, 0);
	} else {
	/*
	 * transport_generic_request_failure() will drop the extra
	 * se_cmd->cmd_kref reference after T10-PI error, and handle
	 * any non-zero ->queue_status() callback error retries.
	 */
	if (ret)
		transport_generic_request_failure(se_cmd, se_cmd->pi_err);
	else
		target_execute_cmd(se_cmd);
}
}

static void
isert_do_control_comp(struct work_struct *work)
@@ -2171,26 +2198,28 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
		chain_wr = &isert_cmd->tx_desc.send_wr;
	}

	isert_rdma_rw_ctx_post(isert_cmd, isert_conn, cqe, chain_wr);
	isert_dbg("Cmd: %p posted RDMA_WRITE for iSER Data READ\n", isert_cmd);
	return 1;
	rc = isert_rdma_rw_ctx_post(isert_cmd, isert_conn, cqe, chain_wr);
	isert_dbg("Cmd: %p posted RDMA_WRITE for iSER Data READ rc: %d\n",
		  isert_cmd, rc);
	return rc;
}

static int
isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery)
{
	struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd);
	int ret;

	isert_dbg("Cmd: %p RDMA_READ data_length: %u write_data_done: %u\n",
		 isert_cmd, cmd->se_cmd.data_length, cmd->write_data_done);

	isert_cmd->tx_desc.tx_cqe.done = isert_rdma_read_done;
	isert_rdma_rw_ctx_post(isert_cmd, conn->context,
	ret = isert_rdma_rw_ctx_post(isert_cmd, conn->context,
				     &isert_cmd->tx_desc.tx_cqe, NULL);

	isert_dbg("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n",
		 isert_cmd);
	return 0;
	isert_dbg("Cmd: %p posted RDMA_READ memory for ISER Data WRITE rc: %d\n",
		 isert_cmd, ret);
	return ret;
}

static int
+2 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@

#define ISER_RX_PAD_SIZE	(ISCSI_DEF_MAX_RECV_SEG_LEN + 4096 - \
		(ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \
		 sizeof(struct ib_cqe)))
		 sizeof(struct ib_cqe) + sizeof(bool)))

#define ISCSI_ISER_SG_TABLESIZE		256

@@ -85,6 +85,7 @@ struct iser_rx_desc {
	u64		dma_addr;
	struct ib_sge	rx_sg;
	struct ib_cqe	rx_cqe;
	bool		in_use;
	char		pad[ISER_RX_PAD_SIZE];
} __packed;

+1 −2
Original line number Diff line number Diff line
@@ -485,8 +485,7 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *);

int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
	iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
	return 0;
	return iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
}
EXPORT_SYMBOL(iscsit_queue_rsp);

+5 −8
Original line number Diff line number Diff line
@@ -1398,11 +1398,10 @@ static u32 lio_sess_get_initiator_sid(
static int lio_queue_data_in(struct se_cmd *se_cmd)
{
	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
	struct iscsi_conn *conn = cmd->conn;

	cmd->i_state = ISTATE_SEND_DATAIN;
	cmd->conn->conn_transport->iscsit_queue_data_in(cmd->conn, cmd);

	return 0;
	return conn->conn_transport->iscsit_queue_data_in(conn, cmd);
}

static int lio_write_pending(struct se_cmd *se_cmd)
@@ -1431,16 +1430,14 @@ static int lio_write_pending_status(struct se_cmd *se_cmd)
static int lio_queue_status(struct se_cmd *se_cmd)
{
	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
	struct iscsi_conn *conn = cmd->conn;

	cmd->i_state = ISTATE_SEND_STATUS;

	if (cmd->se_cmd.scsi_status || cmd->sense_reason) {
		iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
		return 0;
		return iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
	}
	cmd->conn->conn_transport->iscsit_queue_status(cmd->conn, cmd);

	return 0;
	return conn->conn_transport->iscsit_queue_status(conn, cmd);
}

static void lio_queue_tm_rsp(struct se_cmd *se_cmd)
+0 −16
Original line number Diff line number Diff line
@@ -781,22 +781,6 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
	} else if (IS_TYPE_NUMBER(param)) {
		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
			SET_PSTATE_REPLY_OPTIONAL(param);
		/*
		 * The GlobalSAN iSCSI Initiator for MacOSX does
		 * not respond to MaxBurstLength, FirstBurstLength,
		 * DefaultTime2Wait or DefaultTime2Retain parameter keys.
		 * So, we set them to 'reply optional' here, and assume the
		 * the defaults from iscsi_parameters.h if the initiator
		 * is not RFC compliant and the keys are not negotiated.
		 */
		if (!strcmp(param->name, MAXBURSTLENGTH))
			SET_PSTATE_REPLY_OPTIONAL(param);
		if (!strcmp(param->name, FIRSTBURSTLENGTH))
			SET_PSTATE_REPLY_OPTIONAL(param);
		if (!strcmp(param->name, DEFAULTTIME2WAIT))
			SET_PSTATE_REPLY_OPTIONAL(param);
		if (!strcmp(param->name, DEFAULTTIME2RETAIN))
			SET_PSTATE_REPLY_OPTIONAL(param);
		/*
		 * Required for gPXE iSCSI boot client
		 */
Loading