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

Commit cb47c183 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull target updates from Nicholas Bellinger:
 "There have been lots of work in a number of areas this past round.
  The highlights include:

   - Break out target_core_cdb.c emulation into SPC/SBC ops (hch)
   - Add a parse_cdb method to target backend drivers (hch)
   - Move sync_cache + write_same + unmap into spc_ops (hch)
   - Use target_execute_cmd for WRITEs in iscsi_target + srpt (hch)
   - Offload WRITE I/O backend submission in tcm_qla2xxx + tcm_fc (hch +
     nab)
   - Refactor core_update_device_list_for_node() into enable/disable
     funcs (agrover)
   - Replace the TCM processing thread with a TMR work queue (hch)
   - Fix regression in transport_add_device_to_core_hba from TMR
     conversion (DanC)
   - Remove racy, now-redundant check of sess_tearing_down with qla2xxx
     (roland)
   - Add range checking, fix reading of data len + possible underflow in
     UNMAP (roland)
   - Allow for target_submit_cmd() returning errors + convert fabrics
     (roland + nab)
   - Drop bogus struct file usage for iSCSI/SCTP (viro)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (54 commits)
  iscsi-target: Drop bogus struct file usage for iSCSI/SCTP
  target: NULL dereference on error path
  target: Allow for target_submit_cmd() returning errors
  target: Check number of unmap descriptors against our limit
  target: Fix possible integer underflow in UNMAP emulation
  target: Fix reading of data length fields for UNMAP commands
  target: Add range checking to UNMAP emulation
  target: Add generation of LOGICAL BLOCK ADDRESS OUT OF RANGE
  target: Make unnecessarily global se_dev_align_max_sectors() static
  target: Remove se_session.sess_wait_list
  qla2xxx: Remove racy, now-redundant check of sess_tearing_down
  target: Check sess_tearing_down in target_get_sess_cmd()
  sbp-target: Consolidate duplicated error path code in sbp_handle_command()
  target: Un-export target_get_sess_cmd()
  qla2xxx: Get rid of redundant qla_tgt_sess.tearing_down
  target: Make core_disable_device_list_for_node use pre-refactoring lock ordering
  target: refactor core_update_device_list_for_node()
  target: Eliminate else using boolean logic
  target: Misc retval cleanups
  target: Remove hba param from core_dev_add_lun
  ...
parents 4d460fd3 bf6932f4
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -1377,10 +1377,14 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
		break;
	case SRPT_STATE_NEED_DATA:
		/* DMA_TO_DEVICE (write) - RDMA read error. */

		/* XXX(hch): this is a horrible layering violation.. */
		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
		ioctx->cmd.transport_state &= ~CMD_T_ACTIVE;
		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
		transport_generic_handle_data(&ioctx->cmd);

		complete(&ioctx->cmd.transport_lun_stop_comp);
		break;
	case SRPT_STATE_CMD_RSP_SENT:
		/*
@@ -1463,9 +1467,10 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
/**
 * srpt_handle_rdma_comp() - Process an IB RDMA completion notification.
 *
 * Note: transport_generic_handle_data() is asynchronous so unmapping the
 * data that has been transferred via IB RDMA must be postponed until the
 * check_stop_free() callback.
 * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping
 * the data that has been transferred via IB RDMA had to be postponed until the
 * check_stop_free() callback.  None of this is nessecary anymore and needs to
 * be cleaned up.
 */
static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch,
				  struct srpt_send_ioctx *ioctx,
@@ -1477,7 +1482,7 @@ static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch,
	if (opcode == SRPT_RDMA_READ_LAST) {
		if (srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA,
						SRPT_STATE_DATA_IN))
			transport_generic_handle_data(&ioctx->cmd);
			target_execute_cmd(&ioctx->cmd);
		else
			printk(KERN_ERR "%s[%d]: wrong state = %d\n", __func__,
			       __LINE__, srpt_get_cmd_state(ioctx));
