static ssize_t scsiback_tpg_nexus_store()

in xen-scsiback.c [1580:1653]


static ssize_t scsiback_tpg_nexus_store(struct config_item *item,
		const char *page, size_t count)
{
	struct se_portal_group *se_tpg = to_tpg(item);
	struct scsiback_tpg *tpg = container_of(se_tpg,
				struct scsiback_tpg, se_tpg);
	struct scsiback_tport *tport_wwn = tpg->tport;
	unsigned char i_port[VSCSI_NAMELEN], *ptr, *port_ptr;
	int ret;
	/*
	 * Shutdown the active I_T nexus if 'NULL' is passed.
	 */
	if (!strncmp(page, "NULL", 4)) {
		ret = scsiback_drop_nexus(tpg);
		return (!ret) ? count : ret;
	}
	/*
	 * Otherwise make sure the passed virtual Initiator port WWN matches
	 * the fabric protocol_id set in scsiback_make_tport(), and call
	 * scsiback_make_nexus().
	 */
	if (strlen(page) >= VSCSI_NAMELEN) {
		pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",
			page, VSCSI_NAMELEN);
		return -EINVAL;
	}
	snprintf(&i_port[0], VSCSI_NAMELEN, "%s", page);

	ptr = strstr(i_port, "naa.");
	if (ptr) {
		if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {
			pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",
				i_port, scsiback_dump_proto_id(tport_wwn));
			return -EINVAL;
		}
		port_ptr = &i_port[0];
		goto check_newline;
	}
	ptr = strstr(i_port, "fc.");
	if (ptr) {
		if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {
			pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",
				i_port, scsiback_dump_proto_id(tport_wwn));
			return -EINVAL;
		}
		port_ptr = &i_port[3]; /* Skip over "fc." */
		goto check_newline;
	}
	ptr = strstr(i_port, "iqn.");
	if (ptr) {
		if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {
			pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",
				i_port, scsiback_dump_proto_id(tport_wwn));
			return -EINVAL;
		}
		port_ptr = &i_port[0];
		goto check_newline;
	}
	pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",
		i_port);
	return -EINVAL;
	/*
	 * Clear any trailing newline for the NAA WWN
	 */
check_newline:
	if (i_port[strlen(i_port) - 1] == '\n')
		i_port[strlen(i_port) - 1] = '\0';

	ret = scsiback_make_nexus(tpg, port_ptr);
	if (ret < 0)
		return ret;

	return count;
}