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

Commit 141eaccd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "Here are the target pending updates for v3.15-rc1.  Apologies in
  advance for waiting until the second to last day of the merge window
  to send these out.

  The highlights this round include:

   - iser-target support for T10 PI (DIF) offloads (Sagi + Or)
   - Fix Task Aborted Status (TAS) handling in target-core (Alex Leung)
   - Pass in transport supported PI at session initialization (Sagi + MKP + nab)
   - Add WRITE_INSERT + READ_STRIP T10 PI support in target-core (nab + Sagi)
   - Fix iscsi-target ERL=2 ASYNC_EVENT connection pointer bug (nab)
   - Fix tcm_fc use-after-free of ft_tpg (Andy Grover)
   - Use correct ib_sg_dma primitives in ib_isert (Mike Marciniszyn)

  Also, note the virtio-scsi + vhost-scsi changes to expose T10 PI
  metadata into KVM guest have been left-out for now, as there where a
  few comments from MST + Paolo that where not able to be addressed in
  time for v3.15.  Please expect this feature for v3.16-rc1"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (43 commits)
  ib_srpt: Use correct ib_sg_dma primitives
  target/tcm_fc: Rename ft_tport_create to ft_tport_get
  target/tcm_fc: Rename ft_{add,del}_lport to {add,del}_wwn
  target/tcm_fc: Rename structs and list members for clarity
  target/tcm_fc: Limit to 1 TPG per wwn
  target/tcm_fc: Don't export ft_lport_list
  target/tcm_fc: Fix use-after-free of ft_tpg
  target: Add check to prevent Abort Task from aborting itself
  target: Enable READ_STRIP emulation in target_complete_ok_work
  target/sbc: Add sbc_dif_read_strip software emulation
  target: Enable WRITE_INSERT emulation in target_execute_cmd
  target/sbc: Add sbc_dif_generate software emulation
  target/sbc: Only expose PI read_cap16 bits when supported by fabric
  target/spc: Only expose PI mode page bits when supported by fabric
  target/spc: Only expose PI inquiry bits when supported by fabric
  target: Pass in transport supported PI at session initialization
  target/iblock: Fix double bioset_integrity_free bug
  Target/sbc: Initialize COMPARE_AND_WRITE write_sg scatterlist
  target/rd: T10-Dif: RAM disk is allocating more space than required.
  iscsi-target: Fix ERL=2 ASYNC_EVENT connection pointer bug
  ...
parents 93094449 b0768080
Loading
Loading
Loading
Loading
+639 −189

File changed.

Preview size limit exceeded, changes collapsed.

+31 −7
Original line number Diff line number Diff line
@@ -50,11 +50,35 @@ struct iser_tx_desc {
	struct ib_send_wr send_wr;
} __packed;

enum isert_indicator {
	ISERT_PROTECTED		= 1 << 0,
	ISERT_DATA_KEY_VALID	= 1 << 1,
	ISERT_PROT_KEY_VALID	= 1 << 2,
	ISERT_SIG_KEY_VALID	= 1 << 3,
};

struct pi_context {
	struct ib_mr		       *prot_mr;
	struct ib_fast_reg_page_list   *prot_frpl;
	struct ib_mr		       *sig_mr;
};

struct fast_reg_descriptor {
	struct list_head		list;
	struct ib_mr		       *data_mr;
	struct ib_fast_reg_page_list   *data_frpl;
	bool			valid;
	u8				ind;
	struct pi_context	       *pi_ctx;
};

struct isert_data_buf {
	struct scatterlist     *sg;
	int			nents;
	u32			sg_off;
	u32			len; /* cur_rdma_length */
	u32			offset;
	unsigned int		dma_nents;
	enum dma_data_direction dma_dir;
};

