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

Commit ed9ea4ed authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "The highlights this round include:

   - Add support for T10 PI pass-through between vhost-scsi +
     virtio-scsi (MST + Paolo + MKP + nab)
   - Add support for T10 PI in qla2xxx target mode (Quinn + MKP + hch +
     nab, merged through scsi.git)
   - Add support for percpu-ida pre-allocation in qla2xxx target code
     (Quinn + nab)
   - A number of iser-target fixes related to hardening the network
     portal shutdown path (Sagi + Slava)
   - Fix response length residual handling for a number of control CDBs
     (Roland + Christophe V.)
   - Various iscsi RFC conformance fixes in the CHAP authentication path
     (Tejas and Calsoft folks + nab)
   - Return TASK_SET_FULL status for tcm_fc(FCoE) DataIn + Response
     failures (Vasu + Jun + nab)
   - Fix long-standing ABORT_TASK + session reset hang (nab)
   - Convert iser-initiator + iser-target to include T10 bytes into EDTL
     (Sagi + Or + MKP + Mike Christie)
   - Fix NULL pointer dereference regression related to XCOPY introduced
     in v3.15 + CC'ed to v3.12.y (nab)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (34 commits)
  target: Fix NULL pointer dereference for XCOPY in target_put_sess_cmd
  vhost-scsi: Include prot_bytes into expected data transfer length
  TARGET/sbc,loopback: Adjust command data length in case pi exists on the wire
  libiscsi, iser: Adjust data_length to include protection information
  scsi_cmnd: Introduce scsi_transfer_length helper
  target: Report correct response length for some commands
  target/sbc: Check that the LBA and number of blocks are correct in VERIFY
  target/sbc: Remove sbc_check_valid_sectors()
  Target/iscsi: Fix sendtargets response pdu for iser transport
  Target/iser: Fix a wrong dereference in case discovery session is over iser
  iscsi-target: Fix ABORT_TASK + connection reset iscsi_queue_req memory leak
  target: Use complete_all for se_cmd->t_transport_stop_comp
  target: Set CMD_T_ACTIVE bit for Task Management Requests
  target: cleanup some boolean tests
  target/spc: Simplify INQUIRY EVPD=0x80
  tcm_fc: Generate TASK_SET_FULL status for response failures
  tcm_fc: Generate TASK_SET_FULL status for DataIN failures
  iscsi-target: Reject mutual authentication with reflected CHAP_C
  iscsi-target: Remove no-op from iscsit_tpg_del_portal_group
  iscsi-target: Fix CHAP_A parameter list handling
  ...
parents c1fdb2d3 0ed6e189
Loading
Loading
Loading
Loading
+10 −24
Original line number Diff line number Diff line
@@ -41,11 +41,11 @@
#include "iscsi_iser.h"

/* Register user buffer memory and initialize passive rdma
 *  dto descriptor. Total data size is stored in
 *  iser_task->data[ISER_DIR_IN].data_len
 *  dto descriptor. Data size is stored in
 *  task->data[ISER_DIR_IN].data_len, Protection size
 *  os stored in task->prot[ISER_DIR_IN].data_len
 */
static int iser_prepare_read_cmd(struct iscsi_task *task,
				 unsigned int edtl)
static int iser_prepare_read_cmd(struct iscsi_task *task)

