Commit a7aa96a9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull scsi target fixes from Nicholas Bellinger:
 "This series include:

   - Close race between iser-target network portal shutdown + accepting
     new connection logins (sagi)
   - Fix free-after-use regression in tcm_fc post conversion to
     percpu-ida pre-allocation (nab)
   - Explicitly disable Immediate + Unsolicited Data for iser-target
     connections when T10-PI is enabled (sagi + nab)
   - Allow pi_prot_type + emulate_write_cache attributes to be set to
     zero regardless of backend support (andy)
   - memory leak fix (mikulas)"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  target: fix memory leak on XCOPY
  target: Don't allow setting WC emulation if device doesn't support
  iscsi-target: Disable Immediate + Unsolicited Data with ISER Protection
  tcm_fc: Fix free-after-use regression in ft_free_cmd
  iscsi-target: Change BUG_ON to REJECT in iscsit_process_nop_out
  Target/iscsi,iser: Avoid accepting transport connections during stop stage
  Target/iser: Fix iscsit_accept_np and rdma_cm racy flow
  Target/iser: Fix wrong connection requests list addition
  target: Allow non-supporting backends to set pi_prot_type to 0
parents b1400276 1e1110c4
Loading
Loading
Loading
Loading
+17 −21
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>
#include <target/iscsi/iscsi_transport.h>
#include <linux/semaphore.h>

#include "isert_proto.h"
#include "ib_isert.h"
@@ -561,7 +562,15 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
	struct isert_device *device;
	struct ib_device *ib_dev = cma_id->device;
	int ret = 0;
	u8 pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi;
	u8 pi_support;

	spin_lock_bh(&np->np_thread_lock);
	if (!np->enabled) {
		spin_unlock_bh(&np->np_thread_lock);
		pr_debug("iscsi_np is not enabled, reject connect request\n");
		return rdma_reject(cma_id, NULL, 0);
	}
	spin_unlock_bh(&np->np_thread_lock);

	pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n",
		 cma_id, cma_id->context);
@@ -652,6 +661,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
		goto out_mr;
	}

	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;
@@ -663,11 +673,11 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
		goto out_conn_dev;

	mutex_lock(&isert_np->np_accept_mutex);
	list_add_tail(&isert_np->np_accept_list, &isert_conn->conn_accept_node);
	list_add_tail(&isert_conn->conn_accept_node, &isert_np->np_accept_list);
	mutex_unlock(&isert_np->np_accept_mutex);

	pr_debug("isert_connect_request() waking up np_accept_wq: %p\n", np);
	wake_up(&isert_np->np_accept_wq);
	pr_debug("isert_connect_request() up np_sem np: %p\n", np);
	up(&isert_np->np_sem);
	return 0;

out_conn_dev:
@@ -2999,7 +3009,7 @@ isert_setup_np(struct iscsi_np *np,
		pr_err("Unable to allocate struct isert_np\n");
		return -ENOMEM;
	}
	init_waitqueue_head(&isert_np->np_accept_wq);
	sema_init(&isert_np->np_sem, 0);
	mutex_init(&isert_np->np_accept_mutex);
	INIT_LIST_HEAD(&isert_np->np_accept_list);
	init_completion(&isert_np->np_login_comp);
@@ -3047,18 +3057,6 @@ out:
	return ret;
}

static int
isert_check_accept_queue(struct isert_np *isert_np)
{
	int empty;

	mutex_lock(&isert_np->np_accept_mutex);
	empty = list_empty(&isert_np->np_accept_list);
	mutex_unlock(&isert_np->np_accept_mutex);

	return empty;
}

static int
isert_rdma_accept(struct isert_conn *isert_conn)
{
@@ -3151,16 +3149,14 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
	int max_accept = 0, ret;

accept_wait:
	ret = wait_event_interruptible(isert_np->np_accept_wq,
			!isert_check_accept_queue(isert_np) ||
			np->np_thread_state == ISCSI_NP_THREAD_RESET);
	ret = down_interruptible(&isert_np->np_sem);
	if (max_accept > 5)
		return -ENODEV;

	spin_lock_bh(&np->np_thread_lock);
	if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
		spin_unlock_bh(&np->np_thread_lock);
		pr_err("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
		pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
		return -ENODEV;
	}
	spin_unlock_bh(&np->np_thread_lock);
+1 −1
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ struct isert_device {
};

struct isert_np {
	wait_queue_head_t	np_accept_wq;
	struct semaphore	np_sem;
	struct rdma_cm_id	*np_cm_id;
	struct mutex		np_accept_mutex;
	struct list_head	np_accept_list;
+3 −1
Original line number Diff line number Diff line
@@ -1593,7 +1593,9 @@ int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
	 * Initiator is expecting a NopIN ping reply..
	 */
	if (hdr->itt != RESERVED_ITT) {
		BUG_ON(!cmd);
		if (!cmd)
			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
						(unsigned char *)hdr);

		spin_lock_bh(&conn->cmd_lock);
		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
+1 −0
Original line number Diff line number Diff line
@@ -775,6 +775,7 @@ struct iscsi_np {
	int			np_ip_proto;
	int			np_sock_type;
	enum np_thread_state_table np_thread_state;
	bool                    enabled;
	enum iscsi_timer_flags_table np_login_timer_flags;
	u32			np_exports;
	enum np_flags_table	np_flags;
+27 −1
Original line number Diff line number Diff line
@@ -436,7 +436,7 @@ static int iscsi_login_zero_tsih_s2(
		}
		off = mrdsl % PAGE_SIZE;
		if (!off)
			return 0;
			goto check_prot;

		if (mrdsl < PAGE_SIZE)
			mrdsl = PAGE_SIZE;
@@ -452,6 +452,31 @@ static int iscsi_login_zero_tsih_s2(
				ISCSI_LOGIN_STATUS_NO_RESOURCES);
			return -1;
		}
		/*
		 * ISER currently requires that ImmediateData + Unsolicited
		 * Data be disabled when protection / signature MRs are enabled.
		 */
check_prot:
		if (sess->se_sess->sup_prot_ops &
		   (TARGET_PROT_DOUT_STRIP | TARGET_PROT_DOUT_PASS |
		    TARGET_PROT_DOUT_INSERT)) {

			sprintf(buf, "ImmediateData=No");
			if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
				iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
						    ISCSI_LOGIN_STATUS_NO_RESOURCES);
				return -1;
			}

			sprintf(buf, "InitialR2T=Yes");
			if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
				iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
						    ISCSI_LOGIN_STATUS_NO_RESOURCES);
				return -1;
			}
			pr_debug("Forcing ImmediateData=No + InitialR2T=Yes for"
				 " T10-PI enabled ISER session\n");
		}
	}

	return 0;
@@ -984,6 +1009,7 @@ int iscsi_target_setup_login_socket(
	}

	np->np_transport = t;
	np->enabled = true;
	return 0;
}

Loading