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

Commit ecc88efb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull scsi target updates from Nicholas Bellinger:
 "The highlights in this series include:

   - Improve sg_table lookup scalability in RAMDISK_MCP (martin)

   - Add device attribute to expose config name for INQUIRY model (tregaron)

   - Convert tcm_vhost to use lock-less list for cmd completion (asias)

   - Add tcm_vhost support for multiple target's per endpoint (asias)

   - Add tcm_vhost support for multiple queues per vhost (asias)

   - Add missing mapped_lun bounds checking during make_mappedlun setup
     in generic fabric configfs code (jan engelhardt + nab)

   - Enforce individual iscsi-target network portal export once per
     TargetName endpoint (grover + nab)

   - Add WRITE_SAME w/ UNMAP=0 emulation to FILEIO backend (nab)

  Things have been mostly quiet this round, with majority of the work
  being done on the iser-target WIP driver + associated iscsi-target
  refactoring patches currently in flight for v3.10 code.

  At this point there is one patch series left outstanding from Asias to
  add support for UNMAP + WRITE_SAME w/ UNMAP=1 to FILEIO awaiting
  feedback from hch & Co, that will likely be included in a post
  v3.9-rc1 PULL request if there are no objections.

  Also, there is a regression bug recently reported off-list that seems
  to be effecting v3.5 and v3.6 kernels with MSFT iSCSI initiators that
  is still being tracked down.  No word if this effects >= v3.7 just
  yet, but if so there will likely another PULL request coming your
  way.."

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (26 commits)
  target: Rename spc_get_write_same_sectors -> sbc_get_write_same_sectors
  target/file: Add WRITE_SAME w/ UNMAP=0 emulation support
  iscsi-target: Enforce individual network portal export once per TargetName
  iscsi-target: Refactor iscsit_get_np sockaddr matching into iscsit_check_np_match
  target: Add missing mapped_lun bounds checking during make_mappedlun setup
  target: Fix lookup of dynamic NodeACLs during cached demo-mode operation
  target: Fix parameter list length checking in MODE SELECT
  target: Fix error checking for UNMAP commands
  target: Fix sense data for out-of-bounds IO operations
  target_core_rd: break out unterminated loop during copy
  tcm_vhost: Multi-queue support
  tcm_vhost: Multi-target support
  target: Add device attribute to expose config_item_name for INQUIRY model
  target: don't truncate the fail intr address
  target: don't always say "ipv6" as address type
  target/iblock: Use backend REQ_FLUSH hint for WriteCacheEnabled status
  iscsi-target: make some temporary buffers larger
  tcm_vhost: Optimize gup in vhost_scsi_map_to_sgl
  tcm_vhost: Use iov_num_pages to calculate sgl_count
  tcm_vhost: Introduce iov_num_pages
  ...
parents 70a3a06d 972b29c8
Loading
Loading
Loading
Loading
+39 −26
Original line number Diff line number Diff line
@@ -264,24 +264,16 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
	return 0;
}

