diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 20:41:14 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 20:41:14 +0100 |
commit | 5266e5b12c8b73587130325f7074d2f49ef9e427 (patch) | |
tree | 79abfbf1b047de05860fa832f66fce5078cc6434 /drivers/vhost/scsi.c | |
parent | Merge tag 'pci-v4.6-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff) | |
parent | target: Fix target_release_cmd_kref shutdown comp leak (diff) | |
download | linux-5266e5b12c8b73587130325f7074d2f49ef9e427.tar.xz linux-5266e5b12c8b73587130325f7074d2f49ef9e427.zip |
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 this round include:
- Add target_alloc_session() w/ callback helper for doing se_session
allocation + tag + se_node_acl lookup. (HCH + nab)
- Tree-wide fabric driver conversion to use target_alloc_session()
- Convert sbp-target to use percpu_ida tag pre-allocation, and
TARGET_SCF_ACK_KREF I/O krefs (Chris Boot + nab)
- Convert usb-gadget to use percpu_ida tag pre-allocation, and
TARGET_SCF_ACK_KREF I/O krefs (Andrzej Pietrasiewicz + nab)
- Convert xen-scsiback to use percpu_ida tag pre-allocation, and
TARGET_SCF_ACK_KREF I/O krefs (Juergen Gross + nab)
- Convert tcm_fc to use TARGET_SCF_ACK_KREF I/O + TMR krefs
- Convert ib_srpt to use percpu_ida tag pre-allocation
- Add DebugFS node for qla2xxx target sess list (Quinn)
- Rework iser-target connection termination (Jenny + Sagi)
- Convert iser-target to new CQ API (HCH)
- Add pass-through WRITE_SAME support for IBLOCK (Mike Christie)
- Introduce data_bitmap for asynchronous access of data area (Sheng
Yang + Andy)
- Fix target_release_cmd_kref shutdown comp leak (Himanshu Madhani)
Also, there is a separate PULL request coming for cxgb4 NIC driver
prerequisites for supporting hw iscsi segmentation offload (ISO), that
will be the base for a number of v4.7 developments involving
iscsi-target hw offloads"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (36 commits)
target: Fix target_release_cmd_kref shutdown comp leak
target: Avoid DataIN transfers for non-GOOD SAM status
target/user: Report capability of handling out-of-order completions to userspace
target/user: Fix size_t format-spec build warning
target/user: Don't free expired command when time out
target/user: Introduce data_bitmap, replace data_length/data_head/data_tail
target/user: Free data ring in unified function
target/user: Use iovec[] to describe continuous area
target: Remove enum transport_lunflags_table
target/iblock: pass WRITE_SAME to device if possible
iser-target: Kill the ->isert_cmd back pointer in struct iser_tx_desc
iser-target: Kill struct isert_rdma_wr
iser-target: Convert to new CQ API
iser-target: Split and properly type the login buffer
iser-target: Remove ISER_RECV_DATA_SEG_LEN
iser-target: Remove impossible condition from isert_wait_conn
iser-target: Remove redundant wait in release_conn
iser-target: Rework connection termination
iser-target: Separate flows for np listeners and connections cma events
iser-target: Add new state ISER_CONN_BOUND to isert_conn
...
Diffstat (limited to 'drivers/vhost/scsi.c')
-rw-r--r-- | drivers/vhost/scsi.c | 99 |
1 files changed, 41 insertions, 58 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index f898686cdd93..0e6fd556c982 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -1664,8 +1664,7 @@ static void vhost_scsi_port_unlink(struct se_portal_group *se_tpg, mutex_unlock(&vhost_scsi_mutex); } -static void vhost_scsi_free_cmd_map_res(struct vhost_scsi_nexus *nexus, - struct se_session *se_sess) +static void vhost_scsi_free_cmd_map_res(struct se_session *se_sess) { struct vhost_scsi_cmd *tv_cmd; unsigned int i; @@ -1721,98 +1720,82 @@ static struct configfs_attribute *vhost_scsi_tpg_attrib_attrs[] = { NULL, }; -static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, - const char *name) +static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg, + struct se_session *se_sess, void *p) { - struct se_portal_group *se_tpg; - struct se_session *se_sess; - struct vhost_scsi_nexus *tv_nexus; struct vhost_scsi_cmd *tv_cmd; unsigned int i; - mutex_lock(&tpg->tv_tpg_mutex); - if (tpg->tpg_nexus) { - mutex_unlock(&tpg->tv_tpg_mutex); - pr_debug("tpg->tpg_nexus already exists\n"); - return -EEXIST; - } - se_tpg = &tpg->se_tpg; - - tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL); - if (!tv_nexus) { - mutex_unlock(&tpg->tv_tpg_mutex); - pr_err("Unable to allocate struct vhost_scsi_nexus\n"); - return -ENOMEM; - } - /* - * Initialize the struct se_session pointer and setup tagpool - * for struct vhost_scsi_cmd descriptors - */ - tv_nexus->tvn_se_sess = transport_init_session_tags( - VHOST_SCSI_DEFAULT_TAGS, - sizeof(struct vhost_scsi_cmd), - TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS); - if (IS_ERR(tv_nexus->tvn_se_sess)) { - mutex_unlock(&tpg->tv_tpg_mutex); - kfree(tv_nexus); - return -ENOMEM; - } - se_sess = tv_nexus->tvn_se_sess; for (i = 0; i < VHOST_SCSI_DEFAULT_TAGS; i++) { tv_cmd = &((struct vhost_scsi_cmd *)se_sess->sess_cmd_map)[i]; tv_cmd->tvc_sgl = kzalloc(sizeof(struct scatterlist) * VHOST_SCSI_PREALLOC_SGLS, GFP_KERNEL); if (!tv_cmd->tvc_sgl) { - mutex_unlock(&tpg->tv_tpg_mutex); pr_err("Unable to allocate tv_cmd->tvc_sgl\n"); goto out; } tv_cmd->tvc_upages = kzalloc(sizeof(struct page *) * - VHOST_SCSI_PREALLOC_UPAGES, GFP_KERNEL); + VHOST_SCSI_PREALLOC_UPAGES, GFP_KERNEL); if (!tv_cmd->tvc_upages) { - mutex_unlock(&tpg->tv_tpg_mutex); pr_err("Unable to allocate tv_cmd->tvc_upages\n"); goto out; } tv_cmd->tvc_prot_sgl = kzalloc(sizeof(struct scatterlist) * - VHOST_SCSI_PREALLOC_PROT_SGLS, GFP_KERNEL); + VHOST_SCSI_PREALLOC_PROT_SGLS, GFP_KERNEL); if (!tv_cmd->tvc_prot_sgl) { - mutex_unlock(&tpg->tv_tpg_mutex); pr_err("Unable to allocate tv_cmd->tvc_prot_sgl\n"); goto out; } } + return 0; +out: + vhost_scsi_free_cmd_map_res(se_sess); + return -ENOMEM; +} + +static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, + const char *name) +{ + struct se_portal_group *se_tpg; + struct vhost_scsi_nexus *tv_nexus; + + mutex_lock(&tpg->tv_tpg_mutex); + if (tpg->tpg_nexus) { + mutex_unlock(&tpg->tv_tpg_mutex); + pr_debug("tpg->tpg_nexus already exists\n"); + return -EEXIST; + } + se_tpg = &tpg->se_tpg; + + tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL); + if (!tv_nexus) { + mutex_unlock(&tpg->tv_tpg_mutex); + pr_err("Unable to allocate struct vhost_scsi_nexus\n"); + return -ENOMEM; + } /* * Since we are running in 'demo mode' this call with generate a * struct se_node_acl for the vhost_scsi struct se_portal_group with * the SCSI Initiator port name of the passed configfs group 'name'. */ - tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( - se_tpg, (unsigned char *)name); - if (!tv_nexus->tvn_se_sess->se_node_acl) { + tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, + VHOST_SCSI_DEFAULT_TAGS, + sizeof(struct vhost_scsi_cmd), + TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS, + (unsigned char *)name, tv_nexus, + vhost_scsi_nexus_cb); + if (IS_ERR(tv_nexus->tvn_se_sess)) { mutex_unlock(&tpg->tv_tpg_mutex); - pr_debug("core_tpg_check_initiator_node_acl() failed" - " for %s\n", name); - goto out; + kfree(tv_nexus); + return -ENOMEM; } - /* - * Now register the TCM vhost virtual I_T Nexus as active. - */ - transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, - tv_nexus->tvn_se_sess, tv_nexus); tpg->tpg_nexus = tv_nexus; mutex_unlock(&tpg->tv_tpg_mutex); return 0; - -out: - vhost_scsi_free_cmd_map_res(tv_nexus, se_sess); - transport_free_session(se_sess); - kfree(tv_nexus); - return -ENOMEM; } static int vhost_scsi_drop_nexus(struct vhost_scsi_tpg *tpg) @@ -1853,7 +1836,7 @@ static int vhost_scsi_drop_nexus(struct vhost_scsi_tpg *tpg) " %s Initiator Port: %s\n", vhost_scsi_dump_proto_id(tpg->tport), tv_nexus->tvn_se_sess->se_node_acl->initiatorname); - vhost_scsi_free_cmd_map_res(tv_nexus, se_sess); + vhost_scsi_free_cmd_map_res(se_sess); /* * Release the SCSI I_T Nexus to the emulated vhost Target Port */ |