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

Commit e20d3ef5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "The highlights this round include:

   - Update vhost-scsi to support F_ANY_LAYOUT using mm/iov_iter.c
     logic, and signal VERSION_1 support (MST + Viro + nab)

   - Fix iscsi/iser-target to remove problematic active_ts_set usage
     (Gavin Guo)

   - Update iscsi/iser-target to support multi-sequence sendtargets
     (Sagi)

   - Fix original PR_APTPL_BUF_LEN 8k size limitation (Martin Svec)

   - Add missing WRITE_SAME end-of-device sanity check (Bart)

   - Check for LBA + sectors wrap-around in sbc_parse_cdb() (nab)

   - Other various minor SPC/SBC compliance fixes based upon Ronnie
     Sahlberg test suite (nab)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (32 commits)
  target: Set LBPWS10 bit in Logical Block Provisioning EVPD
  target: Fail UNMAP when emulate_tpu=0
  target: Fail WRITE_SAME w/ UNMAP=1 when emulate_tpws=0
  target: Add sanity checks for DPO/FUA bit usage
  target: Perform PROTECT sanity checks for WRITE_SAME
  target: Fail I/O with PROTECT bit when protection is unsupported
  target: Check for LBA + sectors wrap-around in sbc_parse_cdb
  target: Add missing WRITE_SAME end-of-device sanity check
  iscsi-target: Avoid IN_LOGOUT failure case for iser-target
  target: Fix PR_APTPL_BUF_LEN buffer size limitation
  iscsi-target: Drop problematic active_ts_list usage
  iscsi/iser-target: Support multi-sequence sendtargets text response
  iser-target: Remove duplicate function names
  vhost/scsi: potential memory corruption
  vhost/scsi: Global tcm_vhost -> vhost_scsi rename
  vhost/scsi: Drop left-over scsi_tcq.h include
  vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits
  vhost/scsi: Add ANY_LAYOUT support in vhost_scsi_handle_vq
  vhost/scsi: Add ANY_LAYOUT iov -> sgl mapping prerequisites
  vhost/scsi: Change vhost_scsi_map_to_sgl to accept iov ptr + len
  ...
parents 1acd2de5 aa04dae4
Loading
Loading
Loading
Loading
+30 −16
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
#define ISER_MAX_CQ_LEN		(ISER_MAX_RX_CQ_LEN + ISER_MAX_TX_CQ_LEN + \
				 ISERT_MAX_CONN)

int isert_debug_level = 0;
static int isert_debug_level;
module_param_named(debug_level, isert_debug_level, int, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)");

@@ -949,7 +949,7 @@ isert_post_recv(struct isert_conn *isert_conn, u32 count)
		isert_err("ib_post_recv() failed with ret: %d\n", ret);
		isert_conn->post_recv_buf_count -= count;
	} else {
		isert_dbg("isert_post_recv(): Posted %d RX buffers\n", count);
		isert_dbg("Posted %d RX buffers\n", count);
		isert_conn->conn_rx_desc_head = rx_head;
	}
	return ret;
@@ -1351,18 +1351,20 @@ isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd
	struct iscsi_conn *conn = isert_conn->conn;
	u32 payload_length = ntoh24(hdr->dlength);
	int rc;
	unsigned char *text_in;
	unsigned char *text_in = NULL;

	rc = iscsit_setup_text_cmd(conn, cmd, hdr);
	if (rc < 0)
		return rc;

	if (payload_length) {
		text_in = kzalloc(payload_length, GFP_KERNEL);
		if (!text_in) {
			isert_err("Unable to allocate text_in of payload_length: %u\n",
				  payload_length);
			return -ENOMEM;
		}
	}
	cmd->text_in_ptr = text_in;

	memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length);
