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

Commit 1ab142d4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "This contains the usual set of updates and bugfixes to target-core +
  existing fabric module code, along with a handful of the patches
  destined for v3.3 stable.

  It also contains the necessary target-core infrastructure pieces
  required to run using tcm_qla2xxx.ko WWPNs with the new Qlogic Fibre
  Channel fabric module currently queued in target-pending/for-next-merge,
  and coming for round 2.

  The highlights for this series include:

   - Add target_submit_tmr() helper function for fabric task management
     (andy)
   - Convert tcm_fc to use target_submit_tmr() (andy)
   - Replace target core various cmd flags with a transport state (hch)
   - Convert loopback to use workqueue submission (hch)
   - Convert target core to use array_zalloc for tpg_lun_list (joern)
   - Convert target core to use array_zalloc for device_list (joern)
   - Add target core support for TMR_ABORT_TASK (nab)
   - Add target core se_sess->sess_kref + get/put helpers (nab)
   - Add target core se_node_acl->acl_kref for ->acl_free_comp usage
     (nab)
   - Convert iscsi-target to use target_put_session + sess_kref (nab)
   - Fix tcm_fc fc_exch memory leak in ft_send_resp_status (nab)
   - Fix ib_srpt srpt_handle_cmd send_ioctx->ioctx_kref leak on
     exception (nab)
   - Fix target core up handling of short INQUIRY buffers (roland)
   - Untangle target-core front-end and back-end meanings of max_sectors
     attribute (roland)
   - Set loopback residual field for SCSI commands (roland)
   - Fix target-core 16-bit target ports for SET TARGET PORT GROUPS
     emulation (roland)

  Thanks again to Andy, Christoph, Joern, Roland, and everyone who has
  contributed this round!"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (64 commits)
  ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception
  loopback: Fix transport_generic_allocate_tasks error handling
  iscsi-target: remove improper externs
  iscsi-target: Remove unused variables in iscsi_target_parameters.c
  target: remove obvious warnings
  target: Use array_zalloc for device_list
  target: Use array_zalloc for tpg_lun_list
  target: Fix sense code for unsupported SERVICE ACTION IN
  target: Remove hack to make READ CAPACITY(10) lie if thin provisioning is enabled
  target: Bump core version to v4.1.0-rc2-ml + fabric versions
  tcm_fc: Fix fc_exch memory leak in ft_send_resp_status
  target: Drop unused legacy target_core_fabric_ops API callers
  iscsi-target: Convert to use target_put_session + sess_kref
  target: Convert se_node_acl->acl_group removal to use ->acl_kref
  target: Add se_node_acl->acl_kref for ->acl_free_comp usage
  target: Add se_node_acl->acl_free_comp for NodeACL release path
  target: Add se_sess->sess_kref + get/put helpers
  target: Convert session_lock to irqsave
  target: Fix typo in drivers/target
  iscsi-target: Fix dynamic -> explict NodeACL pointer reference
  ...
parents 267d7b23 187e70a5
Loading
Loading
Loading
Loading
+24 −40
Original line number Diff line number Diff line
@@ -1378,7 +1378,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
		break;
	case SRPT_STATE_NEED_DATA:
		/* DMA_TO_DEVICE (write) - RDMA read error. */
		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
		transport_generic_handle_data(&ioctx->cmd);
		break;
	case SRPT_STATE_CMD_RSP_SENT:
@@ -1387,7 +1389,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
		 * not been received in time.
		 */
		srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
		kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
		break;
	case SRPT_STATE_MGMT_RSP_SENT:
@@ -1494,6 +1498,7 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch,
{
	struct se_cmd *cmd;
	enum srpt_command_state state;
	unsigned long flags;

	cmd = &ioctx->cmd;
	state = srpt_get_cmd_state(ioctx);
@@ -1513,7 +1518,9 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch,
			       __func__, __LINE__, state);
		break;
	case SRPT_RDMA_WRITE_LAST:
		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
		break;
	default:
		printk(KERN_ERR "%s[%d]: opcode = %u\n", __func__,
@@ -1750,6 +1757,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
		       srp_cmd->tag);
		cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		goto send_sense;
	}

@@ -1757,15 +1765,19 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
	cmd->data_direction = dir;
	unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
				       sizeof(srp_cmd->lun));
	if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0)
	if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) {
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		goto send_sense;
	}
	ret = transport_generic_allocate_tasks(cmd, srp_cmd->cdb);
	if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
	if (ret < 0) {
		kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
		if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) {
			srpt_queue_status(cmd);
	else if (cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)
			return 0;
		} else
			goto send_sense;
	else
		WARN_ON_ONCE(ret);
	}

	transport_handle_cdb_direct(cmd);
	return 0;
