linux/drivers/vhost/tcm_vhost.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Vhost kernel TCM fabric driver for virtio SCSI initiators
   3 *
   4 * (C) Copyright 2010-2012 RisingTide Systems LLC.
   5 * (C) Copyright 2010-2012 IBM Corp.
   6 *
   7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
   8 *
   9 * Authors: Nicholas A. Bellinger <nab@risingtidesystems.com>
  10 *          Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 ****************************************************************************/
  23
  24#include <linux/module.h>
  25#include <linux/moduleparam.h>
  26#include <generated/utsrelease.h>
  27#include <linux/utsname.h>
  28#include <linux/init.h>
  29#include <linux/slab.h>
  30#include <linux/kthread.h>
  31#include <linux/types.h>
  32#include <linux/string.h>
  33#include <linux/configfs.h>
  34#include <linux/ctype.h>
  35#include <linux/compat.h>
  36#include <linux/eventfd.h>
  37#include <linux/vhost.h>
  38#include <linux/fs.h>
  39#include <linux/miscdevice.h>
  40#include <asm/unaligned.h>
  41#include <scsi/scsi.h>
  42#include <scsi/scsi_tcq.h>
  43#include <target/target_core_base.h>
  44#include <target/target_core_fabric.h>
  45#include <target/target_core_fabric_configfs.h>
  46#include <target/target_core_configfs.h>
  47#include <target/configfs_macros.h>
  48#include <linux/vhost.h>
  49#include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */
  50#include <linux/virtio_scsi.h>
  51
  52#include "vhost.c"
  53#include "vhost.h"
  54#include "tcm_vhost.h"
  55
  56enum {
  57        VHOST_SCSI_VQ_CTL = 0,
  58        VHOST_SCSI_VQ_EVT = 1,
  59        VHOST_SCSI_VQ_IO = 2,
  60};
  61
  62struct vhost_scsi {
  63        struct tcm_vhost_tpg *vs_tpg;   /* Protected by vhost_scsi->dev.mutex */
  64        struct vhost_dev dev;
  65        struct vhost_virtqueue vqs[3];
  66
  67        struct vhost_work vs_completion_work; /* cmd completion work item */
  68        struct list_head vs_completion_list;  /* cmd completion queue */
  69        spinlock_t vs_completion_lock;        /* protects s_completion_list */
  70};
  71
  72/* Local pointer to allocated TCM configfs fabric module */
  73static struct target_fabric_configfs *tcm_vhost_fabric_configfs;
  74
  75static struct workqueue_struct *tcm_vhost_workqueue;
  76
  77/* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */
  78static DEFINE_MUTEX(tcm_vhost_mutex);
  79static LIST_HEAD(tcm_vhost_list);
  80
  81static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
  82{
  83        return 1;
  84}
  85
  86static int tcm_vhost_check_false(struct se_portal_group *se_tpg)
  87{
  88        return 0;
  89}
  90
  91static char *tcm_vhost_get_fabric_name(void)
  92{
  93        return "vhost";
  94}
  95
  96static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg)
  97{
  98        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
  99                                struct tcm_vhost_tpg, se_tpg);
 100        struct tcm_vhost_tport *tport = tpg->tport;
 101
 102        switch (tport->tport_proto_id) {
 103        case SCSI_PROTOCOL_SAS:
 104                return sas_get_fabric_proto_ident(se_tpg);
 105        case SCSI_PROTOCOL_FCP:
 106                return fc_get_fabric_proto_ident(se_tpg);
 107        case SCSI_PROTOCOL_ISCSI:
 108                return iscsi_get_fabric_proto_ident(se_tpg);
 109        default:
 110                pr_err("Unknown tport_proto_id: 0x%02x, using"
 111                        " SAS emulation\n", tport->tport_proto_id);
 112                break;
 113        }
 114
 115        return sas_get_fabric_proto_ident(se_tpg);
 116}
 117
 118static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg)
 119{
 120        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 121                                struct tcm_vhost_tpg, se_tpg);
 122        struct tcm_vhost_tport *tport = tpg->tport;
 123
 124        return &tport->tport_name[0];
 125}
 126
 127static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg)
 128{
 129        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 130                                struct tcm_vhost_tpg, se_tpg);
 131        return tpg->tport_tpgt;
 132}
 133
 134static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg)
 135{
 136        return 1;
 137}
 138
 139static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
 140        struct se_node_acl *se_nacl,
 141        struct t10_pr_registration *pr_reg,
 142        int *format_code,
 143        unsigned char *buf)
 144{
 145        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 146                                struct tcm_vhost_tpg, se_tpg);
 147        struct tcm_vhost_tport *tport = tpg->tport;
 148
 149        switch (tport->tport_proto_id) {
 150        case SCSI_PROTOCOL_SAS:
 151                return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 152                                        format_code, buf);
 153        case SCSI_PROTOCOL_FCP:
 154                return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 155                                        format_code, buf);
 156        case SCSI_PROTOCOL_ISCSI:
 157                return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 158                                        format_code, buf);
 159        default:
 160                pr_err("Unknown tport_proto_id: 0x%02x, using"
 161                        " SAS emulation\n", tport->tport_proto_id);
 162                break;
 163        }
 164
 165        return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 166                        format_code, buf);
 167}
 168
 169static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
 170        struct se_node_acl *se_nacl,
 171        struct t10_pr_registration *pr_reg,
 172        int *format_code)
 173{
 174        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 175                                struct tcm_vhost_tpg, se_tpg);
 176        struct tcm_vhost_tport *tport = tpg->tport;
 177
 178        switch (tport->tport_proto_id) {
 179        case SCSI_PROTOCOL_SAS:
 180                return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 181                                        format_code);
 182        case SCSI_PROTOCOL_FCP:
 183                return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 184                                        format_code);
 185        case SCSI_PROTOCOL_ISCSI:
 186                return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 187                                        format_code);
 188        default:
 189                pr_err("Unknown tport_proto_id: 0x%02x, using"
 190                        " SAS emulation\n", tport->tport_proto_id);
 191                break;
 192        }
 193
 194        return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 195                        format_code);
 196}
 197
 198static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
 199        const char *buf,
 200        u32 *out_tid_len,
 201        char **port_nexus_ptr)
 202{
 203        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 204                                struct tcm_vhost_tpg, se_tpg);
 205        struct tcm_vhost_tport *tport = tpg->tport;
 206
 207        switch (tport->tport_proto_id) {
 208        case SCSI_PROTOCOL_SAS:
 209                return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 210                                        port_nexus_ptr);
 211        case SCSI_PROTOCOL_FCP:
 212                return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 213                                        port_nexus_ptr);
 214        case SCSI_PROTOCOL_ISCSI:
 215                return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 216                                        port_nexus_ptr);
 217        default:
 218                pr_err("Unknown tport_proto_id: 0x%02x, using"
 219                        " SAS emulation\n", tport->tport_proto_id);
 220                break;
 221        }
 222
 223        return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 224                        port_nexus_ptr);
 225}
 226
 227static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
 228        struct se_portal_group *se_tpg)
 229{
 230        struct tcm_vhost_nacl *nacl;
 231
 232        nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL);
 233        if (!nacl) {
 234                pr_err("Unable to alocate struct tcm_vhost_nacl\n");
 235                return NULL;
 236        }
 237
 238        return &nacl->se_node_acl;
 239}
 240
 241static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
 242        struct se_node_acl *se_nacl)
 243{
 244        struct tcm_vhost_nacl *nacl = container_of(se_nacl,
 245                        struct tcm_vhost_nacl, se_node_acl);
 246        kfree(nacl);
 247}
 248
 249static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg)
 250{
 251        return 1;
 252}
 253
 254static void tcm_vhost_release_cmd(struct se_cmd *se_cmd)
 255{
 256        return;
 257}
 258
 259static int tcm_vhost_shutdown_session(struct se_session *se_sess)
 260{
 261        return 0;
 262}
 263
 264static void tcm_vhost_close_session(struct se_session *se_sess)
 265{
 266        return;
 267}
 268
 269static u32 tcm_vhost_sess_get_index(struct se_session *se_sess)
 270{
 271        return 0;
 272}
 273
 274static int tcm_vhost_write_pending(struct se_cmd *se_cmd)
 275{
 276        /* Go ahead and process the write immediately */
 277        target_execute_cmd(se_cmd);
 278        return 0;
 279}
 280
 281static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd)
 282{
 283        return 0;
 284}
 285
 286static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl)
 287{
 288        return;
 289}
 290
 291static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd)
 292{
 293        return 0;
 294}
 295
 296static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd)
 297{
 298        return 0;
 299}
 300
 301static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
 302{
 303        struct vhost_scsi *vs = tv_cmd->tvc_vhost;
 304
 305        spin_lock_bh(&vs->vs_completion_lock);
 306        list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
 307        spin_unlock_bh(&vs->vs_completion_lock);
 308
 309        vhost_work_queue(&vs->dev, &vs->vs_completion_work);
 310}
 311
 312static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd)
 313{
 314        struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
 315                                struct tcm_vhost_cmd, tvc_se_cmd);
 316        vhost_scsi_complete_cmd(tv_cmd);
 317        return 0;
 318}
 319
 320static int tcm_vhost_queue_status(struct se_cmd *se_cmd)
 321{
 322        struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
 323                                struct tcm_vhost_cmd, tvc_se_cmd);
 324        vhost_scsi_complete_cmd(tv_cmd);
 325        return 0;
 326}
 327
 328static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
 329{
 330        return 0;
 331}
 332
 333static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd,
 334        u32 sense_length)
 335{
 336        return 0;
 337}
 338
 339static u16 tcm_vhost_get_fabric_sense_len(void)
 340{
 341        return 0;
 342}
 343
 344static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
 345{
 346        struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 347
 348        /* TODO locking against target/backend threads? */
 349        transport_generic_free_cmd(se_cmd, 1);
 350
 351        if (tv_cmd->tvc_sgl_count) {
 352                u32 i;
 353                for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
 354                        put_page(sg_page(&tv_cmd->tvc_sgl[i]));
 355
 356                kfree(tv_cmd->tvc_sgl);
 357        }
 358
 359        kfree(tv_cmd);
 360}
 361
 362/* Dequeue a command from the completion list */
 363static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion(
 364        struct vhost_scsi *vs)
 365{
 366        struct tcm_vhost_cmd *tv_cmd = NULL;
 367
 368        spin_lock_bh(&vs->vs_completion_lock);
 369        if (list_empty(&vs->vs_completion_list)) {
 370                spin_unlock_bh(&vs->vs_completion_lock);
 371                return NULL;
 372        }
 373
 374        list_for_each_entry(tv_cmd, &vs->vs_completion_list,
 375                            tvc_completion_list) {
 376                list_del(&tv_cmd->tvc_completion_list);
 377                break;
 378        }
 379        spin_unlock_bh(&vs->vs_completion_lock);
 380        return tv_cmd;
 381}
 382
 383/* Fill in status and signal that we are done processing this command
 384 *
 385 * This is scheduled in the vhost work queue so we are called with the owner
 386 * process mm and can access the vring.
 387 */
 388static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
 389{
 390        struct vhost_scsi *vs = container_of(work, struct vhost_scsi,
 391                                        vs_completion_work);
 392        struct tcm_vhost_cmd *tv_cmd;
 393
 394        while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) {
 395                struct virtio_scsi_cmd_resp v_rsp;
 396                struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 397                int ret;
 398
 399                pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
 400                        tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
 401
 402                memset(&v_rsp, 0, sizeof(v_rsp));
 403                v_rsp.resid = se_cmd->residual_count;
 404                /* TODO is status_qualifier field needed? */
 405                v_rsp.status = se_cmd->scsi_status;
 406                v_rsp.sense_len = se_cmd->scsi_sense_length;
 407                memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
 408                       v_rsp.sense_len);
 409                ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
 410                if (likely(ret == 0))
 411                        vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0);
 412                else
 413                        pr_err("Faulted on virtio_scsi_cmd_resp\n");
 414
 415                vhost_scsi_free_cmd(tv_cmd);
 416        }
 417
 418        vhost_signal(&vs->dev, &vs->vqs[2]);
 419}
 420
 421static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
 422        struct tcm_vhost_tpg *tv_tpg,
 423        struct virtio_scsi_cmd_req *v_req,
 424        u32 exp_data_len,
 425        int data_direction)
 426{
 427        struct tcm_vhost_cmd *tv_cmd;
 428        struct tcm_vhost_nexus *tv_nexus;
 429        struct se_portal_group *se_tpg = &tv_tpg->se_tpg;
 430        struct se_session *se_sess;
 431        struct se_cmd *se_cmd;
 432        int sam_task_attr;
 433
 434        tv_nexus = tv_tpg->tpg_nexus;
 435        if (!tv_nexus) {
 436                pr_err("Unable to locate active struct tcm_vhost_nexus\n");
 437                return ERR_PTR(-EIO);
 438        }
 439        se_sess = tv_nexus->tvn_se_sess;
 440
 441        tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC);
 442        if (!tv_cmd) {
 443                pr_err("Unable to allocate struct tcm_vhost_cmd\n");
 444                return ERR_PTR(-ENOMEM);
 445        }
 446        INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
 447        tv_cmd->tvc_tag = v_req->tag;
 448
 449        se_cmd = &tv_cmd->tvc_se_cmd;
 450        /*
 451         * Locate the SAM Task Attr from virtio_scsi_cmd_req
 452         */
 453        sam_task_attr = v_req->task_attr;
 454        /*
 455         * Initialize struct se_cmd descriptor from TCM infrastructure
 456         */
 457        transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len,
 458                                data_direction, sam_task_attr,
 459                                &tv_cmd->tvc_sense_buf[0]);
 460
 461#if 0   /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */
 462        if (bidi)
 463                se_cmd->se_cmd_flags |= SCF_BIDI;
 464#endif
 465        return tv_cmd;
 466}
 467
 468/*
 469 * Map a user memory range into a scatterlist
 470 *
 471 * Returns the number of scatterlist entries used or -errno on error.
 472 */
 473static int vhost_scsi_map_to_sgl(struct scatterlist *sgl,
 474        unsigned int sgl_count, void __user *ptr, size_t len, int write)
 475{
 476        struct scatterlist *sg = sgl;
 477        unsigned int npages = 0;
 478        int ret;
 479
 480        while (len > 0) {
 481                struct page *page;
 482                unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK;
 483                unsigned int nbytes = min_t(unsigned int,
 484                                PAGE_SIZE - offset, len);
 485
 486                if (npages == sgl_count) {
 487                        ret = -ENOBUFS;
 488                        goto err;
 489                }
 490
 491                ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page);
 492                BUG_ON(ret == 0); /* we should either get our page or fail */
 493                if (ret < 0)
 494                        goto err;
 495
 496                sg_set_page(sg, page, nbytes, offset);
 497                ptr += nbytes;
 498                len -= nbytes;
 499                sg++;
 500                npages++;
 501        }
 502        return npages;
 503
 504err:
 505        /* Put pages that we hold */
 506        for (sg = sgl; sg != &sgl[npages]; sg++)
 507                put_page(sg_page(sg));
 508        return ret;
 509}
 510
 511static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
 512        struct iovec *iov, unsigned int niov, int write)
 513{
 514        int ret;
 515        unsigned int i;
 516        u32 sgl_count;
 517        struct scatterlist *sg;
 518
 519        /*
 520         * Find out how long sglist needs to be
 521         */
 522        sgl_count = 0;
 523        for (i = 0; i < niov; i++) {
 524                sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len +
 525                                PAGE_SIZE - 1) >> PAGE_SHIFT) -
 526                                ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT);
 527        }
 528        /* TODO overflow checking */
 529
 530        sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC);
 531        if (!sg)
 532                return -ENOMEM;
 533        pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__,
 534               sg, sgl_count, !sg);
 535        sg_init_table(sg, sgl_count);
 536
 537        tv_cmd->tvc_sgl = sg;
 538        tv_cmd->tvc_sgl_count = sgl_count;
 539
 540        pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count);
 541        for (i = 0; i < niov; i++) {
 542                ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base,
 543                                        iov[i].iov_len, write);
 544                if (ret < 0) {
 545                        for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
 546                                put_page(sg_page(&tv_cmd->tvc_sgl[i]));
 547                        kfree(tv_cmd->tvc_sgl);
 548                        tv_cmd->tvc_sgl = NULL;
 549                        tv_cmd->tvc_sgl_count = 0;
 550                        return ret;
 551                }
 552
 553                sg += ret;
 554                sgl_count -= ret;
 555        }
 556        return 0;
 557}
 558
 559static void tcm_vhost_submission_work(struct work_struct *work)
 560{
 561        struct tcm_vhost_cmd *tv_cmd =
 562                container_of(work, struct tcm_vhost_cmd, work);
 563        struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 564        struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
 565        int rc, sg_no_bidi = 0;
 566        /*
 567         * Locate the struct se_lun pointer based on v_req->lun, and
 568         * attach it to struct se_cmd
 569         */
 570        rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun);
 571        if (rc < 0) {
 572                pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun);
 573                transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd,
 574                        tv_cmd->tvc_se_cmd.scsi_sense_reason, 0);
 575                transport_generic_free_cmd(se_cmd, 0);
 576                return;
 577        }
 578
 579        rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb);
 580        if (rc == -ENOMEM) {
 581                transport_send_check_condition_and_sense(se_cmd,
 582                                TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
 583                transport_generic_free_cmd(se_cmd, 0);
 584                return;
 585        } else if (rc < 0) {
 586                if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
 587                        tcm_vhost_queue_status(se_cmd);
 588                else
 589                        transport_send_check_condition_and_sense(se_cmd,
 590                                        se_cmd->scsi_sense_reason, 0);
 591                transport_generic_free_cmd(se_cmd, 0);
 592                return;
 593        }
 594
 595        if (tv_cmd->tvc_sgl_count) {
 596                sg_ptr = tv_cmd->tvc_sgl;
 597                /*
 598                 * For BIDI commands, pass in the extra READ buffer
 599                 * to transport_generic_map_mem_to_cmd() below..
 600                 */
 601/* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */
 602#if 0
 603                if (se_cmd->se_cmd_flags & SCF_BIDI) {
 604                        sg_bidi_ptr = NULL;
 605                        sg_no_bidi = 0;
 606                }
 607#endif
 608        } else {
 609                sg_ptr = NULL;
 610        }
 611
 612        rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr,
 613                                tv_cmd->tvc_sgl_count, sg_bidi_ptr,
 614                                sg_no_bidi);
 615        if (rc < 0) {
 616                transport_send_check_condition_and_sense(se_cmd,
 617                                se_cmd->scsi_sense_reason, 0);
 618                transport_generic_free_cmd(se_cmd, 0);
 619                return;
 620        }
 621        transport_handle_cdb_direct(se_cmd);
 622}
 623
 624static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
 625{
 626        struct vhost_virtqueue *vq = &vs->vqs[2];
 627        struct virtio_scsi_cmd_req v_req;
 628        struct tcm_vhost_tpg *tv_tpg;
 629        struct tcm_vhost_cmd *tv_cmd;
 630        u32 exp_data_len, data_first, data_num, data_direction;
 631        unsigned out, in, i;
 632        int head, ret;
 633
 634        /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
 635        tv_tpg = vs->vs_tpg;
 636        if (unlikely(!tv_tpg)) {
 637                pr_err("%s endpoint not set\n", __func__);
 638                return;
 639        }
 640
 641        mutex_lock(&vq->mutex);
 642        vhost_disable_notify(&vs->dev, vq);
 643
 644        for (;;) {
 645                head = vhost_get_vq_desc(&vs->dev, vq, vq->iov,
 646                                        ARRAY_SIZE(vq->iov), &out, &in,
 647                                        NULL, NULL);
 648                pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n",
 649                                        head, out, in);
 650                /* On error, stop handling until the next kick. */
 651                if (unlikely(head < 0))
 652                        break;
 653                /* Nothing new?  Wait for eventfd to tell us they refilled. */
 654                if (head == vq->num) {
 655                        if (unlikely(vhost_enable_notify(&vs->dev, vq))) {
 656                                vhost_disable_notify(&vs->dev, vq);
 657                                continue;
 658                        }
 659                        break;
 660                }
 661
 662/* FIXME: BIDI operation */
 663                if (out == 1 && in == 1) {
 664                        data_direction = DMA_NONE;
 665                        data_first = 0;
 666                        data_num = 0;
 667                } else if (out == 1 && in > 1) {
 668                        data_direction = DMA_FROM_DEVICE;
 669                        data_first = out + 1;
 670                        data_num = in - 1;
 671                } else if (out > 1 && in == 1) {
 672                        data_direction = DMA_TO_DEVICE;
 673                        data_first = 1;
 674                        data_num = out - 1;
 675                } else {
 676                        vq_err(vq, "Invalid buffer layout out: %u in: %u\n",
 677                                        out, in);
 678                        break;
 679                }
 680
 681                /*
 682                 * Check for a sane resp buffer so we can report errors to
 683                 * the guest.
 684                 */
 685                if (unlikely(vq->iov[out].iov_len !=
 686                                        sizeof(struct virtio_scsi_cmd_resp))) {
 687                        vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
 688                                " bytes\n", vq->iov[out].iov_len);
 689                        break;
 690                }
 691
 692                if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) {
 693                        vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu"
 694                                " bytes\n", vq->iov[0].iov_len);
 695                        break;
 696                }
 697                pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p,"
 698                        " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req));
 699                ret = __copy_from_user(&v_req, vq->iov[0].iov_base,
 700                                sizeof(v_req));
 701                if (unlikely(ret)) {
 702                        vq_err(vq, "Faulted on virtio_scsi_cmd_req\n");
 703                        break;
 704                }
 705
 706                exp_data_len = 0;
 707                for (i = 0; i < data_num; i++)
 708                        exp_data_len += vq->iov[data_first + i].iov_len;
 709
 710                tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req,
 711                                        exp_data_len, data_direction);
 712                if (IS_ERR(tv_cmd)) {
 713                        vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
 714                                        PTR_ERR(tv_cmd));
 715                        break;
 716                }
 717                pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction"
 718                        ": %d\n", tv_cmd, exp_data_len, data_direction);
 719
 720                tv_cmd->tvc_vhost = vs;
 721
 722                if (unlikely(vq->iov[out].iov_len !=
 723                                sizeof(struct virtio_scsi_cmd_resp))) {
 724                        vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
 725                                " bytes, out: %d, in: %d\n",
 726                                vq->iov[out].iov_len, out, in);
 727                        break;
 728                }
 729
 730                tv_cmd->tvc_resp = vq->iov[out].iov_base;
 731
 732                /*
 733                 * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb
 734                 * that will be used by tcm_vhost_new_cmd_map() and down into
 735                 * target_setup_cmd_from_cdb()
 736                 */
 737                memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE);
 738                /*
 739                 * Check that the recieved CDB size does not exceeded our
 740                 * hardcoded max for tcm_vhost
 741                 */
 742                /* TODO what if cdb was too small for varlen cdb header? */
 743                if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) >
 744                                        TCM_VHOST_MAX_CDB_SIZE)) {
 745                        vq_err(vq, "Received SCSI CDB with command_size: %d that"
 746                                " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
 747                                scsi_command_size(tv_cmd->tvc_cdb),
 748                                TCM_VHOST_MAX_CDB_SIZE);
 749                        break; /* TODO */
 750                }
 751                tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF;
 752
 753                pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
 754                        tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun);
 755
 756                if (data_direction != DMA_NONE) {
 757                        ret = vhost_scsi_map_iov_to_sgl(tv_cmd,
 758                                        &vq->iov[data_first], data_num,
 759                                        data_direction == DMA_TO_DEVICE);
 760                        if (unlikely(ret)) {
 761                                vq_err(vq, "Failed to map iov to sgl\n");
 762                                break; /* TODO */
 763                        }
 764                }
 765
 766                /*
 767                 * Save the descriptor from vhost_get_vq_desc() to be used to
 768                 * complete the virtio-scsi request in TCM callback context via
 769                 * tcm_vhost_queue_data_in() and tcm_vhost_queue_status()
 770                 */
 771                tv_cmd->tvc_vq_desc = head;
 772                /*
 773                 * Dispatch tv_cmd descriptor for cmwq execution in process
 774                 * context provided by tcm_vhost_workqueue.  This also ensures
 775                 * tv_cmd is executed on the same kworker CPU as this vhost
 776                 * thread to gain positive L2 cache locality effects..
 777                 */
 778                INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work);
 779                queue_work(tcm_vhost_workqueue, &tv_cmd->work);
 780        }
 781
 782        mutex_unlock(&vq->mutex);
 783}
 784
 785static void vhost_scsi_ctl_handle_kick(struct vhost_work *work)
 786{
 787        pr_debug("%s: The handling func for control queue.\n", __func__);
 788}
 789
 790static void vhost_scsi_evt_handle_kick(struct vhost_work *work)
 791{
 792        pr_debug("%s: The handling func for event queue.\n", __func__);
 793}
 794
 795static void vhost_scsi_handle_kick(struct vhost_work *work)
 796{
 797        struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
 798                                                poll.work);
 799        struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
 800
 801        vhost_scsi_handle_vq(vs);
 802}
 803
 804/*
 805 * Called from vhost_scsi_ioctl() context to walk the list of available
 806 * tcm_vhost_tpg with an active struct tcm_vhost_nexus
 807 */
 808static int vhost_scsi_set_endpoint(
 809        struct vhost_scsi *vs,
 810        struct vhost_scsi_target *t)
 811{
 812        struct tcm_vhost_tport *tv_tport;
 813        struct tcm_vhost_tpg *tv_tpg;
 814        int index;
 815
 816        mutex_lock(&vs->dev.mutex);
 817        /* Verify that ring has been setup correctly. */
 818        for (index = 0; index < vs->dev.nvqs; ++index) {
 819                /* Verify that ring has been setup correctly. */
 820                if (!vhost_vq_access_ok(&vs->vqs[index])) {
 821                        mutex_unlock(&vs->dev.mutex);
 822                        return -EFAULT;
 823                }
 824        }
 825        mutex_unlock(&vs->dev.mutex);
 826
 827        mutex_lock(&tcm_vhost_mutex);
 828        list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
 829                mutex_lock(&tv_tpg->tv_tpg_mutex);
 830                if (!tv_tpg->tpg_nexus) {
 831                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 832                        continue;
 833                }
 834                if (tv_tpg->tv_tpg_vhost_count != 0) {
 835                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 836                        continue;
 837                }
 838                tv_tport = tv_tpg->tport;
 839
 840                if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) &&
 841                    (tv_tpg->tport_tpgt == t->vhost_tpgt)) {
 842                        tv_tpg->tv_tpg_vhost_count++;
 843                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 844                        mutex_unlock(&tcm_vhost_mutex);
 845
 846                        mutex_lock(&vs->dev.mutex);
 847                        if (vs->vs_tpg) {
 848                                mutex_unlock(&vs->dev.mutex);
 849                                mutex_lock(&tv_tpg->tv_tpg_mutex);
 850                                tv_tpg->tv_tpg_vhost_count--;
 851                                mutex_unlock(&tv_tpg->tv_tpg_mutex);
 852                                return -EEXIST;
 853                        }
 854
 855                        vs->vs_tpg = tv_tpg;
 856                        smp_mb__after_atomic_inc();
 857                        mutex_unlock(&vs->dev.mutex);
 858                        return 0;
 859                }
 860                mutex_unlock(&tv_tpg->tv_tpg_mutex);
 861        }
 862        mutex_unlock(&tcm_vhost_mutex);
 863        return -EINVAL;
 864}
 865
 866static int vhost_scsi_clear_endpoint(
 867        struct vhost_scsi *vs,
 868        struct vhost_scsi_target *t)
 869{
 870        struct tcm_vhost_tport *tv_tport;
 871        struct tcm_vhost_tpg *tv_tpg;
 872        int index, ret;
 873
 874        mutex_lock(&vs->dev.mutex);
 875        /* Verify that ring has been setup correctly. */
 876        for (index = 0; index < vs->dev.nvqs; ++index) {
 877                if (!vhost_vq_access_ok(&vs->vqs[index])) {
 878                        ret = -EFAULT;
 879                        goto err;
 880                }
 881        }
 882
 883        if (!vs->vs_tpg) {
 884                ret = -ENODEV;
 885                goto err;
 886        }
 887        tv_tpg = vs->vs_tpg;
 888        tv_tport = tv_tpg->tport;
 889
 890        if (strcmp(tv_tport->tport_name, t->vhost_wwpn) ||
 891            (tv_tpg->tport_tpgt != t->vhost_tpgt)) {
 892                pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu"
 893                        " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n",
 894                        tv_tport->tport_name, tv_tpg->tport_tpgt,
 895                        t->vhost_wwpn, t->vhost_tpgt);
 896                ret = -EINVAL;
 897                goto err;
 898        }
 899        tv_tpg->tv_tpg_vhost_count--;
 900        vs->vs_tpg = NULL;
 901        mutex_unlock(&vs->dev.mutex);
 902
 903        return 0;
 904
 905err:
 906        mutex_unlock(&vs->dev.mutex);
 907        return ret;
 908}
 909
 910static int vhost_scsi_open(struct inode *inode, struct file *f)
 911{
 912        struct vhost_scsi *s;
 913        int r;
 914
 915        s = kzalloc(sizeof(*s), GFP_KERNEL);
 916        if (!s)
 917                return -ENOMEM;
 918
 919        vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
 920        INIT_LIST_HEAD(&s->vs_completion_list);
 921        spin_lock_init(&s->vs_completion_lock);
 922
 923        s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick;
 924        s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick;
 925        s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick;
 926        r = vhost_dev_init(&s->dev, s->vqs, 3);
 927        if (r < 0) {
 928                kfree(s);
 929                return r;
 930        }
 931
 932        f->private_data = s;
 933        return 0;
 934}
 935
 936static int vhost_scsi_release(struct inode *inode, struct file *f)
 937{
 938        struct vhost_scsi *s = f->private_data;
 939
 940        if (s->vs_tpg && s->vs_tpg->tport) {
 941                struct vhost_scsi_target backend;
 942
 943                memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name,
 944                                sizeof(backend.vhost_wwpn));
 945                backend.vhost_tpgt = s->vs_tpg->tport_tpgt;
 946                vhost_scsi_clear_endpoint(s, &backend);
 947        }
 948
 949        vhost_dev_cleanup(&s->dev, false);
 950        kfree(s);
 951        return 0;
 952}
 953
 954static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
 955{
 956        vhost_poll_flush(&vs->dev.vqs[index].poll);
 957}
 958
 959static void vhost_scsi_flush(struct vhost_scsi *vs)
 960{
 961        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL);
 962        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT);
 963        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO);
 964}
 965
 966static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 967{
 968        if (features & ~VHOST_FEATURES)
 969                return -EOPNOTSUPP;
 970
 971        mutex_lock(&vs->dev.mutex);
 972        if ((features & (1 << VHOST_F_LOG_ALL)) &&
 973            !vhost_log_access_ok(&vs->dev)) {
 974                mutex_unlock(&vs->dev.mutex);
 975                return -EFAULT;
 976        }
 977        vs->dev.acked_features = features;
 978        smp_wmb();
 979        vhost_scsi_flush(vs);
 980        mutex_unlock(&vs->dev.mutex);
 981        return 0;
 982}
 983
 984static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,
 985                                unsigned long arg)
 986{
 987        struct vhost_scsi *vs = f->private_data;
 988        struct vhost_scsi_target backend;
 989        void __user *argp = (void __user *)arg;
 990        u64 __user *featurep = argp;
 991        u64 features;
 992        int r, abi_version = VHOST_SCSI_ABI_VERSION;
 993
 994        switch (ioctl) {
 995        case VHOST_SCSI_SET_ENDPOINT:
 996                if (copy_from_user(&backend, argp, sizeof backend))
 997                        return -EFAULT;
 998                if (backend.reserved != 0)
 999                        return -EOPNOTSUPP;
1000
1001                return vhost_scsi_set_endpoint(vs, &backend);
1002        case VHOST_SCSI_CLEAR_ENDPOINT:
1003                if (copy_from_user(&backend, argp, sizeof backend))
1004                        return -EFAULT;
1005                if (backend.reserved != 0)
1006                        return -EOPNOTSUPP;
1007
1008                return vhost_scsi_clear_endpoint(vs, &backend);
1009        case VHOST_SCSI_GET_ABI_VERSION:
1010                if (copy_to_user(argp, &abi_version, sizeof abi_version))
1011                        return -EFAULT;
1012                return 0;
1013        case VHOST_GET_FEATURES:
1014                features = VHOST_FEATURES;
1015                if (copy_to_user(featurep, &features, sizeof features))
1016                        return -EFAULT;
1017                return 0;
1018        case VHOST_SET_FEATURES:
1019                if (copy_from_user(&features, featurep, sizeof features))
1020                        return -EFAULT;
1021                return vhost_scsi_set_features(vs, features);
1022        default:
1023                mutex_lock(&vs->dev.mutex);
1024                r = vhost_dev_ioctl(&vs->dev, ioctl, arg);
1025                mutex_unlock(&vs->dev.mutex);
1026                return r;
1027        }
1028}
1029
1030#ifdef CONFIG_COMPAT
1031static long vhost_scsi_compat_ioctl(struct file *f, unsigned int ioctl,
1032                                unsigned long arg)
1033{
1034        return vhost_scsi_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
1035}
1036#endif
1037
1038static const struct file_operations vhost_scsi_fops = {
1039        .owner          = THIS_MODULE,
1040        .release        = vhost_scsi_release,
1041        .unlocked_ioctl = vhost_scsi_ioctl,
1042#ifdef CONFIG_COMPAT
1043        .compat_ioctl   = vhost_scsi_compat_ioctl,
1044#endif
1045        .open           = vhost_scsi_open,
1046        .llseek         = noop_llseek,
1047};
1048
1049static struct miscdevice vhost_scsi_misc = {
1050        MISC_DYNAMIC_MINOR,
1051        "vhost-scsi",
1052        &vhost_scsi_fops,
1053};
1054
1055static int __init vhost_scsi_register(void)
1056{
1057        return misc_register(&vhost_scsi_misc);
1058}
1059
1060static int vhost_scsi_deregister(void)
1061{
1062        return misc_deregister(&vhost_scsi_misc);
1063}
1064
1065static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport)
1066{
1067        switch (tport->tport_proto_id) {
1068        case SCSI_PROTOCOL_SAS:
1069                return "SAS";
1070        case SCSI_PROTOCOL_FCP:
1071                return "FCP";
1072        case SCSI_PROTOCOL_ISCSI:
1073                return "iSCSI";
1074        default:
1075                break;
1076        }
1077
1078        return "Unknown";
1079}
1080
1081static int tcm_vhost_port_link(struct se_portal_group *se_tpg,
1082        struct se_lun *lun)
1083{
1084        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1085                                struct tcm_vhost_tpg, se_tpg);
1086
1087        mutex_lock(&tv_tpg->tv_tpg_mutex);
1088        tv_tpg->tv_tpg_port_count++;
1089        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1090
1091        return 0;
1092}
1093
1094static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg,
1095        struct se_lun *se_lun)
1096{
1097        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1098                                struct tcm_vhost_tpg, se_tpg);
1099
1100        mutex_lock(&tv_tpg->tv_tpg_mutex);
1101        tv_tpg->tv_tpg_port_count--;
1102        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1103}
1104
1105static struct se_node_acl *tcm_vhost_make_nodeacl(
1106        struct se_portal_group *se_tpg,
1107        struct config_group *group,
1108        const char *name)
1109{
1110        struct se_node_acl *se_nacl, *se_nacl_new;
1111        struct tcm_vhost_nacl *nacl;
1112        u64 wwpn = 0;
1113        u32 nexus_depth;
1114
1115        /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
1116                return ERR_PTR(-EINVAL); */
1117        se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg);
1118        if (!se_nacl_new)
1119                return ERR_PTR(-ENOMEM);
1120
1121        nexus_depth = 1;
1122        /*
1123         * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
1124         * when converting a NodeACL from demo mode -> explict
1125         */
1126        se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
1127                                name, nexus_depth);
1128        if (IS_ERR(se_nacl)) {
1129                tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new);
1130                return se_nacl;
1131        }
1132        /*
1133         * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN
1134         */
1135        nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl);
1136        nacl->iport_wwpn = wwpn;
1137
1138        return se_nacl;
1139}
1140
1141static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl)
1142{
1143        struct tcm_vhost_nacl *nacl = container_of(se_acl,
1144                                struct tcm_vhost_nacl, se_node_acl);
1145        core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);
1146        kfree(nacl);
1147}
1148
1149static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg,
1150        const char *name)
1151{
1152        struct se_portal_group *se_tpg;
1153        struct tcm_vhost_nexus *tv_nexus;
1154
1155        mutex_lock(&tv_tpg->tv_tpg_mutex);
1156        if (tv_tpg->tpg_nexus) {
1157                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1158                pr_debug("tv_tpg->tpg_nexus already exists\n");
1159                return -EEXIST;
1160        }
1161        se_tpg = &tv_tpg->se_tpg;
1162
1163        tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL);
1164        if (!tv_nexus) {
1165                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1166                pr_err("Unable to allocate struct tcm_vhost_nexus\n");
1167                return -ENOMEM;
1168        }
1169        /*
1170         *  Initialize the struct se_session pointer
1171         */
1172        tv_nexus->tvn_se_sess = transport_init_session();
1173        if (IS_ERR(tv_nexus->tvn_se_sess)) {
1174                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1175                kfree(tv_nexus);
1176                return -ENOMEM;
1177        }
1178        /*
1179         * Since we are running in 'demo mode' this call with generate a
1180         * struct se_node_acl for the tcm_vhost struct se_portal_group with
1181         * the SCSI Initiator port name of the passed configfs group 'name'.
1182         */
1183        tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
1184                                se_tpg, (unsigned char *)name);
1185        if (!tv_nexus->tvn_se_sess->se_node_acl) {
1186                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1187                pr_debug("core_tpg_check_initiator_node_acl() failed"
1188                                " for %s\n", name);
1189                transport_free_session(tv_nexus->tvn_se_sess);
1190                kfree(tv_nexus);
1191                return -ENOMEM;
1192        }
1193        /*
1194         * Now register the TCM vhost virtual I_T Nexus as active with the
1195         * call to __transport_register_session()
1196         */
1197        __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
1198                        tv_nexus->tvn_se_sess, tv_nexus);
1199        tv_tpg->tpg_nexus = tv_nexus;
1200
1201        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1202        return 0;
1203}
1204
1205static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg)
1206{
1207        struct se_session *se_sess;
1208        struct tcm_vhost_nexus *tv_nexus;
1209
1210        mutex_lock(&tpg->tv_tpg_mutex);
1211        tv_nexus = tpg->tpg_nexus;
1212        if (!tv_nexus) {
1213                mutex_unlock(&tpg->tv_tpg_mutex);
1214                return -ENODEV;
1215        }
1216
1217        se_sess = tv_nexus->tvn_se_sess;
1218        if (!se_sess) {
1219                mutex_unlock(&tpg->tv_tpg_mutex);
1220                return -ENODEV;
1221        }
1222
1223        if (tpg->tv_tpg_port_count != 0) {
1224                mutex_unlock(&tpg->tv_tpg_mutex);
1225                pr_err("Unable to remove TCM_vhost I_T Nexus with"
1226                        " active TPG port count: %d\n",
1227                        tpg->tv_tpg_port_count);
1228                return -EBUSY;
1229        }
1230
1231        if (tpg->tv_tpg_vhost_count != 0) {
1232                mutex_unlock(&tpg->tv_tpg_mutex);
1233                pr_err("Unable to remove TCM_vhost I_T Nexus with"
1234                        " active TPG vhost count: %d\n",
1235                        tpg->tv_tpg_vhost_count);
1236                return -EBUSY;
1237        }
1238
1239        pr_debug("TCM_vhost_ConfigFS: Removing I_T Nexus to emulated"
1240                " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport),
1241                tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
1242        /*
1243         * Release the SCSI I_T Nexus to the emulated vhost Target Port
1244         */
1245        transport_deregister_session(tv_nexus->tvn_se_sess);
1246        tpg->tpg_nexus = NULL;
1247        mutex_unlock(&tpg->tv_tpg_mutex);
1248
1249        kfree(tv_nexus);
1250        return 0;
1251}
1252
1253static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg,
1254        char *page)
1255{
1256        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1257                                struct tcm_vhost_tpg, se_tpg);
1258        struct tcm_vhost_nexus *tv_nexus;
1259        ssize_t ret;
1260
1261        mutex_lock(&tv_tpg->tv_tpg_mutex);
1262        tv_nexus = tv_tpg->tpg_nexus;
1263        if (!tv_nexus) {
1264                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1265                return -ENODEV;
1266        }
1267        ret = snprintf(page, PAGE_SIZE, "%s\n",
1268                        tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
1269        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1270
1271        return ret;
1272}
1273
1274static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg,
1275        const char *page,
1276        size_t count)
1277{
1278        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1279                                struct tcm_vhost_tpg, se_tpg);
1280        struct tcm_vhost_tport *tport_wwn = tv_tpg->tport;
1281        unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr;
1282        int ret;
1283        /*
1284         * Shutdown the active I_T nexus if 'NULL' is passed..
1285         */
1286        if (!strncmp(page, "NULL", 4)) {
1287                ret = tcm_vhost_drop_nexus(tv_tpg);
1288                return (!ret) ? count : ret;
1289        }
1290        /*
1291         * Otherwise make sure the passed virtual Initiator port WWN matches
1292         * the fabric protocol_id set in tcm_vhost_make_tport(), and call
1293         * tcm_vhost_make_nexus().
1294         */
1295        if (strlen(page) >= TCM_VHOST_NAMELEN) {
1296                pr_err("Emulated NAA Sas Address: %s, exceeds"
1297                                " max: %d\n", page, TCM_VHOST_NAMELEN);
1298                return -EINVAL;
1299        }
1300        snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page);
1301
1302        ptr = strstr(i_port, "naa.");
1303        if (ptr) {
1304                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {
1305                        pr_err("Passed SAS Initiator Port %s does not"
1306                                " match target port protoid: %s\n", i_port,
1307                                tcm_vhost_dump_proto_id(tport_wwn));
1308                        return -EINVAL;
1309                }
1310                port_ptr = &i_port[0];
1311                goto check_newline;
1312        }
1313        ptr = strstr(i_port, "fc.");
1314        if (ptr) {
1315                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {
1316                        pr_err("Passed FCP Initiator Port %s does not"
1317                                " match target port protoid: %s\n", i_port,
1318                                tcm_vhost_dump_proto_id(tport_wwn));
1319                        return -EINVAL;
1320                }
1321                port_ptr = &i_port[3]; /* Skip over "fc." */
1322                goto check_newline;
1323        }
1324        ptr = strstr(i_port, "iqn.");
1325        if (ptr) {
1326                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {
1327                        pr_err("Passed iSCSI Initiator Port %s does not"
1328                                " match target port protoid: %s\n", i_port,
1329                                tcm_vhost_dump_proto_id(tport_wwn));
1330                        return -EINVAL;
1331                }
1332                port_ptr = &i_port[0];
1333                goto check_newline;
1334        }
1335        pr_err("Unable to locate prefix for emulated Initiator Port:"
1336                        " %s\n", i_port);
1337        return -EINVAL;
1338        /*
1339         * Clear any trailing newline for the NAA WWN
1340         */
1341check_newline:
1342        if (i_port[strlen(i_port)-1] == '\n')
1343                i_port[strlen(i_port)-1] = '\0';
1344
1345        ret = tcm_vhost_make_nexus(tv_tpg, port_ptr);
1346        if (ret < 0)
1347                return ret;
1348
1349        return count;
1350}
1351
1352TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR);
1353
1354static struct configfs_attribute *tcm_vhost_tpg_attrs[] = {
1355        &tcm_vhost_tpg_nexus.attr,
1356        NULL,
1357};
1358
1359static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn,
1360        struct config_group *group,
1361        const char *name)
1362{
1363        struct tcm_vhost_tport *tport = container_of(wwn,
1364                        struct tcm_vhost_tport, tport_wwn);
1365
1366        struct tcm_vhost_tpg *tpg;
1367        unsigned long tpgt;
1368        int ret;
1369
1370        if (strstr(name, "tpgt_") != name)
1371                return ERR_PTR(-EINVAL);
1372        if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)
1373                return ERR_PTR(-EINVAL);
1374
1375        tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL);
1376        if (!tpg) {
1377                pr_err("Unable to allocate struct tcm_vhost_tpg");
1378                return ERR_PTR(-ENOMEM);
1379        }
1380        mutex_init(&tpg->tv_tpg_mutex);
1381        INIT_LIST_HEAD(&tpg->tv_tpg_list);
1382        tpg->tport = tport;
1383        tpg->tport_tpgt = tpgt;
1384
1385        ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn,
1386                                &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL);
1387        if (ret < 0) {
1388                kfree(tpg);
1389                return NULL;
1390        }
1391        mutex_lock(&tcm_vhost_mutex);
1392        list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list);
1393        mutex_unlock(&tcm_vhost_mutex);
1394
1395        return &tpg->se_tpg;
1396}
1397
1398static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg)
1399{
1400        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
1401                                struct tcm_vhost_tpg, se_tpg);
1402
1403        mutex_lock(&tcm_vhost_mutex);
1404        list_del(&tpg->tv_tpg_list);
1405        mutex_unlock(&tcm_vhost_mutex);
1406        /*
1407         * Release the virtual I_T Nexus for this vhost TPG
1408         */
1409        tcm_vhost_drop_nexus(tpg);
1410        /*
1411         * Deregister the se_tpg from TCM..
1412         */
1413        core_tpg_deregister(se_tpg);
1414        kfree(tpg);
1415}
1416
1417static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf,
1418        struct config_group *group,
1419        const char *name)
1420{
1421        struct tcm_vhost_tport *tport;
1422        char *ptr;
1423        u64 wwpn = 0;
1424        int off = 0;
1425
1426        /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
1427                return ERR_PTR(-EINVAL); */
1428
1429        tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL);
1430        if (!tport) {
1431                pr_err("Unable to allocate struct tcm_vhost_tport");
1432                return ERR_PTR(-ENOMEM);
1433        }
1434        tport->tport_wwpn = wwpn;
1435        /*
1436         * Determine the emulated Protocol Identifier and Target Port Name
1437         * based on the incoming configfs directory name.
1438         */
1439        ptr = strstr(name, "naa.");
1440        if (ptr) {
1441                tport->tport_proto_id = SCSI_PROTOCOL_SAS;
1442                goto check_len;
1443        }
1444        ptr = strstr(name, "fc.");
1445        if (ptr) {
1446                tport->tport_proto_id = SCSI_PROTOCOL_FCP;
1447                off = 3; /* Skip over "fc." */
1448                goto check_len;
1449        }
1450        ptr = strstr(name, "iqn.");
1451        if (ptr) {
1452                tport->tport_proto_id = SCSI_PROTOCOL_ISCSI;
1453                goto check_len;
1454        }
1455
1456        pr_err("Unable to locate prefix for emulated Target Port:"
1457                        " %s\n", name);
1458        kfree(tport);
1459        return ERR_PTR(-EINVAL);
1460
1461check_len:
1462        if (strlen(name) >= TCM_VHOST_NAMELEN) {
1463                pr_err("Emulated %s Address: %s, exceeds"
1464                        " max: %d\n", name, tcm_vhost_dump_proto_id(tport),
1465                        TCM_VHOST_NAMELEN);
1466                kfree(tport);
1467                return ERR_PTR(-EINVAL);
1468        }
1469        snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]);
1470
1471        pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target"
1472                " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name);
1473
1474        return &tport->tport_wwn;
1475}
1476
1477static void tcm_vhost_drop_tport(struct se_wwn *wwn)
1478{
1479        struct tcm_vhost_tport *tport = container_of(wwn,
1480                                struct tcm_vhost_tport, tport_wwn);
1481
1482        pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target"
1483                " %s Address: %s\n", tcm_vhost_dump_proto_id(tport),
1484                tport->tport_name);
1485
1486        kfree(tport);
1487}
1488
1489static ssize_t tcm_vhost_wwn_show_attr_version(
1490        struct target_fabric_configfs *tf,
1491        char *page)
1492{
1493        return sprintf(page, "TCM_VHOST fabric module %s on %s/%s"
1494                "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
1495                utsname()->machine);
1496}
1497
1498TF_WWN_ATTR_RO(tcm_vhost, version);
1499
1500static struct configfs_attribute *tcm_vhost_wwn_attrs[] = {
1501        &tcm_vhost_wwn_version.attr,
1502        NULL,
1503};
1504
1505static struct target_core_fabric_ops tcm_vhost_ops = {
1506        .get_fabric_name                = tcm_vhost_get_fabric_name,
1507        .get_fabric_proto_ident         = tcm_vhost_get_fabric_proto_ident,
1508        .tpg_get_wwn                    = tcm_vhost_get_fabric_wwn,
1509        .tpg_get_tag                    = tcm_vhost_get_tag,
1510        .tpg_get_default_depth          = tcm_vhost_get_default_depth,
1511        .tpg_get_pr_transport_id        = tcm_vhost_get_pr_transport_id,
1512        .tpg_get_pr_transport_id_len    = tcm_vhost_get_pr_transport_id_len,
1513        .tpg_parse_pr_out_transport_id  = tcm_vhost_parse_pr_out_transport_id,
1514        .tpg_check_demo_mode            = tcm_vhost_check_true,
1515        .tpg_check_demo_mode_cache      = tcm_vhost_check_true,
1516        .tpg_check_demo_mode_write_protect = tcm_vhost_check_false,
1517        .tpg_check_prod_mode_write_protect = tcm_vhost_check_false,
1518        .tpg_alloc_fabric_acl           = tcm_vhost_alloc_fabric_acl,
1519        .tpg_release_fabric_acl         = tcm_vhost_release_fabric_acl,
1520        .tpg_get_inst_index             = tcm_vhost_tpg_get_inst_index,
1521        .release_cmd                    = tcm_vhost_release_cmd,
1522        .shutdown_session               = tcm_vhost_shutdown_session,
1523        .close_session                  = tcm_vhost_close_session,
1524        .sess_get_index                 = tcm_vhost_sess_get_index,
1525        .sess_get_initiator_sid         = NULL,
1526        .write_pending                  = tcm_vhost_write_pending,
1527        .write_pending_status           = tcm_vhost_write_pending_status,
1528        .set_default_node_attributes    = tcm_vhost_set_default_node_attrs,
1529        .get_task_tag                   = tcm_vhost_get_task_tag,
1530        .get_cmd_state                  = tcm_vhost_get_cmd_state,
1531        .queue_data_in                  = tcm_vhost_queue_data_in,
1532        .queue_status                   = tcm_vhost_queue_status,
1533        .queue_tm_rsp                   = tcm_vhost_queue_tm_rsp,
1534        .get_fabric_sense_len           = tcm_vhost_get_fabric_sense_len,
1535        .set_fabric_sense_len           = tcm_vhost_set_fabric_sense_len,
1536        /*
1537         * Setup callers for generic logic in target_core_fabric_configfs.c
1538         */
1539        .fabric_make_wwn                = tcm_vhost_make_tport,
1540        .fabric_drop_wwn                = tcm_vhost_drop_tport,
1541        .fabric_make_tpg                = tcm_vhost_make_tpg,
1542        .fabric_drop_tpg                = tcm_vhost_drop_tpg,
1543        .fabric_post_link               = tcm_vhost_port_link,
1544        .fabric_pre_unlink              = tcm_vhost_port_unlink,
1545        .fabric_make_np                 = NULL,
1546        .fabric_drop_np                 = NULL,
1547        .fabric_make_nodeacl            = tcm_vhost_make_nodeacl,
1548        .fabric_drop_nodeacl            = tcm_vhost_drop_nodeacl,
1549};
1550
1551static int tcm_vhost_register_configfs(void)
1552{
1553        struct target_fabric_configfs *fabric;
1554        int ret;
1555
1556        pr_debug("TCM_VHOST fabric module %s on %s/%s"
1557                " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
1558                utsname()->machine);
1559        /*
1560         * Register the top level struct config_item_type with TCM core
1561         */
1562        fabric = target_fabric_configfs_init(THIS_MODULE, "vhost");
1563        if (IS_ERR(fabric)) {
1564                pr_err("target_fabric_configfs_init() failed\n");
1565                return PTR_ERR(fabric);
1566        }
1567        /*
1568         * Setup fabric->tf_ops from our local tcm_vhost_ops
1569         */
1570        fabric->tf_ops = tcm_vhost_ops;
1571        /*
1572         * Setup default attribute lists for various fabric->tf_cit_tmpl
1573         */
1574        TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs;
1575        TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs;
1576        TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
1577        TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
1578        TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
1579        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;
1580        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
1581        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
1582        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
1583        /*
1584         * Register the fabric for use within TCM
1585         */
1586        ret = target_fabric_configfs_register(fabric);
1587        if (ret < 0) {
1588                pr_err("target_fabric_configfs_register() failed"
1589                                " for TCM_VHOST\n");
1590                return ret;
1591        }
1592        /*
1593         * Setup our local pointer to *fabric
1594         */
1595        tcm_vhost_fabric_configfs = fabric;
1596        pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n");
1597        return 0;
1598};
1599
1600static void tcm_vhost_deregister_configfs(void)
1601{
1602        if (!tcm_vhost_fabric_configfs)
1603                return;
1604
1605        target_fabric_configfs_deregister(tcm_vhost_fabric_configfs);
1606        tcm_vhost_fabric_configfs = NULL;
1607        pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n");
1608};
1609
1610static int __init tcm_vhost_init(void)
1611{
1612        int ret = -ENOMEM;
1613        /*
1614         * Use our own dedicated workqueue for submitting I/O into
1615         * target core to avoid contention within system_wq.
1616         */
1617        tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0);
1618        if (!tcm_vhost_workqueue)
1619                goto out;
1620
1621        ret = vhost_scsi_register();
1622        if (ret < 0)
1623                goto out_destroy_workqueue;
1624
1625        ret = tcm_vhost_register_configfs();
1626        if (ret < 0)
1627                goto out_vhost_scsi_deregister;
1628
1629        return 0;
1630
1631out_vhost_scsi_deregister:
1632        vhost_scsi_deregister();
1633out_destroy_workqueue:
1634        destroy_workqueue(tcm_vhost_workqueue);
1635out:
1636        return ret;
1637};
1638
1639static void tcm_vhost_exit(void)
1640{
1641        tcm_vhost_deregister_configfs();
1642        vhost_scsi_deregister();
1643        destroy_workqueue(tcm_vhost_workqueue);
1644};
1645
1646MODULE_DESCRIPTION("TCM_VHOST series fabric driver");
1647MODULE_LICENSE("GPL");
1648module_init(tcm_vhost_init);
1649module_exit(tcm_vhost_exit);
1650
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.