@@ -1434,9 +1436,15 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
		ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr);
		break;
	case ISCSI_OP_TEXT:
		if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) {
			cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
			if (!cmd)
				break;
		} else {
			cmd = isert_allocate_cmd(conn);
			if (!cmd)
				break;
		}

		isert_cmd = iscsit_priv_cmd(cmd);
		ret = isert_handle_text_cmd(isert_conn, isert_cmd, cmd,
@@ -1658,6 +1666,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
	struct isert_conn *isert_conn = isert_cmd->conn;
	struct iscsi_conn *conn = isert_conn->conn;
	struct isert_device *device = isert_conn->conn_device;
	struct iscsi_text_rsp *hdr;

	isert_dbg("Cmd %p\n", isert_cmd);

@@ -1698,6 +1707,11 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
	case ISCSI_OP_REJECT:
	case ISCSI_OP_NOOP_OUT:
	case ISCSI_OP_TEXT:
		hdr = (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header;
		/* If the continue bit is on, keep the command alive */
		if (hdr->flags & ISCSI_FLAG_TEXT_CONTINUE)
			break;

		spin_lock_bh(&conn->cmd_lock);
		if (!list_empty(&cmd->i_conn_node))
			list_del_init(&cmd->i_conn_node);
@@ -1709,8 +1723,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
		 * associated cmd->se_cmd needs to be released.
		 */
		if (cmd->se_cmd.se_tfo != NULL) {
			isert_dbg("Calling transport_generic_free_cmd from"
				 " isert_put_cmd for 0x%02x\n",
			isert_dbg("Calling transport_generic_free_cmd for 0x%02x\n",
				 cmd->iscsi_opcode);
			transport_generic_free_cmd(&cmd->se_cmd, 0);
			break;
@@ -2275,7 +2288,7 @@ isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
	}
	isert_init_send_wr(isert_conn, isert_cmd, send_wr);

	isert_dbg("conn %p Text Reject\n", isert_conn);
	isert_dbg("conn %p Text Response\n", isert_conn);

	return isert_post_response(isert_conn, isert_cmd);
}
@@ -3136,7 +3149,7 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
	spin_lock_bh(&np->np_thread_lock);
	if (np->np_thread_state >= ISCSI_NP_THREAD_RESET) {
		spin_unlock_bh(&np->np_thread_lock);
		isert_dbg("np_thread_state %d for isert_accept_np\n",
		isert_dbg("np_thread_state %d\n",
			 np->np_thread_state);
		/**
		 * No point in stalling here when np_thread
@@ -3320,7 +3333,8 @@ static int __init isert_init(void)
{
	int ret;

	isert_comp_wq = alloc_workqueue("isert_comp_wq", 0, 0);
	isert_comp_wq = alloc_workqueue("isert_comp_wq",
					WQ_UNBOUND | WQ_HIGHPRI, 0);
	if (!isert_comp_wq) {
		isert_err("Unable to allocate isert_comp_wq\n");
		ret = -ENOMEM;
+2 −2
Original line number Diff line number Diff line
@@ -3518,7 +3518,7 @@ static void srpt_close_session(struct se_session *se_sess)
	DECLARE_COMPLETION_ONSTACK(release_done);
	struct srpt_rdma_ch *ch;
	struct srpt_device *sdev;
	int res;
	unsigned long res;

	ch = se_sess->fabric_sess_ptr;
	WARN_ON(ch->sess != se_sess);
@@ -3533,7 +3533,7 @@ static void srpt_close_session(struct se_session *se_sess)
	spin_unlock_irq(&sdev->spinlock);

	res = wait_for_completion_timeout(&release_done, 60 * HZ);
	WARN_ON(res <= 0);
	WARN_ON(res == 0);
}

/**
+1 −3
Original line number Diff line number Diff line
@@ -1570,9 +1570,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
	 * match the format by tcm_qla2xxx explict ConfigFS NodeACLs.
	 */
	memset(&port_name, 0, 36);
	snprintf(port_name, 36, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
		fc_wwpn[0], fc_wwpn[1], fc_wwpn[2], fc_wwpn[3], fc_wwpn[4],
		fc_wwpn[5], fc_wwpn[6], fc_wwpn[7]);
	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
	/*
	 * Locate our struct se_node_acl either from an explict NodeACL created
	 * via ConfigFS, or via running in TPG demo mode.
+70 −35
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@
#include <target/target_core_fabric.h>
#include <target/target_core_configfs.h>

#include "iscsi_target_core.h"
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_parameters.h"
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_tq.h"
@@ -45,7 +45,7 @@
#include "iscsi_target_util.h"
#include "iscsi_target.h"
#include "iscsi_target_device.h"
#include "iscsi_target_stat.h"
#include <target/iscsi/iscsi_target_stat.h>

#include <target/iscsi/iscsi_transport.h>

@@ -968,11 +968,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,

	conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
		spin_lock_bh(&conn->sess->ttt_lock);
		cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++;
		if (cmd->targ_xfer_tag == 0xFFFFFFFF)
			cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++;
		spin_unlock_bh(&conn->sess->ttt_lock);
		cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
	} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
		cmd->targ_xfer_tag = 0xFFFFFFFF;
	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
@@ -1998,6 +1994,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
	cmd->data_direction	= DMA_NONE;
	cmd->text_in_ptr	= NULL;

	return 0;
}
@@ -2011,10 +2008,14 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
	int cmdsn_ret;

	if (!text_in) {
		cmd->targ_xfer_tag = be32_to_cpu(hdr->ttt);
		if (cmd->targ_xfer_tag == 0xFFFFFFFF) {
			pr_err("Unable to locate text_in buffer for sendtargets"
			       " discovery\n");
			goto reject;
		}
		goto empty_sendtargets;
	}
	if (strncmp("SendTargets", text_in, 11) != 0) {
		pr_err("Received Text Data that is not"
			" SendTargets, cannot continue.\n");
@@ -2040,6 +2041,7 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
	spin_unlock_bh(&conn->cmd_lock);

empty_sendtargets:
	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
@@ -3047,11 +3049,7 @@ static int iscsit_send_r2t(
	int_to_scsilun(cmd->se_cmd.orig_fe_lun,
			(struct scsi_lun *)&hdr->lun);
	hdr->itt		= cmd->init_task_tag;
	spin_lock_bh(&conn->sess->ttt_lock);
	r2t->targ_xfer_tag	= conn->sess->targ_xfer_tag++;
	if (r2t->targ_xfer_tag == 0xFFFFFFFF)
		r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++;
	spin_unlock_bh(&conn->sess->ttt_lock);
	r2t->targ_xfer_tag	= session_get_next_ttt(conn->sess);
	hdr->ttt		= cpu_to_be32(r2t->targ_xfer_tag);
	hdr->statsn		= cpu_to_be32(conn->stat_sn);
	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
@@ -3393,7 +3391,8 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np)

static int
iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
				  enum iscsit_transport_type network_transport)
				  enum iscsit_transport_type network_transport,
				  int skip_bytes, bool *completed)
{
	char *payload = NULL;
	struct iscsi_conn *conn = cmd->conn;
@@ -3405,7 +3404,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
	unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
	unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;

	buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength,
	buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength,
			 SENDTARGETS_BUF_LIMIT);

	payload = kzalloc(buffer_len, GFP_KERNEL);
@@ -3484,9 +3483,16 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
						end_of_buf = 1;
						goto eob;
					}

					if (skip_bytes && len <= skip_bytes) {
						skip_bytes -= len;
					} else {
						memcpy(payload + payload_len, buf, len);
						payload_len += len;
						target_name_printed = 1;
						if (len > skip_bytes)
							skip_bytes = 0;
					}
				}

				len = sprintf(buf, "TargetAddress="
@@ -3502,15 +3508,24 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
					end_of_buf = 1;
					goto eob;
				}

				if (skip_bytes && len <= skip_bytes) {
					skip_bytes -= len;
				} else {
					memcpy(payload + payload_len, buf, len);
					payload_len += len;
					if (len > skip_bytes)
						skip_bytes = 0;
				}
			}
			spin_unlock(&tpg->tpg_np_lock);
		}
		spin_unlock(&tiqn->tiqn_tpg_lock);
eob:
		if (end_of_buf)
		if (end_of_buf) {
			*completed = false;
			break;
		}

		if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE)
			break;
@@ -3528,13 +3543,23 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
		      enum iscsit_transport_type network_transport)
{
	int text_length, padding;
	bool completed = true;

	text_length = iscsit_build_sendtargets_response(cmd, network_transport);
	text_length = iscsit_build_sendtargets_response(cmd, network_transport,
							cmd->read_data_done,
							&completed);
	if (text_length < 0)
		return text_length;

	hdr->opcode = ISCSI_OP_TEXT_RSP;
	if (completed) {
		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
	} else {
		hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
		cmd->read_data_done += text_length;
		if (cmd->targ_xfer_tag == 0xFFFFFFFF)
			cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
	}
	hdr->opcode = ISCSI_OP_TEXT_RSP;
	padding = ((-text_length) & 3);
	hton24(hdr->dlength, text_length);
	hdr->itt = cmd->init_task_tag;
@@ -3543,21 +3568,25 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
	hdr->statsn = cpu_to_be32(cmd->stat_sn);

	iscsit_increment_maxcmdsn(cmd, conn->sess);
	/*
	 * Reset maxcmdsn_inc in multi-part text payload exchanges to
	 * correctly increment MaxCmdSN for each response answering a
	 * non immediate text request with a valid CmdSN.
	 */
	cmd->maxcmdsn_inc = 0;
	hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
	hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);

	pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
		" Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
		text_length, conn->cid);
	pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x,"
		" Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag,
		cmd->targ_xfer_tag, cmd->stat_sn, text_length, conn->cid,
		!!(hdr->flags & ISCSI_FLAG_CMD_FINAL),
		!!(hdr->flags & ISCSI_FLAG_TEXT_CONTINUE));

	return text_length + padding;
}
EXPORT_SYMBOL(iscsit_build_text_rsp);

/*
 *	FIXME: Add support for F_BIT and C_BIT when the length is longer than
 *	MaxRecvDataSegmentLength.
 */
static int iscsit_send_text_rsp(
	struct iscsi_cmd *cmd,
	struct iscsi_conn *conn)
@@ -4021,9 +4050,15 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
		ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
		break;
	case ISCSI_OP_TEXT:
		if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
			cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
			if (!cmd)
				goto reject;
		} else {
			cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
			if (!cmd)
				goto reject;
		}

		ret = iscsit_handle_text_cmd(conn, cmd, buf);
		break;
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
#include <linux/err.h>
#include <linux/scatterlist.h>

#include "iscsi_target_core.h"
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_nego.h"
#include "iscsi_target_auth.h"

Loading