Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull SCSI target fixes from Nicholas Bellinger:
 "Here are the target pending fixes for v3.17-rc6.

  Included are Sagi's long overdue fixes related to iser-target
  shutdown, along with a couple of fixes from Sebastian related to ALUA
  Referrals changes that when in during the v3.14 time-frame.

  Also included are a few iscsi-target fixes, most recently of which
  where found during Joern's Coverity scanning of target code"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  iscsi-target: avoid NULL pointer in iscsi_copy_param_list failure
  iscsi-target: Fix memory corruption in iscsit_logout_post_handler_diffcid
  target: Fix inverted logic in SE_DEV_ALUA_SUPPORT_STATE_STORE
  target: Fix user data segment multiplier in spc_emulate_evpd_b3()
  iscsi-target: Ignore ICF_GOT_LAST_DATAOUT during Data-Out ITT lookup
  Target/iser: Fix initiator_depth and responder_resources
  Target/iser: Avoid calling rdma_disconnect twice
  Target/iser: Don't put isert_conn inside disconnected handler
  Target/iser: Get isert_conn reference once got to connected_handler
Linus Torvalds 11 years ago
parent
commit
0d9514334b

+ 11 - 9
drivers/infiniband/ulp/isert/ib_isert.c

@@ -586,17 +586,12 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 	init_completion(&isert_conn->conn_wait);
 	init_completion(&isert_conn->conn_wait);
 	init_completion(&isert_conn->conn_wait_comp_err);
 	init_completion(&isert_conn->conn_wait_comp_err);
 	kref_init(&isert_conn->conn_kref);
 	kref_init(&isert_conn->conn_kref);
-	kref_get(&isert_conn->conn_kref);
 	mutex_init(&isert_conn->conn_mutex);
 	mutex_init(&isert_conn->conn_mutex);
 	spin_lock_init(&isert_conn->conn_lock);
 	spin_lock_init(&isert_conn->conn_lock);
 	INIT_LIST_HEAD(&isert_conn->conn_fr_pool);
 	INIT_LIST_HEAD(&isert_conn->conn_fr_pool);
 
 
 	cma_id->context = isert_conn;
 	cma_id->context = isert_conn;
 	isert_conn->conn_cm_id = cma_id;
 	isert_conn->conn_cm_id = cma_id;
-	isert_conn->responder_resources = event->param.conn.responder_resources;
-	isert_conn->initiator_depth = event->param.conn.initiator_depth;
-	pr_debug("Using responder_resources: %u initiator_depth: %u\n",
-		 isert_conn->responder_resources, isert_conn->initiator_depth);
 
 
 	isert_conn->login_buf = kzalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
 	isert_conn->login_buf = kzalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
 					ISER_RX_LOGIN_SIZE, GFP_KERNEL);
 					ISER_RX_LOGIN_SIZE, GFP_KERNEL);
@@ -643,6 +638,12 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 		goto out_rsp_dma_map;
 		goto out_rsp_dma_map;
 	}
 	}
 
 
+	/* Set max inflight RDMA READ requests */
+	isert_conn->initiator_depth = min_t(u8,
+				event->param.conn.initiator_depth,
+				device->dev_attr.max_qp_init_rd_atom);
+	pr_debug("Using initiator_depth: %u\n", isert_conn->initiator_depth);
+
 	isert_conn->conn_device = device;
 	isert_conn->conn_device = device;
 	isert_conn->conn_pd = ib_alloc_pd(isert_conn->conn_device->ib_device);
 	isert_conn->conn_pd = ib_alloc_pd(isert_conn->conn_device->ib_device);
 	if (IS_ERR(isert_conn->conn_pd)) {
 	if (IS_ERR(isert_conn->conn_pd)) {
@@ -746,7 +747,9 @@ isert_connect_release(struct isert_conn *isert_conn)
 static void
 static void
 isert_connected_handler(struct rdma_cm_id *cma_id)
 isert_connected_handler(struct rdma_cm_id *cma_id)
 {
 {
-	return;
+	struct isert_conn *isert_conn = cma_id->context;
+
+	kref_get(&isert_conn->conn_kref);
 }
 }
 
 
 static void
 static void
@@ -798,7 +801,6 @@ isert_disconnect_work(struct work_struct *work)
 
 
 wake_up:
 wake_up:
 	complete(&isert_conn->conn_wait);
 	complete(&isert_conn->conn_wait);
-	isert_put_conn(isert_conn);
 }
 }
 
 
 static void
 static void
@@ -3067,7 +3069,6 @@ isert_rdma_accept(struct isert_conn *isert_conn)
 	int ret;
 	int ret;
 
 
 	memset(&cp, 0, sizeof(struct rdma_conn_param));
 	memset(&cp, 0, sizeof(struct rdma_conn_param));
-	cp.responder_resources = isert_conn->responder_resources;
 	cp.initiator_depth = isert_conn->initiator_depth;
 	cp.initiator_depth = isert_conn->initiator_depth;
 	cp.retry_count = 7;
 	cp.retry_count = 7;
 	cp.rnr_retry_count = 7;
 	cp.rnr_retry_count = 7;
