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