@@ -1871,8 +1883,8 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
		goto process_tmr;
	}
	cmd->se_tmr_req = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
	if (!cmd->se_tmr_req) {
	res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
	if (res < 0) {
		send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
		send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
		goto process_tmr;
@@ -3513,25 +3525,6 @@ static void srpt_close_session(struct se_session *se_sess)
	WARN_ON(res <= 0);
}

/**
 * To do: Find out whether stop_session() has a meaning for transports
 * other than iSCSI.
 */
static void srpt_stop_session(struct se_session *se_sess, int sess_sleep,
			      int conn_sleep)
{
}

static void srpt_reset_nexus(struct se_session *sess)
{
	printk(KERN_ERR "This is the SRP protocol, not iSCSI\n");
}

static int srpt_sess_logged_in(struct se_session *se_sess)
{
	return true;
}

/**
 * srpt_sess_get_index() - Return the value of scsiAttIntrPortIndex (SCSI-MIB).
 *
@@ -3576,11 +3569,6 @@ static u16 srpt_get_fabric_sense_len(void)
	return 0;
}

static int srpt_is_state_remove(struct se_cmd *se_cmd)
{
	return 0;
}

/**
 * srpt_parse_i_port_id() - Parse an initiator port ID.
 * @name: ASCII representation of a 128-bit initiator port ID.
@@ -3950,9 +3938,6 @@ static struct target_core_fabric_ops srpt_template = {
	.check_stop_free		= srpt_check_stop_free,
	.shutdown_session		= srpt_shutdown_session,
	.close_session			= srpt_close_session,
	.stop_session			= srpt_stop_session,
	.fall_back_to_erl0		= srpt_reset_nexus,
	.sess_logged_in			= srpt_sess_logged_in,
	.sess_get_index			= srpt_sess_get_index,
	.sess_get_initiator_sid		= NULL,
	.write_pending			= srpt_write_pending,
@@ -3965,7 +3950,6 @@ static struct target_core_fabric_ops srpt_template = {
	.queue_tm_rsp			= srpt_queue_response,
	.get_fabric_sense_len		= srpt_get_fabric_sense_len,
	.set_fabric_sense_len		= srpt_set_fabric_sense_len,
	.is_state_remove		= srpt_is_state_remove,
	/*
	 * Setup function pointers for generic logic in
	 * target_core_fabric_configfs.c
+1 −3
Original line number Diff line number Diff line
@@ -1682,9 +1682,7 @@ void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,

	memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));

	int_to_scsilun(sc_cmd->device->lun,
			(struct scsi_lun *) fcp_cmnd->fc_lun);

	int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);

	fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
	memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
+2 −3
Original line number Diff line number Diff line
@@ -1074,8 +1074,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
	fsp->cdb_cmd.fc_dl = htonl(fsp->data_len);
	fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK;

	int_to_scsilun(fsp->cmd->device->lun,
		       (struct scsi_lun *)fsp->cdb_cmd.fc_lun);
	int_to_scsilun(fsp->cmd->device->lun, &fsp->cdb_cmd.fc_lun);
	memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len);

	spin_lock_irqsave(&si->scsi_queue_lock, flags);
@@ -1257,7 +1256,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp,

	fsp->cdb_cmd.fc_dl = htonl(fsp->data_len);
	fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET;
	int_to_scsilun(lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun);
	int_to_scsilun(lun, &fsp->cdb_cmd.fc_lun);

	fsp->wait_for_comp = 1;
	init_completion(&fsp->tm_done);
+14 −27
Original line number Diff line number Diff line
@@ -781,7 +781,7 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
	struct scatterlist *sgl;
	u32 length = cmd->se_cmd.data_length;
	int nents = DIV_ROUND_UP(length, PAGE_SIZE);
	int i = 0, ret;
	int i = 0, j = 0, ret;
	/*
	 * If no SCSI payload is present, allocate the default iovecs used for
	 * iSCSI PDU Header
@@ -822,17 +822,15 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
	 */
        ret = iscsit_allocate_iovecs(cmd);
        if (ret < 0)
		goto page_alloc_failed;
		return -ENOMEM;

	return 0;

page_alloc_failed:
	while (i >= 0) {
		__free_page(sg_page(&sgl[i]));
		i--;
	}
	kfree(cmd->t_mem_sg);
	cmd->t_mem_sg = NULL;
	while (j < i)
		__free_page(sg_page(&sgl[j++]));

	kfree(sgl);
	return -ENOMEM;
}