static struct iscsi_np *iscsit_get_np(
bool iscsit_check_np_match(
	struct __kernel_sockaddr_storage *sockaddr,
	struct iscsi_np *np,
	int network_transport)
{
	struct sockaddr_in *sock_in, *sock_in_e;
	struct sockaddr_in6 *sock_in6, *sock_in6_e;
	struct iscsi_np *np;
	int ip_match = 0;
	bool ip_match = false;
	u16 port;

	spin_lock_bh(&np_lock);
	list_for_each_entry(np, &g_np_list, np_list) {
		spin_lock(&np->np_thread_lock);
		if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
			spin_unlock(&np->np_thread_lock);
			continue;
		}

	if (sockaddr->ss_family == AF_INET6) {
		sock_in6 = (struct sockaddr_in6 *)sockaddr;
		sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
@@ -289,22 +281,43 @@ static struct iscsi_np *iscsit_get_np(
		if (!memcmp(&sock_in6->sin6_addr.in6_u,
			    &sock_in6_e->sin6_addr.in6_u,
			    sizeof(struct in6_addr)))
				ip_match = 1;
			ip_match = true;

		port = ntohs(sock_in6->sin6_port);
	} else {
		sock_in = (struct sockaddr_in *)sockaddr;
		sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;

			if (sock_in->sin_addr.s_addr ==
			    sock_in_e->sin_addr.s_addr)
				ip_match = 1;
		if (sock_in->sin_addr.s_addr == sock_in_e->sin_addr.s_addr)
			ip_match = true;

		port = ntohs(sock_in->sin_port);
	}

		if ((ip_match == 1) && (np->np_port == port) &&
		    (np->np_network_transport == network_transport)) {
	if ((ip_match == true) && (np->np_port == port) &&
	    (np->np_network_transport == network_transport))
		return true;

	return false;
}

static struct iscsi_np *iscsit_get_np(
	struct __kernel_sockaddr_storage *sockaddr,
	int network_transport)
{
	struct iscsi_np *np;
	bool match;

	spin_lock_bh(&np_lock);
	list_for_each_entry(np, &g_np_list, np_list) {
		spin_lock(&np->np_thread_lock);
		if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
			spin_unlock(&np->np_thread_lock);
			continue;
		}

		match = iscsit_check_np_match(sockaddr, np, network_transport);
		if (match == true) {
			/*
			 * Increment the np_exports reference count now to
			 * prevent iscsit_del_np() below from being called
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ extern struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *);
extern void iscsit_del_tiqn(struct iscsi_tiqn *);
extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *);
extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *);
extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *,
				struct iscsi_np *, int);
extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
				char *, int);
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
+4 −4
Original line number Diff line number Diff line
@@ -1095,11 +1095,11 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
				SET_PSTATE_REPLY_OPTIONAL(param);
		}
	} else if (IS_TYPE_NUMBER(param)) {
		char *tmpptr, buf[10];
		char *tmpptr, buf[11];
		u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
		u32 proposer_value = simple_strtoul(value, &tmpptr, 0);

		memset(buf, 0, 10);
		memset(buf, 0, sizeof(buf));

		if (!strcmp(param->name, MAXCONNECTIONS) ||
		    !strcmp(param->name, MAXBURSTLENGTH) ||
@@ -1503,8 +1503,8 @@ static int iscsi_enforce_integrity_rules(
			FirstBurstLength = simple_strtoul(param->value,
					&tmpptr, 0);
			if (FirstBurstLength > MaxBurstLength) {
				char tmpbuf[10];
				memset(tmpbuf, 0, 10);
				char tmpbuf[11];
				memset(tmpbuf, 0, sizeof(tmpbuf));
				sprintf(tmpbuf, "%u", MaxBurstLength);
				if (iscsi_update_param_value(param, tmpbuf))
					return -1;
+15 −10
Original line number Diff line number Diff line
@@ -410,14 +410,16 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
	struct iscsi_tiqn *tiqn = container_of(igrps,
			struct iscsi_tiqn, tiqn_stat_grps);
	struct iscsi_login_stats *lstat = &tiqn->login_stats;
	unsigned char buf[8];
	int ret;

	spin_lock(&lstat->lock);
	snprintf(buf, 8, "%s", (lstat->last_intr_fail_ip_addr != NULL) ?
				"ipv6" : "ipv4");
	if (lstat->last_intr_fail_ip_family == AF_INET6)
		ret = snprintf(page, PAGE_SIZE, "ipv6\n");
	else
		ret = snprintf(page, PAGE_SIZE, "ipv4\n");
	spin_unlock(&lstat->lock);

	return snprintf(page, PAGE_SIZE, "%s\n", buf);
	return ret;
}
ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type);

@@ -427,16 +429,19 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
	struct iscsi_tiqn *tiqn = container_of(igrps,
			struct iscsi_tiqn, tiqn_stat_grps);
	struct iscsi_login_stats *lstat = &tiqn->login_stats;
	unsigned char buf[32];
	int ret;

	spin_lock(&lstat->lock);
	if (lstat->last_intr_fail_ip_family == AF_INET6)
		snprintf(buf, 32, "[%s]", lstat->last_intr_fail_ip_addr);
	else
		snprintf(buf, 32, "%s", lstat->last_intr_fail_ip_addr);
	if (lstat->last_intr_fail_ip_family == AF_INET6) {
		ret = snprintf(page, PAGE_SIZE, "[%s]\n",
			       lstat->last_intr_fail_ip_addr);
	} else {
		ret = snprintf(page, PAGE_SIZE, "%s\n",
			       lstat->last_intr_fail_ip_addr);
	}
	spin_unlock(&lstat->lock);

	return snprintf(page, PAGE_SIZE, "%s\n", buf);
	return ret;
}
ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr);

+39 −0
Original line number Diff line number Diff line
@@ -422,6 +422,35 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
	return NULL;
}

static bool iscsit_tpg_check_network_portal(
	struct iscsi_tiqn *tiqn,
	struct __kernel_sockaddr_storage *sockaddr,
	int network_transport)
{
	struct iscsi_portal_group *tpg;
	struct iscsi_tpg_np *tpg_np;
	struct iscsi_np *np;
	bool match = false;

	spin_lock(&tiqn->tiqn_tpg_lock);
	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {

		spin_lock(&tpg->tpg_np_lock);
		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
			np = tpg_np->tpg_np;

			match = iscsit_check_np_match(sockaddr, np,
						network_transport);
			if (match == true)
				break;
		}
		spin_unlock(&tpg->tpg_np_lock);
	}
	spin_unlock(&tiqn->tiqn_tpg_lock);

	return match;
}

struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
	struct iscsi_portal_group *tpg,
	struct __kernel_sockaddr_storage *sockaddr,
@@ -432,6 +461,16 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
	struct iscsi_np *np;
	struct iscsi_tpg_np *tpg_np;

	if (!tpg_np_parent) {
		if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
				network_transport) == true) {
			pr_err("Network Portal: %s already exists on a"
				" different TPG on %s\n", ip_str,
				tpg->tpg_tiqn->tiqn);
			return ERR_PTR(-EEXIST);
		}
	}

	tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
	if (!tpg_np) {
		pr_err("Unable to allocate memory for"
Loading