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

Commit 36511e86 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target fixes from Nicholas Bellinger:
 - fix tcm-user backend driver expired cmd time processing (agrover)
 - eliminate kref_put_spinlock_irqsave() for I/O completion (bart)
 - fix iscsi login kthread failure case hung task regression (nab)
 - fix COMPARE_AND_WRITE completion use-after-free race (nab)
 - fix COMPARE_AND_WRITE with SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC non zero
   SGL offset data corruption.  (Jan + Doug)
 - fix >= v4.4-rc1 regression for tcm_qla2xxx enable configfs attribute
   (Himanshu + HCH)

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  target/stat: print full t10_wwn.model buffer
  target: fix COMPARE_AND_WRITE non zero SGL offset data corruption
  qla2xxx: Fix regression introduced by target configFS changes
  kref: Remove kref_put_spinlock_irqsave()
  target: Invoke release_cmd() callback without holding a spinlock
  target: Fix race for SCF_COMPARE_AND_WRITE_POST checking
  iscsi-target: Fix rx_login_comp hang after login failure
  iscsi-target: return -ENOMEM instead of -1 in case of failed kmalloc()
  target/user: Do not set unused fields in tcmu_ops
  target/user: Fix time calc in expired cmd processing
parents 75a29ec1 8f903539
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -902,7 +902,7 @@ static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item,
	return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type);
}

CONFIGFS_ATTR_WO(tcm_qla2xxx_tpg_, enable);
CONFIGFS_ATTR(tcm_qla2xxx_tpg_, enable);
CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions);
CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type);

+12 −1
Original line number Diff line number Diff line
@@ -4074,6 +4074,17 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
	return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
}

static bool iscsi_target_check_conn_state(struct iscsi_conn *conn)
{
	bool ret;

	spin_lock_bh(&conn->state_lock);
	ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN);
	spin_unlock_bh(&conn->state_lock);

	return ret;
}

int iscsi_target_rx_thread(void *arg)
{
	int ret, rc;
@@ -4091,7 +4102,7 @@ int iscsi_target_rx_thread(void *arg)
	 * incoming iscsi/tcp socket I/O, and/or failing the connection.
	 */
	rc = wait_for_completion_interruptible(&conn->rx_login_comp);
	if (rc < 0)
	if (rc < 0 || iscsi_target_check_conn_state(conn))
		return 0;

	if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {
+1 −0
Original line number Diff line number Diff line
@@ -388,6 +388,7 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
	if (login->login_complete) {
		if (conn->rx_thread && conn->rx_thread_active) {
			send_sig(SIGINT, conn->rx_thread, 1);
			complete(&conn->rx_login_comp);
			kthread_stop(conn->rx_thread);
		}
		if (conn->tx_thread && conn->tx_thread_active) {
+5 −5
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
	if (!pl) {
		pr_err("Unable to allocate memory for"
				" struct iscsi_param_list.\n");
		return -1 ;
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&pl->param_list);
	INIT_LIST_HEAD(&pl->extra_response_list);
@@ -578,7 +578,7 @@ int iscsi_copy_param_list(
	param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
	if (!param_list) {
		pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
		return -1;
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&param_list->param_list);
	INIT_LIST_HEAD(&param_list->extra_response_list);
@@ -629,7 +629,7 @@ int iscsi_copy_param_list(

err_out:
	iscsi_release_param_list(param_list);
	return -1;
	return -ENOMEM;
}

static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
@@ -729,7 +729,7 @@ static int iscsi_add_notunderstood_response(
	if (!extra_response) {
		pr_err("Unable to allocate memory for"
			" struct iscsi_extra_response.\n");
		return -1;
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&extra_response->er_list);

@@ -1370,7 +1370,7 @@ int iscsi_decode_text_input(
	tmpbuf = kzalloc(length + 1, GFP_KERNEL);
	if (!tmpbuf) {
		pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length);
		return -1;
		return -ENOMEM;
	}

	memcpy(tmpbuf, textbuf, length);
+11 −6
Original line number Diff line number Diff line
@@ -371,7 +371,8 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o
	return 0;
}

static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success)
static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success,
					   int *post_ret)
{
	unsigned char *buf, *addr;
	struct scatterlist *sg;
@@ -437,7 +438,8 @@ sbc_execute_rw(struct se_cmd *cmd)
			       cmd->data_direction);
}

static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success,
					     int *post_ret)
{
	struct se_device *dev = cmd->se_dev;

@@ -447,8 +449,10 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
	 * sent to the backend driver.
	 */
	spin_lock_irq(&cmd->t_state_lock);
	if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status)
	if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) {
		cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
		*post_ret = 1;
	}
	spin_unlock_irq(&cmd->t_state_lock);

	/*
@@ -460,7 +464,8 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success)
	return TCM_NO_SENSE;
}

static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success)
static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success,
						 int *post_ret)
{
	struct se_device *dev = cmd->se_dev;
	struct scatterlist *write_sg = NULL, *sg;
@@ -556,11 +561,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes

		if (block_size < PAGE_SIZE) {
			sg_set_page(&write_sg[i], m.page, block_size,
				    block_size);
				    m.piter.sg->offset + block_size);
		} else {
			sg_miter_next(&m);
			sg_set_page(&write_sg[i], m.page, block_size,
				    0);
				    m.piter.sg->offset);
		}
		len -= block_size;
		i++;
Loading