@@ -1007,8 +1005,8 @@ static int iscsit_handle_scsi_cmd(
	/*
	 * The CDB is going to an se_device_t.
	 */
	ret = iscsit_get_lun_for_cmd(cmd, hdr->cdb,
				get_unaligned_le64(&hdr->lun));
	ret = transport_lookup_cmd_lun(&cmd->se_cmd,
				       scsilun_to_int(&hdr->lun));
	if (ret < 0) {
		if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) {
			pr_debug("Responding to non-acl'ed,"
@@ -1364,7 +1362,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
		 * outstanding_r2ts reaches zero, go ahead and send the delayed
		 * TASK_ABORTED status.
		 */
		if (atomic_read(&se_cmd->t_transport_aborted) != 0) {
		if (se_cmd->transport_state & CMD_T_ABORTED) {
			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
				if (--cmd->outstanding_r2ts < 1) {
					iscsit_stop_dataout_timer(cmd);
@@ -1472,14 +1470,12 @@ static int iscsit_handle_nop_out(
	unsigned char *ping_data = NULL;
	int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size;
	u32 checksum, data_crc, padding = 0, payload_length;
	u64 lun;
	struct iscsi_cmd *cmd = NULL;
	struct kvec *iov = NULL;
	struct iscsi_nopout *hdr;

	hdr			= (struct iscsi_nopout *) buf;
	payload_length		= ntoh24(hdr->dlength);
	lun			= get_unaligned_le64(&hdr->lun);
	hdr->itt		= be32_to_cpu(hdr->itt);
	hdr->ttt		= be32_to_cpu(hdr->ttt);
	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
@@ -1689,13 +1685,11 @@ static int iscsit_handle_task_mgt_cmd(
	struct se_tmr_req *se_tmr;
	struct iscsi_tmr_req *tmr_req;
	struct iscsi_tm *hdr;
	u32 payload_length;
	int out_of_order_cmdsn = 0;
	int ret;
	u8 function;

	hdr			= (struct iscsi_tm *) buf;
	payload_length		= ntoh24(hdr->dlength);
	hdr->itt		= be32_to_cpu(hdr->itt);
	hdr->rtt		= be32_to_cpu(hdr->rtt);
	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
@@ -1747,8 +1741,8 @@ static int iscsit_handle_task_mgt_cmd(
	 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
	 */
	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
		ret = iscsit_get_lun_for_tmr(cmd,
				get_unaligned_le64(&hdr->lun));
		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
					       scsilun_to_int(&hdr->lun));
		if (ret < 0) {
			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
@@ -2207,14 +2201,10 @@ static int iscsit_handle_snack(
	struct iscsi_conn *conn,
	unsigned char *buf)
{
	u32 unpacked_lun;
	u64 lun;
	struct iscsi_snack *hdr;

	hdr			= (struct iscsi_snack *) buf;
	hdr->flags		&= ~ISCSI_FLAG_CMD_FINAL;
	lun			= get_unaligned_le64(&hdr->lun);
	unpacked_lun		= scsilun_to_int((struct scsi_lun *)&lun);
	hdr->itt		= be32_to_cpu(hdr->itt);
	hdr->ttt		= be32_to_cpu(hdr->ttt);
	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
@@ -3514,7 +3504,6 @@ int iscsi_target_tx_thread(void *arg)
	struct iscsi_cmd *cmd = NULL;
	struct iscsi_conn *conn;
	struct iscsi_queue_req *qr = NULL;
	struct se_cmd *se_cmd;
	struct iscsi_thread_set *ts = arg;
	/*
	 * Allow ourselves to be interrupted by SIGINT so that a
@@ -3697,8 +3686,6 @@ int iscsi_target_tx_thread(void *arg)
				goto transport_err;
			}

			se_cmd = &cmd->se_cmd;

			if (map_sg && !conn->conn_ops->IFMarker) {
				if (iscsit_fe_sendpage_sg(cmd, conn) < 0) {
					conn->tx_response_queue = 0;
@@ -4171,7 +4158,7 @@ int iscsit_close_connection(
	if (!atomic_read(&sess->session_reinstatement) &&
	     atomic_read(&sess->session_fall_back_to_erl0)) {
		spin_unlock_bh(&sess->conn_lock);
		iscsit_close_session(sess);
		target_put_session(sess->se_sess);

		return 0;
	} else if (atomic_read(&sess->session_logout)) {
@@ -4292,7 +4279,7 @@ static void iscsit_logout_post_handler_closesession(
	iscsit_dec_conn_usage_count(conn);
	iscsit_stop_session(sess, 1, 1);
	iscsit_dec_session_usage_count(sess);
	iscsit_close_session(sess);
	target_put_session(sess->se_sess);
}

static void iscsit_logout_post_handler_samecid(
@@ -4458,7 +4445,7 @@ int iscsit_free_session(struct iscsi_session *sess)
	} else
		spin_unlock_bh(&sess->conn_lock);

	iscsit_close_session(sess);
	target_put_session(sess->se_sess);
	return 0;
}

+3 −50
Original line number Diff line number Diff line
@@ -812,9 +812,6 @@ static struct se_node_acl *lio_target_make_nodeacl(
	if (!se_nacl_new)
		return ERR_PTR(-ENOMEM);

	acl = container_of(se_nacl_new, struct iscsi_node_acl,
				se_node_acl);

	cmdsn_depth = ISCSI_TPG_ATTRIB(tpg)->default_cmdsn_depth;
	/*
	 * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
@@ -825,7 +822,8 @@ static struct se_node_acl *lio_target_make_nodeacl(
	if (IS_ERR(se_nacl))
		return se_nacl;

	stats_cg = &acl->se_node_acl.acl_fabric_stat_group;
	acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
	stats_cg = &se_nacl->acl_fabric_stat_group;

	stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
				GFP_KERNEL);
@@ -1505,28 +1503,6 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
	return cmd->i_state;
}

static int iscsi_is_state_remove(struct se_cmd *se_cmd)
{
	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);

	return (cmd->i_state == ISTATE_REMOVE);
}

static int lio_sess_logged_in(struct se_session *se_sess)
{
	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
	int ret;
	/*
	 * Called with spin_lock_bh(&tpg_lock); and
	 * spin_lock(&se_tpg->session_lock); held.
	 */
	spin_lock(&sess->conn_lock);
	ret = (sess->session_state != TARG_SESS_STATE_LOGGED_IN);
	spin_unlock(&sess->conn_lock);

	return ret;
}

static u32 lio_sess_get_index(struct se_session *se_sess)
{
	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
@@ -1700,8 +1676,8 @@ static int lio_tpg_shutdown_session(struct se_session *se_sess)
	atomic_set(&sess->session_reinstatement, 1);
	spin_unlock(&sess->conn_lock);

	iscsit_inc_session_usage_count(sess);
	iscsit_stop_time2retain_timer(sess);
	iscsit_stop_session(sess, 1, 1);

	return 1;
}
@@ -1717,28 +1693,9 @@ static void lio_tpg_close_session(struct se_session *se_sess)
	 * If the iSCSI Session for the iSCSI Initiator Node exists,
	 * forcefully shutdown the iSCSI NEXUS.
	 */
	iscsit_stop_session(sess, 1, 1);
	iscsit_dec_session_usage_count(sess);
	iscsit_close_session(sess);
}

static void lio_tpg_stop_session(
	struct se_session *se_sess,
	int sess_sleep,
	int conn_sleep)
{
	struct iscsi_session *sess = se_sess->fabric_sess_ptr;

	iscsit_stop_session(sess, sess_sleep, conn_sleep);
}

static void lio_tpg_fall_back_to_erl0(struct se_session *se_sess)
{
	struct iscsi_session *sess = se_sess->fabric_sess_ptr;

	iscsit_fall_back_to_erl0(sess);
}

static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
{
	struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
@@ -1802,9 +1759,6 @@ int iscsi_target_register_configfs(void)
	fabric->tf_ops.release_cmd = &lio_release_cmd;
	fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session;
	fabric->tf_ops.close_session = &lio_tpg_close_session;
	fabric->tf_ops.stop_session = &lio_tpg_stop_session;
	fabric->tf_ops.fall_back_to_erl0 = &lio_tpg_fall_back_to_erl0;
	fabric->tf_ops.sess_logged_in = &lio_sess_logged_in;
	fabric->tf_ops.sess_get_index = &lio_sess_get_index;
	fabric->tf_ops.sess_get_initiator_sid = &lio_sess_get_initiator_sid;
	fabric->tf_ops.write_pending = &lio_write_pending;
@@ -1818,7 +1772,6 @@ int iscsi_target_register_configfs(void)
	fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
	fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len;
	fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len;
	fabric->tf_ops.is_state_remove = &iscsi_is_state_remove;
	/*
	 * Setup function pointers for generic logic in target_core_fabric_configfs.c
	 */
Loading