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

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

   - numerous target-core-user improvements related to queue full and
     timeout handling. (MNC)

   - prevent target-core-user corruption when invalid data page is
     requested. (MNC)

   - add target-core device action configfs attributes to allow
     user-space to trigger events separate from existing attributes
     exposed to end-users. (MNC)

   - fix iscsi-target NULL pointer dereference 4.6+ regression in CHAP
     error path. (David Disseldorp)

   - avoid target-core backend UNMAP callbacks if range is zero. (Andrei
     Vagin)

   - fix a iscsi-target 4.14+ regression related multiple PDU logins,
     that was exposed due to removal of TCP prequeue support. (Florian
     Westphal + MNC)

  Also, there is a iser-target bug still being worked on for post -rc1
  code to address a long standing issue resulting in persistent
  ib_post_send() failures, for RNICs with small max_send_sge"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (36 commits)
  iscsi-target: make sure to wake up sleeping login worker
  tcmu: Fix trailing semicolon
  tcmu: fix cmd user after free
  target: fix destroy device in target_configure_device
  tcmu: allow userspace to reset ring
  target core: add device action configfs files
  tcmu: fix error return code in tcmu_configure_device()
  target_core_user: add cmd id to broken ring message
  target: add SAM_STAT_BUSY sense reason
  tcmu: prevent corruption when invalid data page requested
  target: don't call an unmap callback if a range length is zero
  target/iscsi: avoid NULL dereference in CHAP auth error path
  cxgbit: call neigh_event_send() to update MAC address
  target: tcm_loop: Use seq_puts() in tcm_loop_show_info()
  target: tcm_loop: Delete an unnecessary return statement in tcm_loop_submission_work()
  target: tcm_loop: Delete two unnecessary variable initialisations in tcm_loop_issue_tmr()
  target: tcm_loop: Combine substrings for 26 messages
  target: tcm_loop: Improve a size determination in two functions
  target: tcm_loop: Delete an error message for a failed memory allocation in four functions
  sbp-target: Delete an error message for a failed memory allocation in three functions
  ...
parents 8158c2ff 1c130ae0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -893,6 +893,9 @@ cxgbit_offload_init(struct cxgbit_sock *csk, int iptype, __u8 *peer_ip,
		return -ENODEV;

	rcu_read_lock();
	if (!(n->nud_state & NUD_VALID))
		neigh_event_send(n, NULL);

	ret = -ENOMEM;
	if (n->dev->flags & IFF_LOOPBACK) {
		if (iptype == 4)
+2 −1
Original line number Diff line number Diff line
@@ -421,6 +421,7 @@ static int chap_server_compute_md5(
	auth_ret = 0;
out:
	kzfree(desc);
	if (tfm)
		crypto_free_shash(tfm);
	kfree(challenge);
	kfree(challenge_binhex);
+3 −0
Original line number Diff line number Diff line
@@ -432,6 +432,9 @@ static void iscsi_target_sk_data_ready(struct sock *sk)
	if (test_and_set_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) {
		write_unlock_bh(&sk->sk_callback_lock);
		pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1, conn: %p >>>>\n", conn);
		if (iscsi_target_sk_data_ready == conn->orig_data_ready)
			return;
		conn->orig_data_ready(sk);
		return;
	}

+61 −84
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ static void tcm_loop_release_cmd(struct se_cmd *se_cmd)

static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
{
	seq_printf(m, "tcm_loop_proc_info()\n");
	seq_puts(m, "tcm_loop_proc_info()\n");
	return 0;
}

@@ -123,8 +123,8 @@ static void tcm_loop_submission_work(struct work_struct *work)
	}
	tl_nexus = tl_tpg->tl_nexus;
	if (!tl_nexus) {
		scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
				" does not exist\n");
		scmd_printk(KERN_ERR, sc,
			    "TCM_Loop I_T Nexus does not exist\n");
		set_host_byte(sc, DID_ERROR);
		goto out_done;
	}
@@ -166,7 +166,6 @@ static void tcm_loop_submission_work(struct work_struct *work)
out_done:
	kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
	sc->scsi_done(sc);
	return;
}