{
	struct iscsi_iser_task *iser_task = task->dd_data;
@@ -73,14 +73,6 @@ static int iser_prepare_read_cmd(struct iscsi_task *task,
			return err;
	}

	if (edtl > iser_task->data[ISER_DIR_IN].data_len) {
		iser_err("Total data length: %ld, less than EDTL: "
			 "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
			 iser_task->data[ISER_DIR_IN].data_len, edtl,
			 task->itt, iser_task->ib_conn);
		return -EINVAL;
	}

	err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_IN);
	if (err) {
		iser_err("Failed to set up Data-IN RDMA\n");
@@ -100,8 +92,9 @@ static int iser_prepare_read_cmd(struct iscsi_task *task,
}

/* Register user buffer memory and initialize passive rdma
 *  dto descriptor. Total data size is stored in
 *  task->data[ISER_DIR_OUT].data_len
 *  dto descriptor. Data size is stored in
 *  task->data[ISER_DIR_OUT].data_len, Protection size
 *  is stored at task->prot[ISER_DIR_OUT].data_len
 */
static int
iser_prepare_write_cmd(struct iscsi_task *task,
@@ -135,14 +128,6 @@ iser_prepare_write_cmd(struct iscsi_task *task,
			return err;
	}

	if (edtl > iser_task->data[ISER_DIR_OUT].data_len) {
		iser_err("Total data length: %ld, less than EDTL: %d, "
			 "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
			 iser_task->data[ISER_DIR_OUT].data_len,
			 edtl, task->itt, task->conn);
		return -EINVAL;
	}

	err = device->iser_reg_rdma_mem(iser_task, ISER_DIR_OUT);
	if (err != 0) {
		iser_err("Failed to register write cmd RDMA mem\n");
@@ -417,11 +402,12 @@ int iser_send_command(struct iscsi_conn *conn,
	if (scsi_prot_sg_count(sc)) {
		prot_buf->buf  = scsi_prot_sglist(sc);
		prot_buf->size = scsi_prot_sg_count(sc);
		prot_buf->data_len = sc->prot_sdb->length;
		prot_buf->data_len = data_buf->data_len >>
				     ilog2(sc->device->sector_size) * 8;
	}

	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
		err = iser_prepare_read_cmd(task, edtl);
		err = iser_prepare_read_cmd(task);
		if (err)
			goto send_command_error;
	}
+35 −35
Original line number Diff line number Diff line
@@ -663,8 +663,9 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)

	pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi;
	if (pi_support && !device->pi_capable) {
		pr_err("Protection information requested but not supported\n");
		ret = -EINVAL;
		pr_err("Protection information requested but not supported, "
		       "rejecting connect request\n");
		ret = rdma_reject(cma_id, NULL, 0);
		goto out_mr;
	}

@@ -787,14 +788,12 @@ isert_disconnect_work(struct work_struct *work)
		isert_put_conn(isert_conn);
		return;
	}
	if (!isert_conn->logout_posted) {
		pr_debug("Calling rdma_disconnect for !logout_posted from"
			 " isert_disconnect_work\n");

	if (isert_conn->disconnect) {
		/* Send DREQ/DREP towards our initiator */
		rdma_disconnect(isert_conn->conn_cm_id);
		mutex_unlock(&isert_conn->conn_mutex);
		iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
		goto wake_up;
	}

	mutex_unlock(&isert_conn->conn_mutex);

wake_up:
@@ -803,10 +802,11 @@ isert_disconnect_work(struct work_struct *work)
}

static void
isert_disconnected_handler(struct rdma_cm_id *cma_id)
isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect)
{
	struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;

	isert_conn->disconnect = disconnect;
	INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work);
	schedule_work(&isert_conn->conn_logout_work);
}
@@ -815,29 +815,28 @@ static int
isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
{
	int ret = 0;
	bool disconnect = false;

	pr_debug("isert_cma_handler: event %d status %d conn %p id %p\n",
		 event->event, event->status, cma_id->context, cma_id);

	switch (event->event) {
	case RDMA_CM_EVENT_CONNECT_REQUEST:
		pr_debug("RDMA_CM_EVENT_CONNECT_REQUEST: >>>>>>>>>>>>>>>\n");
		ret = isert_connect_request(cma_id, event);
		break;
	case RDMA_CM_EVENT_ESTABLISHED:
		pr_debug("RDMA_CM_EVENT_ESTABLISHED >>>>>>>>>>>>>>\n");
		isert_connected_handler(cma_id);
		break;
	case RDMA_CM_EVENT_DISCONNECTED:
		pr_debug("RDMA_CM_EVENT_DISCONNECTED: >>>>>>>>>>>>>>\n");
		isert_disconnected_handler(cma_id);
		break;
	case RDMA_CM_EVENT_DEVICE_REMOVAL:
	case RDMA_CM_EVENT_ADDR_CHANGE:
	case RDMA_CM_EVENT_ADDR_CHANGE:    /* FALLTHRU */
	case RDMA_CM_EVENT_DISCONNECTED:   /* FALLTHRU */
	case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */
		disconnect = true;
	case RDMA_CM_EVENT_TIMEWAIT_EXIT:  /* FALLTHRU */
		isert_disconnected_handler(cma_id, disconnect);
		break;
	case RDMA_CM_EVENT_CONNECT_ERROR:
	default:
		pr_err("Unknown RDMA CMA event: %d\n", event->event);
		pr_err("Unhandled RDMA CMA event: %d\n", event->event);
		break;
	}

@@ -1054,7 +1053,9 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
	}
	if (!login->login_failed) {
		if (login->login_complete) {
			if (isert_conn->conn_device->use_fastreg) {
			if (!conn->sess->sess_ops->SessionType &&
			    isert_conn->conn_device->use_fastreg) {
				/* Normal Session and fastreg is used */
				u8 pi_support = login->np->tpg_np->tpg->tpg_attrib.t10_pi;

				ret = isert_conn_create_fastreg_pool(isert_conn,
@@ -1824,11 +1825,8 @@ isert_do_control_comp(struct work_struct *work)
		break;
	case ISTATE_SEND_LOGOUTRSP:
		pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
		/*
		 * Call atomic_dec(&isert_conn->post_send_buf_count)
		 * from isert_wait_conn()
		 */
		isert_conn->logout_posted = true;

		atomic_dec(&isert_conn->post_send_buf_count);
		iscsit_logout_post_handler(cmd, cmd->conn);
		break;
	case ISTATE_SEND_TEXTRSP:
@@ -2034,6 +2032,8 @@ isert_cq_rx_comp_err(struct isert_conn *isert_conn)
	isert_conn->state = ISER_CONN_DOWN;
	mutex_unlock(&isert_conn->conn_mutex);

	iscsit_cause_connection_reinstatement(isert_conn->conn, 0);

	complete(&isert_conn->conn_wait_comp_err);
}

@@ -2320,7 +2320,7 @@ isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
	int rc;

	isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
	rc = iscsit_build_text_rsp(cmd, conn, hdr);
	rc = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_INFINIBAND);
	if (rc < 0)
		return rc;

@@ -3156,9 +3156,14 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
		return -ENODEV;

	spin_lock_bh(&np->np_thread_lock);
	if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
	if (np->np_thread_state >= ISCSI_NP_THREAD_RESET) {
		spin_unlock_bh(&np->np_thread_lock);
		pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
		pr_debug("np_thread_state %d for isert_accept_np\n",
			 np->np_thread_state);
		/**
		 * No point in stalling here when np_thread
		 * is in state RESET/SHUTDOWN/EXIT - bail
		 **/
		return -ENODEV;
	}
	spin_unlock_bh(&np->np_thread_lock);
@@ -3208,15 +3213,9 @@ static void isert_wait_conn(struct iscsi_conn *conn)
	struct isert_conn *isert_conn = conn->context;

	pr_debug("isert_wait_conn: Starting \n");
	/*
	 * Decrement post_send_buf_count for special case when called
	 * from isert_do_control_comp() -> iscsit_logout_post_handler()
	 */
	mutex_lock(&isert_conn->conn_mutex);
	if (isert_conn->logout_posted)
		atomic_dec(&isert_conn->post_send_buf_count);

	if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
	mutex_lock(&isert_conn->conn_mutex);
	if (isert_conn->conn_cm_id) {
		pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
		rdma_disconnect(isert_conn->conn_cm_id);
	}
@@ -3293,6 +3292,7 @@ static int __init isert_init(void)

static void __exit isert_exit(void)
{
	flush_scheduled_work();
	destroy_workqueue(isert_comp_wq);
	destroy_workqueue(isert_rx_wq);
	iscsit_unregister_transport(&iser_target_transport);
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,6 @@ struct isert_device;

struct isert_conn {
	enum iser_conn_state	state;
	bool			logout_posted;
	int			post_recv_buf_count;
	atomic_t		post_send_buf_count;
	u32			responder_resources;
@@ -151,6 +150,7 @@ struct isert_conn {
#define ISERT_COMP_BATCH_COUNT	8
	int			conn_comp_batch;
	struct llist_head	conn_comp_llist;
	bool                    disconnect;
};

#define ISERT_MAX_CQ 64
+1 −0
Original line number Diff line number Diff line
@@ -1773,6 +1773,7 @@ config SCSI_BFA_FC
config SCSI_VIRTIO
	tristate "virtio-scsi support"
	depends on VIRTIO
	select BLK_DEV_INTEGRITY
	help
          This is the virtual HBA driver for virtio.  If the kernel will
          be used in a virtual machine, say Y or M.
+9 −9
Original line number Diff line number Diff line
@@ -338,7 +338,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
	struct iscsi_session *session = conn->session;
	struct scsi_cmnd *sc = task->sc;
	struct iscsi_scsi_req *hdr;
	unsigned hdrlength, cmd_len;
	unsigned hdrlength, cmd_len, transfer_length;
	itt_t itt;
	int rc;

@@ -391,11 +391,11 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
	if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
		task->protected = true;

	transfer_length = scsi_transfer_length(sc);
	hdr->data_length = cpu_to_be32(transfer_length);
	if (sc->sc_data_direction == DMA_TO_DEVICE) {
		unsigned out_len = scsi_out(sc)->length;
		struct iscsi_r2t_info *r2t = &task->unsol_r2t;

		hdr->data_length = cpu_to_be32(out_len);
		hdr->flags |= ISCSI_FLAG_CMD_WRITE;
		/*
		 * Write counters:
@@ -414,18 +414,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
		memset(r2t, 0, sizeof(*r2t));

		if (session->imm_data_en) {
			if (out_len >= session->first_burst)
			if (transfer_length >= session->first_burst)
				task->imm_count = min(session->first_burst,
							conn->max_xmit_dlength);
			else
				task->imm_count = min(out_len,
				task->imm_count = min(transfer_length,
						      conn->max_xmit_dlength);
			hton24(hdr->dlength, task->imm_count);
		} else
			zero_data(hdr->dlength);

		if (!session->initial_r2t_en) {
			r2t->data_length = min(session->first_burst, out_len) -
			r2t->data_length = min(session->first_burst,
					       transfer_length) -
					       task->imm_count;
			r2t->data_offset = task->imm_count;
			r2t->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
@@ -438,7 +439,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
	} else {
		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
		zero_data(hdr->dlength);
		hdr->data_length = cpu_to_be32(scsi_in(sc)->length);

		if (sc->sc_data_direction == DMA_FROM_DEVICE)
			hdr->flags |= ISCSI_FLAG_CMD_READ;
@@ -466,7 +466,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
			  scsi_bidi_cmnd(sc) ? "bidirectional" :
			  sc->sc_data_direction == DMA_TO_DEVICE ?
			  "write" : "read", conn->id, sc, sc->cmnd[0],
			  task->itt, scsi_bufflen(sc),
			  task->itt, transfer_length,
			  scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
			  session->cmdsn,
			  session->max_cmdsn - session->exp_cmdsn + 1);
Loading