struct isert_rdma_wr {
@@ -63,12 +87,11 @@ struct isert_rdma_wr {
	enum iser_ib_op_code	iser_ib_op;
	struct ib_sge		*ib_sge;
	struct ib_sge		s_ib_sge;
	int			num_sge;
	struct scatterlist	*sge;
	int			send_wr_num;
	struct ib_send_wr	*send_wr;
	struct ib_send_wr	s_send_wr;
	u32			cur_rdma_length;
	struct isert_data_buf	data;
	struct isert_data_buf	prot;
	struct fast_reg_descriptor *fr_desc;
};

@@ -141,6 +164,7 @@ struct isert_cq_desc {

struct isert_device {
	int			use_fastreg;
	bool			pi_capable;
	int			cqs_used;
	int			refcount;
	int			cq_active_qps[ISERT_MAX_CQ];
+20 −7
Original line number Diff line number Diff line
@@ -1078,6 +1078,7 @@ static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch,
static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
				 struct srpt_send_ioctx *ioctx)
{
	struct ib_device *dev = ch->sport->sdev->device;
	struct se_cmd *cmd;
	struct scatterlist *sg, *sg_orig;
	int sg_cnt;
@@ -1124,7 +1125,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,

	db = ioctx->rbufs;
	tsize = cmd->data_length;
	dma_len = sg_dma_len(&sg[0]);
	dma_len = ib_sg_dma_len(dev, &sg[0]);
	riu = ioctx->rdma_ius;

	/*
@@ -1155,7 +1156,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
					++j;
					if (j < count) {
						sg = sg_next(sg);
						dma_len = sg_dma_len(sg);
						dma_len = ib_sg_dma_len(
								dev, sg);
					}
				}
			} else {
@@ -1192,8 +1194,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
	tsize = cmd->data_length;
	riu = ioctx->rdma_ius;
	sg = sg_orig;
	dma_len = sg_dma_len(&sg[0]);
	dma_addr = sg_dma_address(&sg[0]);
	dma_len = ib_sg_dma_len(dev, &sg[0]);
	dma_addr = ib_sg_dma_address(dev, &sg[0]);

	/* this second loop is really mapped sg_addres to rdma_iu->ib_sge */
	for (i = 0, j = 0;
@@ -1216,8 +1218,10 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
					++j;
					if (j < count) {
						sg = sg_next(sg);
						dma_len = sg_dma_len(sg);
						dma_addr = sg_dma_address(sg);
						dma_len = ib_sg_dma_len(
								dev, sg);
						dma_addr = ib_sg_dma_address(
								dev, sg);
					}
				}
			} else {
@@ -2580,7 +2584,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
		goto destroy_ib;
	}

	ch->sess = transport_init_session();
	ch->sess = transport_init_session(TARGET_PROT_NORMAL);
	if (IS_ERR(ch->sess)) {
		rej->reason = __constant_cpu_to_be32(
				SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
@@ -3081,6 +3085,14 @@ static void srpt_queue_tm_rsp(struct se_cmd *cmd)
	srpt_queue_response(cmd);
}

static void srpt_aborted_task(struct se_cmd *cmd)
{
	struct srpt_send_ioctx *ioctx = container_of(cmd,
				struct srpt_send_ioctx, cmd);

	srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
}

static int srpt_queue_status(struct se_cmd *cmd)
{
	struct srpt_send_ioctx *ioctx;
@@ -3928,6 +3940,7 @@ static struct target_core_fabric_ops srpt_template = {
	.queue_data_in			= srpt_queue_data_in,
	.queue_status			= srpt_queue_status,
	.queue_tm_rsp			= srpt_queue_tm_rsp,
	.aborted_task			= srpt_aborted_task,
	/*
	 * Setup function pointers for generic logic in
	 * target_core_fabric_configfs.c
+17 −1
Original line number Diff line number Diff line
@@ -684,6 +684,20 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
	qlt_xmit_tm_rsp(mcmd);
}

static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
	struct qla_tgt_cmd *cmd = container_of(se_cmd,
				struct qla_tgt_cmd, se_cmd);
	struct scsi_qla_host *vha = cmd->vha;
	struct qla_hw_data *ha = vha->hw;

	if (!cmd->sg_mapped)
		return;

	pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
	cmd->sg_mapped = 0;
}

/* Local pointer to allocated TCM configfs fabric module */
struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
@@ -1468,7 +1482,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
	}
	se_tpg = &tpg->se_tpg;

	se_sess = transport_init_session();
	se_sess = transport_init_session(TARGET_PROT_NORMAL);
	if (IS_ERR(se_sess)) {
		pr_err("Unable to initialize struct se_session\n");
		return PTR_ERR(se_sess);
@@ -1877,6 +1891,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
	.queue_data_in			= tcm_qla2xxx_queue_data_in,
	.queue_status			= tcm_qla2xxx_queue_status,
	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
	.aborted_task			= tcm_qla2xxx_aborted_task,
	/*
	 * Setup function pointers for generic logic in
	 * target_core_fabric_configfs.c
@@ -1926,6 +1941,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
	.queue_data_in			= tcm_qla2xxx_queue_data_in,
	.queue_status			= tcm_qla2xxx_queue_status,
	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
	.aborted_task			= tcm_qla2xxx_aborted_task,
	/*
	 * Setup function pointers for generic logic in
	 * target_core_fabric_configfs.c
+32 −1
Original line number Diff line number Diff line
@@ -499,6 +499,23 @@ static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
	return 0;
}

static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
	bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);

	spin_lock_bh(&conn->cmd_lock);
	if (!list_empty(&cmd->i_conn_node))
		list_del_init(&cmd->i_conn_node);
	spin_unlock_bh(&conn->cmd_lock);

	__iscsit_free_cmd(cmd, scsi_cmd, true);
}

static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn)
{
	return TARGET_PROT_NORMAL;
}

static struct iscsit_transport iscsi_target_transport = {
	.name			= "iSCSI/TCP",
	.transport_type		= ISCSI_TCP,
@@ -513,6 +530,8 @@ static struct iscsit_transport iscsi_target_transport = {
	.iscsit_response_queue	= iscsit_response_queue,
	.iscsit_queue_data_in	= iscsit_queue_rsp,
	.iscsit_queue_status	= iscsit_queue_rsp,
	.iscsit_aborted_task	= iscsit_aborted_task,
	.iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops,
};

static int __init iscsi_target_init_module(void)
@@ -1503,6 +1522,16 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
{
	u32 payload_length = ntoh24(hdr->dlength);

	if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
		pr_err("NopOUT Flag's, Left Most Bit not set, protocol error.\n");
		if (!cmd)
			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
						 (unsigned char *)hdr);
		
		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
					 (unsigned char *)hdr);
	}

	if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
		pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
			" not set, protocol error.\n");
@@ -2468,6 +2497,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
{
	struct iscsi_cmd *cmd;
	struct iscsi_conn *conn_p;
	bool found = false;

	/*
	 * Only send a Asynchronous Message on connections whos network
@@ -2476,11 +2506,12 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
	list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) {
		if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) {
			iscsit_inc_conn_usage_count(conn_p);
			found = true;
			break;
		}
	}

	if (!conn_p)
	if (!found)
		return;

	cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING);
Loading