Loading drivers/vhost/scsi.c +41 −58 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1721,50 +1720,18 @@ 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; } Loading @@ -1772,7 +1739,6 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, tv_cmd->tvc_upages = kzalloc(sizeof(struct page *) * 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; } Loading @@ -1780,39 +1746,56 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, tv_cmd->tvc_prot_sgl = kzalloc(sizeof(struct scatterlist) * 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) Loading Loading @@ -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 */ Loading Loading
drivers/vhost/scsi.c +41 −58 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -1721,50 +1720,18 @@ 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; } Loading @@ -1772,7 +1739,6 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, tv_cmd->tvc_upages = kzalloc(sizeof(struct page *) * 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; } Loading @@ -1780,39 +1746,56 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, tv_cmd->tvc_prot_sgl = kzalloc(sizeof(struct scatterlist) * 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) Loading Loading @@ -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 */ Loading