/*
@@ -177,14 +176,13 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
{
	struct tcm_loop_cmd *tl_cmd;

	pr_debug("tcm_loop_queuecommand() %d:%d:%d:%llu got CDB: 0x%02x"
		" scsi_buf_len: %u\n", sc->device->host->host_no,
		sc->device->id, sc->device->channel, sc->device->lun,
		sc->cmnd[0], scsi_bufflen(sc));
	pr_debug("%s() %d:%d:%d:%llu got CDB: 0x%02x scsi_buf_len: %u\n",
		 __func__, sc->device->host->host_no, sc->device->id,
		 sc->device->channel, sc->device->lun, sc->cmnd[0],
		 scsi_bufflen(sc));

	tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC);
	if (!tl_cmd) {
		pr_err("Unable to allocate struct tcm_loop_cmd\n");
		set_host_byte(sc, DID_ERROR);
		sc->scsi_done(sc);
		return 0;
@@ -204,10 +202,10 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
			      u64 lun, int task, enum tcm_tmreq_table tmr)
{
	struct se_cmd *se_cmd = NULL;
	struct se_cmd *se_cmd;
	struct se_session *se_sess;
	struct tcm_loop_nexus *tl_nexus;
	struct tcm_loop_cmd *tl_cmd = NULL;
	struct tcm_loop_cmd *tl_cmd;
	int ret = TMR_FUNCTION_FAILED, rc;

	/*
@@ -215,16 +213,13 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
	 */
	tl_nexus = tl_tpg->tl_nexus;
	if (!tl_nexus) {
		pr_err("Unable to perform device reset without"
				" active I_T Nexus\n");
		pr_err("Unable to perform device reset without active I_T Nexus\n");
		return ret;
	}

	tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
	if (!tl_cmd) {
		pr_err("Unable to allocate memory for tl_cmd\n");
	if (!tl_cmd)
		return ret;
	}

	init_completion(&tl_cmd->tmr_done);

@@ -298,8 +293,7 @@ static int tcm_loop_target_reset(struct scsi_cmnd *sc)
	 */
	tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
	if (!tl_hba) {
		pr_err("Unable to perform device reset without"
				" active I_T Nexus\n");
		pr_err("Unable to perform device reset without active I_T Nexus\n");
		return FAILED;
	}
	/*
@@ -417,8 +411,7 @@ static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host

	ret = device_register(&tl_hba->dev);
	if (ret) {
		pr_err("device_register() failed for"
				" tl_hba->dev: %d\n", ret);
		pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
		return -ENODEV;
	}

@@ -447,8 +440,7 @@ static int tcm_loop_alloc_core_bus(void)

	ret = driver_register(&tcm_loop_driverfs);
	if (ret) {
		pr_err("driver_register() failed for"
				"tcm_loop_driverfs\n");
		pr_err("driver_register() failed for tcm_loop_driverfs\n");
		goto bus_unreg;
	}

@@ -587,8 +579,8 @@ static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
				struct tcm_loop_cmd, tl_se_cmd);
	struct scsi_cmnd *sc = tl_cmd->sc;

	pr_debug("tcm_loop_queue_data_in() called for scsi_cmnd: %p"
		     " cdb: 0x%02x\n", sc, sc->cmnd[0]);
	pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
		 __func__, sc, sc->cmnd[0]);

	sc->result = SAM_STAT_GOOD;
	set_host_byte(sc, DID_OK);
@@ -605,8 +597,8 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
				struct tcm_loop_cmd, tl_se_cmd);
	struct scsi_cmnd *sc = tl_cmd->sc;

	pr_debug("tcm_loop_queue_status() called for scsi_cmnd: %p"
			" cdb: 0x%02x\n", sc, sc->cmnd[0]);
	pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
		 __func__, sc, sc->cmnd[0]);

	if (se_cmd->sense_buffer &&
	   ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
@@ -691,8 +683,8 @@ static void tcm_loop_port_unlink(
	sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
				se_lun->unpacked_lun);
	if (!sd) {
		pr_err("Unable to locate struct scsi_device for %d:%d:"
			"%llu\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
		pr_err("Unable to locate struct scsi_device for %d:%d:%llu\n",
		       0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
		return;
	}
	/*
@@ -772,11 +764,9 @@ static int tcm_loop_make_nexus(
		return -EEXIST;
	}

	tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL);
	if (!tl_nexus) {
		pr_err("Unable to allocate struct tcm_loop_nexus\n");
	tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
	if (!tl_nexus)
		return -ENOMEM;
	}

	tl_nexus->se_sess = target_alloc_session(&tl_tpg->tl_se_tpg, 0, 0,
					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
@@ -787,9 +777,8 @@ static int tcm_loop_make_nexus(
		return ret;
	}

	pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
		" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
		name);
	pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated %s Initiator Port: %s\n",
		 tcm_loop_dump_proto_id(tl_hba), name);
	return 0;
}

@@ -808,14 +797,13 @@ static int tcm_loop_drop_nexus(
		return -ENODEV;

	if (atomic_read(&tpg->tl_tpg_port_count)) {
		pr_err("Unable to remove TCM_Loop I_T Nexus with"
			" active TPG port count: %d\n",
		pr_err("Unable to remove TCM_Loop I_T Nexus with active TPG port count: %d\n",
		       atomic_read(&tpg->tl_tpg_port_count));
		return -EPERM;
	}

	pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
		" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
	pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated %s Initiator Port: %s\n",
		 tcm_loop_dump_proto_id(tpg->tl_hba),
		 tl_nexus->se_sess->se_node_acl->initiatorname);
	/*
	 * Release the SCSI I_T Nexus to the emulated Target Port
@@ -868,8 +856,8 @@ static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
	 * tcm_loop_make_nexus()
	 */
	if (strlen(page) >= TL_WWN_ADDR_LEN) {
		pr_err("Emulated NAA Sas Address: %s, exceeds"
				" max: %d\n", page, TL_WWN_ADDR_LEN);
		pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",
		       page, TL_WWN_ADDR_LEN);
		return -EINVAL;
	}
	snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page);
