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

Commit 19e75ed4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
This series contains pending target bug-fixes and cleanups for v3.3-rc3
that have been addressed the past weeks in lio-core.git.

Some of the highlights include:

 - Fix handling for control CDBs with data greater than PAGE_SIZE (andy)
 - Use IP_FREEBIND for iscsi-target to address network portal creation
   issues with systemd (dax)
 - Allow PERSISTENT RESERVE IN for non-reservation holder (marco)
 - Fix iblock se_dev_attrib.unmap_granularity (marco)
 - Fix unsupported WRITE_SAME sense payload handling (martin)
 - Add workaround for zero-length control CDB handling (nab)
 - Fix discovery with INADDR_ANY and IN6ADDR_ANY_INIT (nab)
 - Fix target_submit_cmd() exception handling (nab)
 - Return correct ASC for unimplemented VPD pages (roland)
 - Don't zero pages used for data buffers (roland)
 - Fix return code of core_tpg_.*_lun (sebastian)

* '3.3-rc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (26 commits)
  target: Fix unsupported WRITE_SAME sense payload
  iscsi: use IP_FREEBIND socket option
  iblock: fix handling of large requests
  target: handle empty string writes in sysfs
  iscsi_target: in_aton needs linux/inet.h
  target: Fix iblock se_dev_attrib.unmap_granularity
  target: Fix target_submit_cmd() exception handling
  target: Change target_submit_cmd() to return void
  target: accept REQUEST_SENSE with 18bytes
  target: Fail INQUIRY commands with EVPD==0 but PAGE CODE!=0
  target: Return correct ASC for unimplemented VPD pages
  iscsi-target: Fix discovery with INADDR_ANY and IN6ADDR_ANY_INIT
  target: Allow control CDBs with data > 1 page
  iscsi-target: Fix up a few assignments
  iscsi-target: make one-bit bitfields unsigned
  iscsi-target: Fix double list_add with iscsit_alloc_buffs reject
  iscsi-target: Fix reject release handling in iscsit_free_cmd()
  target: fix return code of core_tpg_.*_lun
  target: use save/restore lock primitive in core_dec_lacl_count()
  target: avoid multiple outputs in scsi_dump_inquiry()
  ...
parents 4d39aa1b 67236c44
Loading
Loading
Loading
Loading
+34 −5
Original line number Diff line number Diff line
@@ -1061,7 +1061,7 @@ static int iscsit_handle_scsi_cmd(
	if (ret < 0)
		return iscsit_add_reject_from_cmd(
				ISCSI_REASON_BOOKMARK_NO_RESOURCES,
				1, 1, buf, cmd);
				1, 0, buf, cmd);
	/*
	 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
	 * the Immediate Bit is not set, and no Immediate
@@ -3164,6 +3164,30 @@ static int iscsit_send_task_mgt_rsp(
	return 0;
}

static bool iscsit_check_inaddr_any(struct iscsi_np *np)
{
	bool ret = false;

	if (np->np_sockaddr.ss_family == AF_INET6) {
		const struct sockaddr_in6 sin6 = {
			.sin6_addr = IN6ADDR_ANY_INIT };
		struct sockaddr_in6 *sock_in6 =
			 (struct sockaddr_in6 *)&np->np_sockaddr;

		if (!memcmp(sock_in6->sin6_addr.s6_addr,
				sin6.sin6_addr.s6_addr, 16))
			ret = true;
	} else {
		struct sockaddr_in * sock_in =
			(struct sockaddr_in *)&np->np_sockaddr;

		if (sock_in->sin_addr.s_addr == INADDR_ANY)
			ret = true;
	}

	return ret;
}

static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
{
	char *payload = NULL;
@@ -3213,12 +3237,17 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
			spin_lock(&tpg->tpg_np_lock);
			list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
						tpg_np_list) {
				struct iscsi_np *np = tpg_np->tpg_np;
				bool inaddr_any = iscsit_check_inaddr_any(np);

				len = sprintf(buf, "TargetAddress="
					"%s%s%s:%hu,%hu",
					(tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
					"[" : "", tpg_np->tpg_np->np_ip,
					(tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
					"]" : "", tpg_np->tpg_np->np_port,
					(np->np_sockaddr.ss_family == AF_INET6) ?
					"[" : "", (inaddr_any == false) ?
						np->np_ip : conn->local_ip,
					(np->np_sockaddr.ss_family == AF_INET6) ?
					"]" : "", (inaddr_any == false) ?
						np->np_port : conn->local_port,
					tpg->tpgt);
				len += 1;

+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <linux/configfs.h>
#include <linux/export.h>
#include <linux/inet.h>
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>
#include <target/target_core_fabric_configfs.h>
+4 −2
Original line number Diff line number Diff line
@@ -508,6 +508,7 @@ struct iscsi_conn {
	u16			cid;
	/* Remote TCP Port */
	u16			login_port;
	u16			local_port;
	int			net_size;
	u32			auth_id;