@@ -3215,7 +3216,7 @@ static void isert_wait_conn(struct iscsi_conn *conn)
 	pr_debug("isert_wait_conn: Starting \n");
 	pr_debug("isert_wait_conn: Starting \n");
 
 
 	mutex_lock(&isert_conn->conn_mutex);
 	mutex_lock(&isert_conn->conn_mutex);
-	if (isert_conn->conn_cm_id) {
+	if (isert_conn->conn_cm_id && !isert_conn->disconnect) {
 		pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
 		pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
 		rdma_disconnect(isert_conn->conn_cm_id);
 		rdma_disconnect(isert_conn->conn_cm_id);
 	}
 	}
@@ -3234,6 +3235,7 @@ static void isert_wait_conn(struct iscsi_conn *conn)
 	wait_for_completion(&isert_conn->conn_wait_comp_err);
 	wait_for_completion(&isert_conn->conn_wait_comp_err);
 
 
 	wait_for_completion(&isert_conn->conn_wait);
 	wait_for_completion(&isert_conn->conn_wait);
+	isert_put_conn(isert_conn);
 }
 }
 
 
 static void isert_free_conn(struct iscsi_conn *conn)
 static void isert_free_conn(struct iscsi_conn *conn)

+ 3 - 1
drivers/target/iscsi/iscsi_target.c

@@ -4540,6 +4540,7 @@ static void iscsit_logout_post_handler_diffcid(
 {
 {
 	struct iscsi_conn *l_conn;
 	struct iscsi_conn *l_conn;
 	struct iscsi_session *sess = conn->sess;
 	struct iscsi_session *sess = conn->sess;
+	bool conn_found = false;
 
 
 	if (!sess)
 	if (!sess)
 		return;
 		return;
@@ -4548,12 +4549,13 @@ static void iscsit_logout_post_handler_diffcid(
 	list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) {
 	list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) {
 		if (l_conn->cid == cid) {
 		if (l_conn->cid == cid) {
 			iscsit_inc_conn_usage_count(l_conn);
 			iscsit_inc_conn_usage_count(l_conn);
+			conn_found = true;
 			break;
 			break;
 		}
 		}
 	}
 	}
 	spin_unlock_bh(&sess->conn_lock);
 	spin_unlock_bh(&sess->conn_lock);
 
 
-	if (!l_conn)
+	if (!conn_found)
 		return;
 		return;
 
 
 	if (l_conn->sock)
 	if (l_conn->sock)

+ 1 - 1
drivers/target/iscsi/iscsi_target_parameters.c

@@ -601,7 +601,7 @@ int iscsi_copy_param_list(
 	param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
 	param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
 	if (!param_list) {
 	if (!param_list) {
 		pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
 		pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
-		goto err_out;
+		return -1;
 	}
 	}
 	INIT_LIST_HEAD(&param_list->param_list);
 	INIT_LIST_HEAD(&param_list->param_list);
 	INIT_LIST_HEAD(&param_list->extra_response_list);
 	INIT_LIST_HEAD(&param_list->extra_response_list);

+ 2 - 0
drivers/target/iscsi/iscsi_target_util.c

@@ -400,6 +400,8 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
 
 
 	spin_lock_bh(&conn->cmd_lock);
 	spin_lock_bh(&conn->cmd_lock);
 	list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
 	list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
+		if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT)
+			continue;
 		if (cmd->init_task_tag == init_task_tag) {
 		if (cmd->init_task_tag == init_task_tag) {
 			spin_unlock_bh(&conn->cmd_lock);
 			spin_unlock_bh(&conn->cmd_lock);
 			return cmd;
 			return cmd;

+ 1 - 1
drivers/target/target_core_configfs.c

@@ -2363,7 +2363,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_support_##_name(\
 		pr_err("Invalid value '%ld', must be '0' or '1'\n", tmp); \
 		pr_err("Invalid value '%ld', must be '0' or '1'\n", tmp); \
 		return -EINVAL;						\
 		return -EINVAL;						\
 	}								\
 	}								\
-	if (!tmp)							\
+	if (tmp)							\
 		t->_var |= _bit;					\
 		t->_var |= _bit;					\
 	else								\
 	else								\
 		t->_var &= ~_bit;					\
 		t->_var &= ~_bit;					\

+ 1 - 1
drivers/target/target_core_spc.c

@@ -664,7 +664,7 @@ spc_emulate_evpd_b3(struct se_cmd *cmd, unsigned char *buf)
 	buf[0] = dev->transport->get_device_type(dev);
 	buf[0] = dev->transport->get_device_type(dev);
 	buf[3] = 0x0c;
 	buf[3] = 0x0c;
 	put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[8]);
 	put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[8]);
-	put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[12]);
+	put_unaligned_be32(dev->t10_alua.lba_map_segment_multiplier, &buf[12]);
 
 
 	return 0;
 	return 0;
 }
 }