Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

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
  ...
This commit is contained in:
Linus Torvalds 2018-02-09 14:49:46 -08:00
commit 858f45bff3
15 changed files with 799 additions and 390 deletions

View File

@ -893,6 +893,9 @@ cxgbit_offload_init(struct cxgbit_sock *csk, int iptype, __u8 *peer_ip,
return -ENODEV; return -ENODEV;
rcu_read_lock(); rcu_read_lock();
if (!(n->nud_state & NUD_VALID))
neigh_event_send(n, NULL);
ret = -ENOMEM; ret = -ENOMEM;
if (n->dev->flags & IFF_LOOPBACK) { if (n->dev->flags & IFF_LOOPBACK) {
if (iptype == 4) if (iptype == 4)

View File

@ -421,7 +421,8 @@ static int chap_server_compute_md5(
auth_ret = 0; auth_ret = 0;
out: out:
kzfree(desc); kzfree(desc);
crypto_free_shash(tfm); if (tfm)
crypto_free_shash(tfm);
kfree(challenge); kfree(challenge);
kfree(challenge_binhex); kfree(challenge_binhex);
return auth_ret; return auth_ret;

View File

@ -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)) { if (test_and_set_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) {
write_unlock_bh(&sk->sk_callback_lock); write_unlock_bh(&sk->sk_callback_lock);
pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1, conn: %p >>>>\n", conn); 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; return;
} }

View File

@ -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) 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; return 0;
} }
@ -123,8 +123,8 @@ static void tcm_loop_submission_work(struct work_struct *work)
} }
tl_nexus = tl_tpg->tl_nexus; tl_nexus = tl_tpg->tl_nexus;
if (!tl_nexus) { if (!tl_nexus) {
scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" scmd_printk(KERN_ERR, sc,
" does not exist\n"); "TCM_Loop I_T Nexus does not exist\n");
set_host_byte(sc, DID_ERROR); set_host_byte(sc, DID_ERROR);
goto out_done; goto out_done;
} }
@ -166,7 +166,6 @@ static void tcm_loop_submission_work(struct work_struct *work)
out_done: out_done:
kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
sc->scsi_done(sc); 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; struct tcm_loop_cmd *tl_cmd;
pr_debug("tcm_loop_queuecommand() %d:%d:%d:%llu got CDB: 0x%02x" pr_debug("%s() %d:%d:%d:%llu got CDB: 0x%02x scsi_buf_len: %u\n",
" scsi_buf_len: %u\n", sc->device->host->host_no, __func__, sc->device->host->host_no, sc->device->id,
sc->device->id, sc->device->channel, sc->device->lun, sc->device->channel, sc->device->lun, sc->cmnd[0],
sc->cmnd[0], scsi_bufflen(sc)); scsi_bufflen(sc));
tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC); tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC);
if (!tl_cmd) { if (!tl_cmd) {
pr_err("Unable to allocate struct tcm_loop_cmd\n");
set_host_byte(sc, DID_ERROR); set_host_byte(sc, DID_ERROR);
sc->scsi_done(sc); sc->scsi_done(sc);
return 0; 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, static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
u64 lun, int task, enum tcm_tmreq_table tmr) 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 se_session *se_sess;
struct tcm_loop_nexus *tl_nexus; 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; 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; tl_nexus = tl_tpg->tl_nexus;
if (!tl_nexus) { if (!tl_nexus) {
pr_err("Unable to perform device reset without" pr_err("Unable to perform device reset without active I_T Nexus\n");
" active I_T Nexus\n");
return ret; return ret;
} }
tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL); tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
if (!tl_cmd) { if (!tl_cmd)
pr_err("Unable to allocate memory for tl_cmd\n");
return ret; return ret;
}
init_completion(&tl_cmd->tmr_done); 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); tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
if (!tl_hba) { if (!tl_hba) {
pr_err("Unable to perform device reset without" pr_err("Unable to perform device reset without active I_T Nexus\n");
" active I_T Nexus\n");
return FAILED; 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); ret = device_register(&tl_hba->dev);
if (ret) { if (ret) {
pr_err("device_register() failed for" pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
" tl_hba->dev: %d\n", ret);
return -ENODEV; return -ENODEV;
} }
@ -447,8 +440,7 @@ static int tcm_loop_alloc_core_bus(void)
ret = driver_register(&tcm_loop_driverfs); ret = driver_register(&tcm_loop_driverfs);
if (ret) { if (ret) {
pr_err("driver_register() failed for" pr_err("driver_register() failed for tcm_loop_driverfs\n");
"tcm_loop_driverfs\n");
goto bus_unreg; 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 tcm_loop_cmd, tl_se_cmd);
struct scsi_cmnd *sc = tl_cmd->sc; struct scsi_cmnd *sc = tl_cmd->sc;
pr_debug("tcm_loop_queue_data_in() called for scsi_cmnd: %p" pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
" cdb: 0x%02x\n", sc, sc->cmnd[0]); __func__, sc, sc->cmnd[0]);
sc->result = SAM_STAT_GOOD; sc->result = SAM_STAT_GOOD;
set_host_byte(sc, DID_OK); 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 tcm_loop_cmd, tl_se_cmd);
struct scsi_cmnd *sc = tl_cmd->sc; struct scsi_cmnd *sc = tl_cmd->sc;
pr_debug("tcm_loop_queue_status() called for scsi_cmnd: %p" pr_debug("%s() called for scsi_cmnd: %p cdb: 0x%02x\n",
" cdb: 0x%02x\n", sc, sc->cmnd[0]); __func__, sc, sc->cmnd[0]);
if (se_cmd->sense_buffer && if (se_cmd->sense_buffer &&
((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) || ((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, sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
se_lun->unpacked_lun); se_lun->unpacked_lun);
if (!sd) { if (!sd) {
pr_err("Unable to locate struct scsi_device for %d:%d:" pr_err("Unable to locate struct scsi_device for %d:%d:%llu\n",
"%llu\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun); 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
return; return;
} }
/* /*
@ -772,11 +764,9 @@ static int tcm_loop_make_nexus(
return -EEXIST; return -EEXIST;
} }
tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL); tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
if (!tl_nexus) { if (!tl_nexus)
pr_err("Unable to allocate struct tcm_loop_nexus\n");
return -ENOMEM; return -ENOMEM;
}
tl_nexus->se_sess = target_alloc_session(&tl_tpg->tl_se_tpg, 0, 0, tl_nexus->se_sess = target_alloc_session(&tl_tpg->tl_se_tpg, 0, 0,
TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS, TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
@ -787,9 +777,8 @@ static int tcm_loop_make_nexus(
return ret; return ret;
} }
pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated" pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated %s Initiator Port: %s\n",
" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), tcm_loop_dump_proto_id(tl_hba), name);
name);
return 0; return 0;
} }
@ -808,15 +797,14 @@ static int tcm_loop_drop_nexus(
return -ENODEV; return -ENODEV;
if (atomic_read(&tpg->tl_tpg_port_count)) { if (atomic_read(&tpg->tl_tpg_port_count)) {
pr_err("Unable to remove TCM_Loop I_T Nexus with" pr_err("Unable to remove TCM_Loop I_T Nexus with active TPG port count: %d\n",
" active TPG port count: %d\n", atomic_read(&tpg->tl_tpg_port_count));
atomic_read(&tpg->tl_tpg_port_count));
return -EPERM; return -EPERM;
} }
pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated" pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated %s Initiator Port: %s\n",
" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), tcm_loop_dump_proto_id(tpg->tl_hba),
tl_nexus->se_sess->se_node_acl->initiatorname); tl_nexus->se_sess->se_node_acl->initiatorname);
/* /*
* Release the SCSI I_T Nexus to the emulated Target Port * 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() * tcm_loop_make_nexus()
*/ */
if (strlen(page) >= TL_WWN_ADDR_LEN) { if (strlen(page) >= TL_WWN_ADDR_LEN) {
pr_err("Emulated NAA Sas Address: %s, exceeds" pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",
" max: %d\n", page, TL_WWN_ADDR_LEN); page, TL_WWN_ADDR_LEN);
return -EINVAL; return -EINVAL;
} }
snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page); 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."); ptr = strstr(i_port, "naa.");
if (ptr) { if (ptr) {
if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) { if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
pr_err("Passed SAS Initiator Port %s does not" pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",
" match target port protoid: %s\n", i_port, i_port, tcm_loop_dump_proto_id(tl_hba));
tcm_loop_dump_proto_id(tl_hba));
return -EINVAL; return -EINVAL;
} }
port_ptr = &i_port[0]; 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."); ptr = strstr(i_port, "fc.");
if (ptr) { if (ptr) {
if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) { if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
pr_err("Passed FCP Initiator Port %s does not" pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",
" match target port protoid: %s\n", i_port, i_port, tcm_loop_dump_proto_id(tl_hba));
tcm_loop_dump_proto_id(tl_hba));
return -EINVAL; return -EINVAL;
} }
port_ptr = &i_port[3]; /* Skip over "fc." */ 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."); ptr = strstr(i_port, "iqn.");
if (ptr) { if (ptr) {
if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) { if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
pr_err("Passed iSCSI Initiator Port %s does not" pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",
" match target port protoid: %s\n", i_port, i_port, tcm_loop_dump_proto_id(tl_hba));
tcm_loop_dump_proto_id(tl_hba));
return -EINVAL; return -EINVAL;
} }
port_ptr = &i_port[0]; port_ptr = &i_port[0];
goto check_newline; goto check_newline;
} }
pr_err("Unable to locate prefix for emulated Initiator Port:" pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",
" %s\n", i_port); i_port);
return -EINVAL; return -EINVAL;
/* /*
* Clear any trailing newline for the NAA WWN * 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; unsigned long tpgt;
if (strstr(name, "tpgt_") != name) { if (strstr(name, "tpgt_") != name) {
pr_err("Unable to locate \"tpgt_#\" directory" pr_err("Unable to locate \"tpgt_#\" directory group\n");
" group\n");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (kstrtoul(name+5, 10, &tpgt)) if (kstrtoul(name+5, 10, &tpgt))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (tpgt >= TL_TPGS_PER_HBA) { if (tpgt >= TL_TPGS_PER_HBA) {
pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA:" pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n",
" %u\n", tpgt, TL_TPGS_PER_HBA); tpgt, TL_TPGS_PER_HBA);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
tl_tpg = &tl_hba->tl_hba_tpgs[tpgt]; 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) if (ret < 0)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s" pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n",
" Target Port %s,t,0x%04lx\n", tcm_loop_dump_proto_id(tl_hba), tcm_loop_dump_proto_id(tl_hba),
config_item_name(&wwn->wwn_group.cg_item), tpgt); config_item_name(&wwn->wwn_group.cg_item), tpgt);
return &tl_tpg->tl_se_tpg; return &tl_tpg->tl_se_tpg;
} }
@ -1062,9 +1045,9 @@ static void tcm_loop_drop_naa_tpg(
tl_tpg->tl_hba = NULL; tl_tpg->tl_hba = NULL;
tl_tpg->tl_tpgt = 0; tl_tpg->tl_tpgt = 0;
pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s" pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n",
" Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba), tcm_loop_dump_proto_id(tl_hba),
config_item_name(&wwn->wwn_group.cg_item), tpgt); config_item_name(&wwn->wwn_group.cg_item), tpgt);
} }
/* End items for tcm_loop_naa_cit */ /* End items for tcm_loop_naa_cit */
@ -1081,11 +1064,10 @@ static struct se_wwn *tcm_loop_make_scsi_hba(
char *ptr; char *ptr;
int ret, off = 0; int ret, off = 0;
tl_hba = kzalloc(sizeof(struct tcm_loop_hba), GFP_KERNEL); tl_hba = kzalloc(sizeof(*tl_hba), GFP_KERNEL);
if (!tl_hba) { if (!tl_hba)
pr_err("Unable to allocate struct tcm_loop_hba\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
/* /*
* Determine the emulated Protocol Identifier and Target Port Name * Determine the emulated Protocol Identifier and Target Port Name
* based on the incoming configfs directory 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."); ptr = strstr(name, "iqn.");
if (!ptr) { if (!ptr) {
pr_err("Unable to locate prefix for emulated Target " pr_err("Unable to locate prefix for emulated Target Port: %s\n",
"Port: %s\n", name); name);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
@ -1112,9 +1094,8 @@ static struct se_wwn *tcm_loop_make_scsi_hba(
check_len: check_len:
if (strlen(name) >= TL_WWN_ADDR_LEN) { if (strlen(name) >= TL_WWN_ADDR_LEN) {
pr_err("Emulated NAA %s Address: %s, exceeds" pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n",
" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba), name, tcm_loop_dump_proto_id(tl_hba), TL_WWN_ADDR_LEN);
TL_WWN_ADDR_LEN);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
@ -1131,10 +1112,8 @@ check_len:
sh = tl_hba->sh; sh = tl_hba->sh;
tcm_loop_hba_no_cnt++; tcm_loop_hba_no_cnt++;
pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target" pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
" %s Address: %s at Linux/SCSI Host ID: %d\n", tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
return &tl_hba->tl_hba_wwn; return &tl_hba->tl_hba_wwn;
out: out:
kfree(tl_hba); kfree(tl_hba);
@ -1147,10 +1126,9 @@ static void tcm_loop_drop_scsi_hba(
struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba *tl_hba = container_of(wwn,
struct tcm_loop_hba, tl_hba_wwn); struct tcm_loop_hba, tl_hba_wwn);
pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target %s Address: %s at Linux/SCSI Host ID: %d\n",
" %s Address: %s at Linux/SCSI Host ID: %d\n", tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address,
tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address, tl_hba->sh->host_no);
tl_hba->sh->host_no);
/* /*
* Call device_unregister() on the original tl_hba->dev. * Call device_unregister() on the original tl_hba->dev.
* tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
@ -1223,8 +1201,7 @@ static int __init tcm_loop_fabric_init(void)
__alignof__(struct tcm_loop_cmd), __alignof__(struct tcm_loop_cmd),
0, NULL); 0, NULL);
if (!tcm_loop_cmd_cache) { if (!tcm_loop_cmd_cache) {
pr_debug("kmem_cache_create() for" pr_debug("kmem_cache_create() for tcm_loop_cmd_cache failed\n");
" tcm_loop_cmd_cache failed\n");
goto out_destroy_workqueue; goto out_destroy_workqueue;
} }

View File

@ -201,10 +201,9 @@ static struct sbp_session *sbp_session_create(
snprintf(guid_str, sizeof(guid_str), "%016llx", guid); snprintf(guid_str, sizeof(guid_str), "%016llx", guid);
sess = kmalloc(sizeof(*sess), GFP_KERNEL); sess = kmalloc(sizeof(*sess), GFP_KERNEL);
if (!sess) { if (!sess)
pr_err("failed to allocate session descriptor\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
spin_lock_init(&sess->lock); spin_lock_init(&sess->lock);
INIT_LIST_HEAD(&sess->login_list); INIT_LIST_HEAD(&sess->login_list);
INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work); 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); tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
if (!tpg) { if (!tpg)
pr_err("Unable to allocate struct sbp_tpg\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
tpg->tport = tport; tpg->tport = tport;
tpg->tport_tpgt = tpgt; tpg->tport_tpgt = tpgt;
@ -2088,10 +2085,8 @@ static struct se_wwn *sbp_make_tport(
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
tport = kzalloc(sizeof(*tport), GFP_KERNEL); tport = kzalloc(sizeof(*tport), GFP_KERNEL);
if (!tport) { if (!tport)
pr_err("Unable to allocate struct sbp_tport\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
tport->guid = guid; tport->guid = guid;
sbp_format_wwn(tport->tport_name, SBP_NAMELEN, guid); sbp_format_wwn(tport->tport_name, SBP_NAMELEN, guid);

View File

@ -1197,6 +1197,7 @@ struct configfs_attribute *passthrough_attrib_attrs[] = {
EXPORT_SYMBOL(passthrough_attrib_attrs); EXPORT_SYMBOL(passthrough_attrib_attrs);
TB_CIT_SETUP_DRV(dev_attrib, NULL, NULL); TB_CIT_SETUP_DRV(dev_attrib, NULL, NULL);
TB_CIT_SETUP_DRV(dev_action, NULL, NULL);
/* End functions for struct config_item_type tb_dev_attrib_cit */ /* End functions for struct config_item_type tb_dev_attrib_cit */
@ -2940,6 +2941,10 @@ static struct config_group *target_core_make_subdev(
config_group_init_type_name(&dev->dev_group, name, &tb->tb_dev_cit); config_group_init_type_name(&dev->dev_group, name, &tb->tb_dev_cit);
config_group_init_type_name(&dev->dev_action_group, "action",
&tb->tb_dev_action_cit);
configfs_add_default_group(&dev->dev_action_group, &dev->dev_group);
config_group_init_type_name(&dev->dev_attrib.da_group, "attrib", config_group_init_type_name(&dev->dev_attrib.da_group, "attrib",
&tb->tb_dev_attrib_cit); &tb->tb_dev_attrib_cit);
configfs_add_default_group(&dev->dev_attrib.da_group, &dev->dev_group); configfs_add_default_group(&dev->dev_attrib.da_group, &dev->dev_group);
@ -3200,6 +3205,7 @@ static const struct config_item_type target_core_cit = {
void target_setup_backend_cits(struct target_backend *tb) void target_setup_backend_cits(struct target_backend *tb)
{ {
target_core_setup_dev_cit(tb); target_core_setup_dev_cit(tb);
target_core_setup_dev_action_cit(tb);
target_core_setup_dev_attrib_cit(tb); target_core_setup_dev_attrib_cit(tb);
target_core_setup_dev_pr_cit(tb); target_core_setup_dev_pr_cit(tb);
target_core_setup_dev_wwn_cit(tb); target_core_setup_dev_wwn_cit(tb);

View File

@ -997,7 +997,7 @@ int target_configure_device(struct se_device *dev)
ret = core_setup_alua(dev); ret = core_setup_alua(dev);
if (ret) if (ret)
goto out_free_index; goto out_destroy_device;
/* /*
* Startup the struct se_device processing thread * Startup the struct se_device processing thread
@ -1041,6 +1041,8 @@ int target_configure_device(struct se_device *dev)
out_free_alua: out_free_alua:
core_alua_free_lu_gp_mem(dev); core_alua_free_lu_gp_mem(dev);
out_destroy_device:
dev->transport->destroy_device(dev);
out_free_index: out_free_index:
mutex_lock(&device_mutex); mutex_lock(&device_mutex);
idr_remove(&devices_idr, dev->dev_index); idr_remove(&devices_idr, dev->dev_index);

View File

@ -273,7 +273,7 @@ static int iscsi_get_pr_transport_id_len(
static char *iscsi_parse_pr_out_transport_id( static char *iscsi_parse_pr_out_transport_id(
struct se_portal_group *se_tpg, struct se_portal_group *se_tpg,
const char *buf, char *buf,
u32 *out_tid_len, u32 *out_tid_len,
char **port_nexus_ptr) char **port_nexus_ptr)
{ {
@ -356,7 +356,7 @@ static char *iscsi_parse_pr_out_transport_id(
} }
} }
return (char *)&buf[4]; return &buf[4];
} }
int target_get_pr_transport_id_len(struct se_node_acl *nacl, int target_get_pr_transport_id_len(struct se_node_acl *nacl,
@ -405,7 +405,7 @@ int target_get_pr_transport_id(struct se_node_acl *nacl,
} }
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg, const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
const char *buf, u32 *out_tid_len, char **port_nexus_ptr) char *buf, u32 *out_tid_len, char **port_nexus_ptr)
{ {
u32 offset; u32 offset;

View File

@ -17,6 +17,7 @@ struct target_backend {
struct config_item_type tb_dev_cit; struct config_item_type tb_dev_cit;
struct config_item_type tb_dev_attrib_cit; struct config_item_type tb_dev_attrib_cit;
struct config_item_type tb_dev_action_cit;
struct config_item_type tb_dev_pr_cit; struct config_item_type tb_dev_pr_cit;
struct config_item_type tb_dev_wwn_cit; struct config_item_type tb_dev_wwn_cit;
struct config_item_type tb_dev_alua_tg_pt_gps_cit; struct config_item_type tb_dev_alua_tg_pt_gps_cit;
@ -102,7 +103,7 @@ int target_get_pr_transport_id(struct se_node_acl *nacl,
struct t10_pr_registration *pr_reg, int *format_code, struct t10_pr_registration *pr_reg, int *format_code,
unsigned char *buf); unsigned char *buf);
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg, const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
const char *buf, u32 *out_tid_len, char **port_nexus_ptr); char *buf, u32 *out_tid_len, char **port_nexus_ptr);
/* target_core_hba.c */ /* target_core_hba.c */
struct se_hba *core_alloc_hba(const char *, u32, u32); struct se_hba *core_alloc_hba(const char *, u32, u32);

View File

@ -1601,7 +1601,7 @@ core_scsi3_decode_spec_i_port(
dest_rtpi = tmp_lun->lun_rtpi; dest_rtpi = tmp_lun->lun_rtpi;
i_str = target_parse_pr_out_transport_id(tmp_tpg, i_str = target_parse_pr_out_transport_id(tmp_tpg,
(const char *)ptr, &tid_len, &iport_ptr); ptr, &tid_len, &iport_ptr);
if (!i_str) if (!i_str)
continue; continue;
@ -3287,7 +3287,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
goto out; goto out;
} }
initiator_str = target_parse_pr_out_transport_id(dest_se_tpg, initiator_str = target_parse_pr_out_transport_id(dest_se_tpg,
(const char *)&buf[24], &tmp_tid_len, &iport_ptr); &buf[24], &tmp_tid_len, &iport_ptr);
if (!initiator_str) { if (!initiator_str) {
pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
" initiator_str from Transport ID\n"); " initiator_str from Transport ID\n");

View File

@ -1216,9 +1216,11 @@ sbc_execute_unmap(struct se_cmd *cmd)
goto err; goto err;
} }
ret = ops->execute_unmap(cmd, lba, range); if (range) {
if (ret) ret = ops->execute_unmap(cmd, lba, range);
goto err; if (ret)
goto err;
}
ptr += 16; ptr += 16;
size -= 16; size -= 16;

View File

@ -1774,6 +1774,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
case TCM_OUT_OF_RESOURCES: case TCM_OUT_OF_RESOURCES:
cmd->scsi_status = SAM_STAT_TASK_SET_FULL; cmd->scsi_status = SAM_STAT_TASK_SET_FULL;
goto queue_status; goto queue_status;
case TCM_LUN_BUSY:
cmd->scsi_status = SAM_STAT_BUSY;
goto queue_status;
case TCM_RESERVATION_CONFLICT: case TCM_RESERVATION_CONFLICT:
/* /*
* No SENSE Data payload for this case, set SCSI Status * No SENSE Data payload for this case, set SCSI Status

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,7 @@ struct target_backend_ops {
void (*free_prot)(struct se_device *); void (*free_prot)(struct se_device *);
struct configfs_attribute **tb_dev_attrib_attrs; struct configfs_attribute **tb_dev_attrib_attrs;
struct configfs_attribute **tb_dev_action_attrs;
}; };
struct sbc_ops { struct sbc_ops {

View File

@ -183,6 +183,7 @@ enum tcm_sense_reason_table {
TCM_TOO_MANY_SEGMENT_DESCS = R(0x1b), TCM_TOO_MANY_SEGMENT_DESCS = R(0x1b),
TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE = R(0x1c), TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE = R(0x1c),
TCM_INSUFFICIENT_REGISTRATION_RESOURCES = R(0x1d), TCM_INSUFFICIENT_REGISTRATION_RESOURCES = R(0x1d),
TCM_LUN_BUSY = R(0x1e),
#undef R #undef R
}; };
@ -808,6 +809,7 @@ struct se_device {
/* T10 SPC-2 + SPC-3 Reservations */ /* T10 SPC-2 + SPC-3 Reservations */
struct t10_reservation t10_pr; struct t10_reservation t10_pr;
struct se_dev_attrib dev_attrib; struct se_dev_attrib dev_attrib;
struct config_group dev_action_group;
struct config_group dev_group; struct config_group dev_group;
struct config_group dev_pr_group; struct config_group dev_pr_group;
struct se_dev_stat_grps dev_stat_grps; struct se_dev_stat_grps dev_stat_grps;