#define CONNFLAG_SCTP_STRUCT_FILE			0x01
@@ -527,6 +528,7 @@ struct iscsi_conn {
	unsigned char		bad_hdr[ISCSI_HDR_LEN];
#define IPV6_ADDRESS_SPACE				48
	unsigned char		login_ip[IPV6_ADDRESS_SPACE];
	unsigned char		local_ip[IPV6_ADDRESS_SPACE];
	int			conn_usage_count;
	int			conn_waiting_on_uc;
	atomic_t		check_immediate_queue;
@@ -561,8 +563,8 @@ struct iscsi_conn {
	struct hash_desc	conn_tx_hash;
	/* Used for scheduling TX and RX connection kthreads */
	cpumask_var_t		conn_cpumask;
	int			conn_rx_reset_cpumask:1;
	int			conn_tx_reset_cpumask:1;
	unsigned int		conn_rx_reset_cpumask:1;
	unsigned int		conn_tx_reset_cpumask:1;
	/* list_head of struct iscsi_cmd for this connection */
	struct list_head	conn_cmd_list;
	struct list_head	immed_queue_list;
+2 −2
Original line number Diff line number Diff line
@@ -1238,7 +1238,7 @@ void iscsit_mod_dataout_timer(struct iscsi_cmd *cmd)
{
	struct iscsi_conn *conn = cmd->conn;
	struct iscsi_session *sess = conn->sess;
	struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
	struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);

	spin_lock_bh(&cmd->dataout_timeout_lock);
	if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) {
@@ -1261,7 +1261,7 @@ void iscsit_start_dataout_timer(
	struct iscsi_conn *conn)
{
	struct iscsi_session *sess = conn->sess;
	struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
	struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);

	if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING)
		return;
+35 −4
Original line number Diff line number Diff line
@@ -615,8 +615,8 @@ static int iscsi_post_login_handler(
		}

		pr_debug("iSCSI Login successful on CID: %hu from %s to"
			" %s:%hu,%hu\n", conn->cid, conn->login_ip, np->np_ip,
				np->np_port, tpg->tpgt);
			" %s:%hu,%hu\n", conn->cid, conn->login_ip,
			conn->local_ip, conn->local_port, tpg->tpgt);

		list_add_tail(&conn->conn_list, &sess->sess_conn_list);
		atomic_inc(&sess->nconn);
@@ -658,7 +658,8 @@ static int iscsi_post_login_handler(
	sess->session_state = TARG_SESS_STATE_LOGGED_IN;

	pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
		conn->cid, conn->login_ip, np->np_ip, np->np_port, tpg->tpgt);
		conn->cid, conn->login_ip, conn->local_ip, conn->local_port,
		tpg->tpgt);

	spin_lock_bh(&sess->conn_lock);
	list_add_tail(&conn->conn_list, &sess->sess_conn_list);
@@ -841,6 +842,14 @@ int iscsi_target_setup_login_socket(
		goto fail;
	}

	ret = kernel_setsockopt(sock, IPPROTO_IP, IP_FREEBIND,
			(char *)&opt, sizeof(opt));
	if (ret < 0) {
		pr_err("kernel_setsockopt() for IP_FREEBIND"
			" failed\n");
		goto fail;
	}

	ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len);
	if (ret < 0) {
		pr_err("kernel_bind() failed: %d\n", ret);
@@ -1020,6 +1029,18 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
		snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
				&sock_in6.sin6_addr.in6_u);
		conn->login_port = ntohs(sock_in6.sin6_port);

		if (conn->sock->ops->getname(conn->sock,
				(struct sockaddr *)&sock_in6, &err, 0) < 0) {
			pr_err("sock_ops->getname() failed.\n");
			iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
					ISCSI_LOGIN_STATUS_TARGET_ERROR);
			goto new_sess_out;
		}
		snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
				&sock_in6.sin6_addr.in6_u);
		conn->local_port = ntohs(sock_in6.sin6_port);

	} else {
		memset(&sock_in, 0, sizeof(struct sockaddr_in));

@@ -1032,6 +1053,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
		}
		sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr);
		conn->login_port = ntohs(sock_in.sin_port);

		if (conn->sock->ops->getname(conn->sock,
				(struct sockaddr *)&sock_in, &err, 0) < 0) {
			pr_err("sock_ops->getname() failed.\n");
			iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
					ISCSI_LOGIN_STATUS_TARGET_ERROR);
			goto new_sess_out;
		}
		sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr);
		conn->local_port = ntohs(sock_in.sin_port);
	}

	conn->network_transport = np->np_network_transport;
@@ -1039,7 +1070,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
	pr_debug("Received iSCSI login request from %s on %s Network"
			" Portal %s:%hu\n", conn->login_ip,
		(conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP",
			np->np_ip, np->np_port);
			conn->local_ip, conn->local_port);

	pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
	conn->conn_state	= TARG_CONN_STATE_IN_LOGIN;
Loading