+3 −13
Original line number Diff line number Diff line
@@ -2643,19 +2643,9 @@ static void qlt_do_work(struct work_struct *work)
	spin_lock_irqsave(&ha->hardware_lock, flags);
	sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
	    atio->u.isp24.fcp_hdr.s_id);
	if (sess) {
		if (unlikely(sess->tearing_down)) {
			sess = NULL;
			spin_unlock_irqrestore(&ha->hardware_lock, flags);
			goto out_term;
		} else {
			/*
			 * Do the extra kref_get() before dropping
			 * qla_hw_data->hardware_lock.
			 */
	/* Do kref_get() before dropping qla_hw_data->hardware_lock. */
	if (sess)
		kref_get(&sess->se_sess->sess_kref);
		}
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	if (unlikely(!sess)) {
+1 −2
Original line number Diff line number Diff line
@@ -639,7 +639,7 @@ struct qla_tgt_func_tmpl {

	int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
			unsigned char *, uint32_t, int, int, int);
	int (*handle_data)(struct qla_tgt_cmd *);
	void (*handle_data)(struct qla_tgt_cmd *);
	int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t,
			uint32_t);
	void (*free_cmd)(struct qla_tgt_cmd *);
@@ -813,7 +813,6 @@ struct qla_tgt_sess {
	unsigned int conf_compl_supported:1;
	unsigned int deleted:1;
	unsigned int local:1;
	unsigned int tearing_down:1;

	struct se_session *se_sess;
	struct scsi_qla_host *vha;
+20 −35
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@
#include <linux/string.h>
#include <linux/configfs.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -466,8 +464,7 @@ static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess)
	vha = sess->vha;

	spin_lock_irqsave(&vha->hw->hardware_lock, flags);
	sess->tearing_down = 1;
	target_splice_sess_cmd_list(se_sess);
	target_sess_cmd_list_set_waiting(se_sess);
	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);

	return 1;
@@ -600,28 +597,15 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
		return -EINVAL;
	}

	target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
	return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
				cmd->unpacked_lun, data_length, fcp_task_attr,
				data_dir, flags);
	return 0;
}

static void tcm_qla2xxx_do_rsp(struct work_struct *work)
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
{
	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
	/*
	 * Dispatch ->queue_status from workqueue process context
	 */
	transport_generic_request_failure(&cmd->se_cmd);
}

/*
 * Called from qla_target.c:qlt_do_ctio_completion()
 */
static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
{
	struct se_cmd *se_cmd = &cmd->se_cmd;
	unsigned long flags;
	/*
	 * Ensure that the complete FCP WRITE payload has been received.
	 * Otherwise return an exception via CHECK_CONDITION status.
@@ -631,24 +615,26 @@ static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
		 * Check if se_cmd has already been aborted via LUN_RESET, and
		 * waiting upon completion in tcm_qla2xxx_write_pending_status()
		 */
		spin_lock_irqsave(&se_cmd->t_state_lock, flags);
		if (se_cmd->transport_state & CMD_T_ABORTED) {
			spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
			complete(&se_cmd->t_transport_stop_comp);
			return 0;
		if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
			complete(&cmd->se_cmd.t_transport_stop_comp);
			return;
		}
		spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);

		se_cmd->scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD;
		INIT_WORK(&cmd->work, tcm_qla2xxx_do_rsp);
		queue_work(tcm_qla2xxx_free_wq, &cmd->work);
		return 0;
		cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD;
		transport_generic_request_failure(&cmd->se_cmd);
		return;
	}

	return target_execute_cmd(&cmd->se_cmd);
}

/*
	 * We now tell TCM to queue this WRITE CDB with TRANSPORT_PROCESS_WRITE
	 * status to the backstore processing thread.
 * Called from qla_target.c:qlt_do_ctio_completion()
 */
	return transport_generic_handle_data(&cmd->se_cmd);
static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
{
	INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
	queue_work(tcm_qla2xxx_free_wq, &cmd->work);
}

/*
@@ -1690,7 +1676,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
	.tpg_alloc_fabric_acl		= tcm_qla2xxx_alloc_fabric_acl,
	.tpg_release_fabric_acl		= tcm_qla2xxx_release_fabric_acl,
	.tpg_get_inst_index		= tcm_qla2xxx_tpg_get_inst_index,
	.new_cmd_map			= NULL,
	.check_stop_free		= tcm_qla2xxx_check_stop_free,
	.release_cmd			= tcm_qla2xxx_release_cmd,
	.put_session			= tcm_qla2xxx_put_session,
+2 −1
Original line number Diff line number Diff line
@@ -9,7 +9,8 @@ target_core_mod-y := target_core_configfs.o \
				   target_core_tmr.o \
				   target_core_tpg.o \
				   target_core_transport.o \
				   target_core_cdb.o \
				   target_core_sbc.o \
				   target_core_spc.o \
				   target_core_ua.o \
				   target_core_rd.o \
				   target_core_stat.o
Loading