@@ -877,9 +865,8 @@ static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
	ptr = strstr(i_port, "naa.");
	if (ptr) {
		if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
			pr_err("Passed SAS Initiator Port %s does not"
				" match target port protoid: %s\n", i_port,
				tcm_loop_dump_proto_id(tl_hba));
			pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",
			       i_port, tcm_loop_dump_proto_id(tl_hba));
			return -EINVAL;
		}
		port_ptr = &i_port[0];
@@ -888,9 +875,8 @@ static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
	ptr = strstr(i_port, "fc.");
	if (ptr) {
		if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
			pr_err("Passed FCP Initiator Port %s does not"
				" match target port protoid: %s\n", i_port,
				tcm_loop_dump_proto_id(tl_hba));
			pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",
			       i_port, tcm_loop_dump_proto_id(tl_hba));
			return -EINVAL;
		}
		port_ptr = &i_port[3]; /* Skip over "fc." */
@@ -899,16 +885,15 @@ static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
	ptr = strstr(i_port, "iqn.");
	if (ptr) {
		if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
			pr_err("Passed iSCSI Initiator Port %s does not"
				" match target port protoid: %s\n", i_port,
				tcm_loop_dump_proto_id(tl_hba));
			pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",
			       i_port, tcm_loop_dump_proto_id(tl_hba));
			return -EINVAL;
		}
		port_ptr = &i_port[0];
		goto check_newline;
	}
	pr_err("Unable to locate prefix for emulated Initiator Port:"
			" %s\n", i_port);
	pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",
	       i_port);
	return -EINVAL;
	/*
	 * Clear any trailing newline for the NAA WWN
@@ -1010,16 +995,15 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
	unsigned long tpgt;

	if (strstr(name, "tpgt_") != name) {
		pr_err("Unable to locate \"tpgt_#\" directory"
				" group\n");
		pr_err("Unable to locate \"tpgt_#\" directory group\n");
		return ERR_PTR(-EINVAL);
	}
	if (kstrtoul(name+5, 10, &tpgt))
		return ERR_PTR(-EINVAL);

	if (tpgt >= TL_TPGS_PER_HBA) {
		pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA:"
				" %u\n", tpgt, TL_TPGS_PER_HBA);
		pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n",
		       tpgt, TL_TPGS_PER_HBA);
		return ERR_PTR(-EINVAL);
	}
	tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
@@ -1032,10 +1016,9 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
	if (ret < 0)
		return ERR_PTR(-ENOMEM);

	pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s"
		" Target Port %s,t,0x%04lx\n", tcm_loop_dump_proto_id(tl_hba),
	pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n",
		 tcm_loop_dump_proto_id(tl_hba),
		 config_item_name(&wwn->wwn_group.cg_item), tpgt);

	return &tl_tpg->tl_se_tpg;
}

@@ -1062,8 +1045,8 @@ static void tcm_loop_drop_naa_tpg(
	tl_tpg->tl_hba = NULL;
	tl_tpg->tl_tpgt = 0;

	pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s"
		" Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
	pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n",
		 tcm_loop_dump_proto_id(tl_hba),
		 config_item_name(&wwn->wwn_group.cg_item), tpgt);
}

@@ -1081,11 +1064,10 @@ static struct se_wwn *tcm_loop_make_scsi_hba(
	char *ptr;
	int ret, off = 0;

	tl_hba = kzalloc(sizeof(struct tcm_loop_hba), GFP_KERNEL);
	if (!tl_hba) {
		pr_err("Unable to allocate struct tcm_loop_hba\n");
	tl_hba = kzalloc(sizeof(*tl_hba), GFP_KERNEL);
	if (!tl_hba)
		return ERR_PTR(-ENOMEM);
	}

	/*
	 * Determine the emulated Protocol Identifier and Target Port Name
	 * based on the incoming configfs directory name.
@@ -1103,8 +1085,8 @@ static struct se_wwn *tcm_loop_make_scsi_hba(
	}
	ptr = strstr(name, "iqn.");
	if (!ptr) {
		pr_err("Unable to locate prefix for emulated Target "
				"Port: %s\n", name);
		pr_err("Unable to locate prefix for emulated Target Port: %s\n",
		       name);
		ret = -EINVAL;
		goto out;
	}
@@ -1112,9 +1094,8 @@ static struct se_wwn *tcm_loop_make_scsi_hba(

check_len:
	if (strlen(name) >= TL_WWN_ADDR_LEN) {
		pr_err("Emulated NAA %s Address: %s, exceeds"
			" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
			TL_WWN_ADDR_LEN);
		pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n",
		       name, tcm_loop_dump_proto_id(tl_hba), TL_WWN_ADDR_LEN);
		ret = -EINVAL;
		goto out;
	}
@@ -1131,10 +1112,8 @@ static struct se_wwn *tcm_loop_make_scsi_hba(

	sh = tl_hba->sh;
	tcm_loop_hba_no_cnt++;
	pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target"
		" %s Address: %s at Linux/SCSI Host ID: %d\n",
	pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
		 tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);

	return &tl_hba->tl_hba_wwn;
out:
	kfree(tl_hba);
@@ -1147,8 +1126,7 @@ static void tcm_loop_drop_scsi_hba(
	struct tcm_loop_hba *tl_hba = container_of(wwn,
				struct tcm_loop_hba, tl_hba_wwn);

	pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target"
		" %s Address: %s at Linux/SCSI Host ID: %d\n",
	pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
		 tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address,
		 tl_hba->sh->host_no);
	/*
@@ -1223,8 +1201,7 @@ static int __init tcm_loop_fabric_init(void)
				__alignof__(struct tcm_loop_cmd),
				0, NULL);
	if (!tcm_loop_cmd_cache) {
		pr_debug("kmem_cache_create() for"
			" tcm_loop_cmd_cache failed\n");
		pr_debug("kmem_cache_create() for tcm_loop_cmd_cache failed\n");
		goto out_destroy_workqueue;
	}

+4 −9
Original line number Diff line number Diff line
@@ -201,10 +201,9 @@ static struct sbp_session *sbp_session_create(
	snprintf(guid_str, sizeof(guid_str), "%016llx", guid);

	sess = kmalloc(sizeof(*sess), GFP_KERNEL);
	if (!sess) {
		pr_err("failed to allocate session descriptor\n");
	if (!sess)
		return ERR_PTR(-ENOMEM);
	}

	spin_lock_init(&sess->lock);
	INIT_LIST_HEAD(&sess->login_list);
	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
@@ -2029,10 +2028,8 @@ static struct se_portal_group *sbp_make_tpg(
	}

	tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
	if (!tpg) {
		pr_err("Unable to allocate struct sbp_tpg\n");
	if (!tpg)
		return ERR_PTR(-ENOMEM);
	}

	tpg->tport = tport;
	tpg->tport_tpgt = tpgt;
@@ -2088,10 +2085,8 @@ static struct se_wwn *sbp_make_tport(
		return ERR_PTR(-EINVAL);

	tport = kzalloc(sizeof(*tport), GFP_KERNEL);
	if (!tport) {
		pr_err("Unable to allocate struct sbp_tport\n");
	if (!tport)
		return ERR_PTR(-ENOMEM);
	}

	tport->guid = guid;
	sbp_format_wwn(tport->tport_name, SBP_NAMELEN, guid);
Loading