linux/drivers/target/iscsi/iscsi_target_tpg.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * This file contains iSCSI Target Portal Group related functions.
   3 *
   4 * (c) Copyright 2007-2013 Datera, Inc.
   5 *
   6 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 ******************************************************************************/
  18
  19#include <target/target_core_base.h>
  20#include <target/target_core_fabric.h>
  21#include <target/target_core_configfs.h>
  22
  23#include "iscsi_target_core.h"
  24#include "iscsi_target_erl0.h"
  25#include "iscsi_target_login.h"
  26#include "iscsi_target_nodeattrib.h"
  27#include "iscsi_target_tpg.h"
  28#include "iscsi_target_util.h"
  29#include "iscsi_target.h"
  30#include "iscsi_target_parameters.h"
  31
  32#include <target/iscsi/iscsi_transport.h>
  33
  34struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
  35{
  36        struct iscsi_portal_group *tpg;
  37
  38        tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
  39        if (!tpg) {
  40                pr_err("Unable to allocate struct iscsi_portal_group\n");
  41                return NULL;
  42        }
  43
  44        tpg->tpgt = tpgt;
  45        tpg->tpg_state = TPG_STATE_FREE;
  46        tpg->tpg_tiqn = tiqn;
  47        INIT_LIST_HEAD(&tpg->tpg_gnp_list);
  48        INIT_LIST_HEAD(&tpg->tpg_list);
  49        mutex_init(&tpg->tpg_access_lock);
  50        sema_init(&tpg->np_login_sem, 1);
  51        spin_lock_init(&tpg->tpg_state_lock);
  52        spin_lock_init(&tpg->tpg_np_lock);
  53
  54        return tpg;
  55}
  56
  57static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
  58
  59int iscsit_load_discovery_tpg(void)
  60{
  61        struct iscsi_param *param;
  62        struct iscsi_portal_group *tpg;
  63        int ret;
  64
  65        tpg = iscsit_alloc_portal_group(NULL, 1);
  66        if (!tpg) {
  67                pr_err("Unable to allocate struct iscsi_portal_group\n");
  68                return -1;
  69        }
  70
  71        ret = core_tpg_register(
  72                        &lio_target_fabric_configfs->tf_ops,
  73                        NULL, &tpg->tpg_se_tpg, tpg,
  74                        TRANSPORT_TPG_TYPE_DISCOVERY);
  75        if (ret < 0) {
  76                kfree(tpg);
  77                return -1;
  78        }
  79
  80        tpg->sid = 1; /* First Assigned LIO Session ID */
  81        iscsit_set_default_tpg_attribs(tpg);
  82
  83        if (iscsi_create_default_params(&tpg->param_list) < 0)
  84                goto out;
  85        /*
  86         * By default we disable authentication for discovery sessions,
  87         * this can be changed with:
  88         *
  89         * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
  90         */
  91        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
  92        if (!param)
  93                goto out;
  94
  95        if (iscsi_update_param_value(param, "CHAP,None") < 0)
  96                goto out;
  97
  98        tpg->tpg_attrib.authentication = 0;
  99
 100        spin_lock(&tpg->tpg_state_lock);
 101        tpg->tpg_state  = TPG_STATE_ACTIVE;
 102        spin_unlock(&tpg->tpg_state_lock);
 103
 104        iscsit_global->discovery_tpg = tpg;
 105        pr_debug("CORE[0] - Allocated Discovery TPG\n");
 106
 107        return 0;
 108out:
 109        if (tpg->sid == 1)
 110                core_tpg_deregister(&tpg->tpg_se_tpg);
 111        kfree(tpg);
 112        return -1;
 113}
 114
 115void iscsit_release_discovery_tpg(void)
 116{
 117        struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
 118
 119        if (!tpg)
 120                return;
 121
 122        core_tpg_deregister(&tpg->tpg_se_tpg);
 123
 124        kfree(tpg);
 125        iscsit_global->discovery_tpg = NULL;
 126}
 127
 128struct iscsi_portal_group *iscsit_get_tpg_from_np(
 129        struct iscsi_tiqn *tiqn,
 130        struct iscsi_np *np,
 131        struct iscsi_tpg_np **tpg_np_out)
 132{
 133        struct iscsi_portal_group *tpg = NULL;
 134        struct iscsi_tpg_np *tpg_np;
 135
 136        spin_lock(&tiqn->tiqn_tpg_lock);
 137        list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
 138
 139                spin_lock(&tpg->tpg_state_lock);
 140                if (tpg->tpg_state == TPG_STATE_FREE) {
 141                        spin_unlock(&tpg->tpg_state_lock);
 142                        continue;
 143                }
 144                spin_unlock(&tpg->tpg_state_lock);
 145
 146                spin_lock(&tpg->tpg_np_lock);
 147                list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 148                        if (tpg_np->tpg_np == np) {
 149                                *tpg_np_out = tpg_np;
 150                                kref_get(&tpg_np->tpg_np_kref);
 151                                spin_unlock(&tpg->tpg_np_lock);
 152                                spin_unlock(&tiqn->tiqn_tpg_lock);
 153                                return tpg;
 154                        }
 155                }
 156                spin_unlock(&tpg->tpg_np_lock);
 157        }
 158        spin_unlock(&tiqn->tiqn_tpg_lock);
 159
 160        return NULL;
 161}
 162
 163int iscsit_get_tpg(
 164        struct iscsi_portal_group *tpg)
 165{
 166        int ret;
 167
 168        ret = mutex_lock_interruptible(&tpg->tpg_access_lock);
 169        return ((ret != 0) || signal_pending(current)) ? -1 : 0;
 170}
 171
 172void iscsit_put_tpg(struct iscsi_portal_group *tpg)
 173{
 174        mutex_unlock(&tpg->tpg_access_lock);
 175}
 176
 177static void iscsit_clear_tpg_np_login_thread(
 178        struct iscsi_tpg_np *tpg_np,
 179        struct iscsi_portal_group *tpg,
 180        bool shutdown)
 181{
 182        if (!tpg_np->tpg_np) {
 183                pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 184                return;
 185        }
 186
 187        iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
 188}
 189
 190void iscsit_clear_tpg_np_login_threads(
 191        struct iscsi_portal_group *tpg,
 192        bool shutdown)
 193{
 194        struct iscsi_tpg_np *tpg_np;
 195
 196        spin_lock(&tpg->tpg_np_lock);
 197        list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 198                if (!tpg_np->tpg_np) {
 199                        pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 200                        continue;
 201                }
 202                spin_unlock(&tpg->tpg_np_lock);
 203                iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
 204                spin_lock(&tpg->tpg_np_lock);
 205        }
 206        spin_unlock(&tpg->tpg_np_lock);
 207}
 208
 209void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
 210{
 211        iscsi_print_params(tpg->param_list);
 212}
 213
 214static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
 215{
 216        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 217
 218        a->authentication = TA_AUTHENTICATION;
 219        a->login_timeout = TA_LOGIN_TIMEOUT;
 220        a->netif_timeout = TA_NETIF_TIMEOUT;
 221        a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
 222        a->generate_node_acls = TA_GENERATE_NODE_ACLS;
 223        a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
 224        a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
 225        a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
 226}
 227
 228int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
 229{
 230        if (tpg->tpg_state != TPG_STATE_FREE) {
 231                pr_err("Unable to add iSCSI Target Portal Group: %d"
 232                        " while not in TPG_STATE_FREE state.\n", tpg->tpgt);
 233                return -EEXIST;
 234        }
 235        iscsit_set_default_tpg_attribs(tpg);
 236
 237        if (iscsi_create_default_params(&tpg->param_list) < 0)
 238                goto err_out;
 239
 240        ISCSI_TPG_ATTRIB(tpg)->tpg = tpg;
 241
 242        spin_lock(&tpg->tpg_state_lock);
 243        tpg->tpg_state  = TPG_STATE_INACTIVE;
 244        spin_unlock(&tpg->tpg_state_lock);
 245
 246        spin_lock(&tiqn->tiqn_tpg_lock);
 247        list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
 248        tiqn->tiqn_ntpgs++;
 249        pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
 250                        tiqn->tiqn, tpg->tpgt);
 251        spin_unlock(&tiqn->tiqn_tpg_lock);
 252
 253        return 0;
 254err_out:
 255        if (tpg->param_list) {
 256                iscsi_release_param_list(tpg->param_list);
 257                tpg->param_list = NULL;
 258        }
 259        kfree(tpg);
 260        return -ENOMEM;
 261}
 262
 263int iscsit_tpg_del_portal_group(
 264        struct iscsi_tiqn *tiqn,
 265        struct iscsi_portal_group *tpg,
 266        int force)
 267{
 268        u8 old_state = tpg->tpg_state;
 269
 270        spin_lock(&tpg->tpg_state_lock);
 271        tpg->tpg_state = TPG_STATE_INACTIVE;
 272        spin_unlock(&tpg->tpg_state_lock);
 273
 274        iscsit_clear_tpg_np_login_threads(tpg, true);
 275
 276        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 277                pr_err("Unable to delete iSCSI Target Portal Group:"
 278                        " %hu while active sessions exist, and force=0\n",
 279                        tpg->tpgt);
 280                tpg->tpg_state = old_state;
 281                return -EPERM;
 282        }
 283
 284        core_tpg_clear_object_luns(&tpg->tpg_se_tpg);
 285
 286        if (tpg->param_list) {
 287                iscsi_release_param_list(tpg->param_list);
 288                tpg->param_list = NULL;
 289        }
 290
 291        core_tpg_deregister(&tpg->tpg_se_tpg);
 292
 293        spin_lock(&tpg->tpg_state_lock);
 294        tpg->tpg_state = TPG_STATE_FREE;
 295        spin_unlock(&tpg->tpg_state_lock);
 296
 297        spin_lock(&tiqn->tiqn_tpg_lock);
 298        tiqn->tiqn_ntpgs--;
 299        list_del(&tpg->tpg_list);
 300        spin_unlock(&tiqn->tiqn_tpg_lock);
 301
 302        pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
 303                        tiqn->tiqn, tpg->tpgt);
 304
 305        kfree(tpg);
 306        return 0;
 307}
 308
 309int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
 310{
 311        struct iscsi_param *param;
 312        struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
 313        int ret;
 314
 315        spin_lock(&tpg->tpg_state_lock);
 316        if (tpg->tpg_state == TPG_STATE_ACTIVE) {
 317                pr_err("iSCSI target portal group: %hu is already"
 318                        " active, ignoring request.\n", tpg->tpgt);
 319                spin_unlock(&tpg->tpg_state_lock);
 320                return -EINVAL;
 321        }
 322        /*
 323         * Make sure that AuthMethod does not contain None as an option
 324         * unless explictly disabled.  Set the default to CHAP if authentication
 325         * is enforced (as per default), and remove the NONE option.
 326         */
 327        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 328        if (!param) {
 329                spin_unlock(&tpg->tpg_state_lock);
 330                return -EINVAL;
 331        }
 332
 333        if (ISCSI_TPG_ATTRIB(tpg)->authentication) {
 334                if (!strcmp(param->value, NONE)) {
 335                        ret = iscsi_update_param_value(param, CHAP);
 336                        if (ret)
 337                                goto err;
 338                }
 339
 340                ret = iscsit_ta_authentication(tpg, 1);
 341                if (ret < 0)
 342                        goto err;
 343        }
 344
 345        tpg->tpg_state = TPG_STATE_ACTIVE;
 346        spin_unlock(&tpg->tpg_state_lock);
 347
 348        spin_lock(&tiqn->tiqn_tpg_lock);
 349        tiqn->tiqn_active_tpgs++;
 350        pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
 351                        tpg->tpgt);
 352        spin_unlock(&tiqn->tiqn_tpg_lock);
 353
 354        return 0;
 355
 356err:
 357        spin_unlock(&tpg->tpg_state_lock);
 358        return ret;
 359}
 360
 361int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
 362{
 363        struct iscsi_tiqn *tiqn;
 364        u8 old_state = tpg->tpg_state;
 365
 366        spin_lock(&tpg->tpg_state_lock);
 367        if (tpg->tpg_state == TPG_STATE_INACTIVE) {
 368                pr_err("iSCSI Target Portal Group: %hu is already"
 369                        " inactive, ignoring request.\n", tpg->tpgt);
 370                spin_unlock(&tpg->tpg_state_lock);
 371                return -EINVAL;
 372        }
 373        tpg->tpg_state = TPG_STATE_INACTIVE;
 374        spin_unlock(&tpg->tpg_state_lock);
 375
 376        iscsit_clear_tpg_np_login_threads(tpg, false);
 377
 378        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 379                spin_lock(&tpg->tpg_state_lock);
 380                tpg->tpg_state = old_state;
 381                spin_unlock(&tpg->tpg_state_lock);
 382                pr_err("Unable to disable iSCSI Target Portal Group:"
 383                        " %hu while active sessions exist, and force=0\n",
 384                        tpg->tpgt);
 385                return -EPERM;
 386        }
 387
 388        tiqn = tpg->tpg_tiqn;
 389        if (!tiqn || (tpg == iscsit_global->discovery_tpg))
 390                return 0;
 391
 392        spin_lock(&tiqn->tiqn_tpg_lock);
 393        tiqn->tiqn_active_tpgs--;
 394        pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
 395                        tpg->tpgt);
 396        spin_unlock(&tiqn->tiqn_tpg_lock);
 397
 398        return 0;
 399}
 400
 401struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
 402        struct iscsi_session *sess)
 403{
 404        struct se_session *se_sess = sess->se_sess;
 405        struct se_node_acl *se_nacl = se_sess->se_node_acl;
 406        struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
 407                                        se_node_acl);
 408
 409        return &acl->node_attrib;
 410}
 411
 412struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
 413        struct iscsi_tpg_np *tpg_np,
 414        int network_transport)
 415{
 416        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 417
 418        spin_lock(&tpg_np->tpg_np_parent_lock);
 419        list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 420                        &tpg_np->tpg_np_parent_list, tpg_np_child_list) {
 421                if (tpg_np_child->tpg_np->np_network_transport ==
 422                                network_transport) {
 423                        spin_unlock(&tpg_np->tpg_np_parent_lock);
 424                        return tpg_np_child;
 425                }
 426        }
 427        spin_unlock(&tpg_np->tpg_np_parent_lock);
 428
 429        return NULL;
 430}
 431
 432static bool iscsit_tpg_check_network_portal(
 433        struct iscsi_tiqn *tiqn,
 434        struct __kernel_sockaddr_storage *sockaddr,
 435        int network_transport)
 436{
 437        struct iscsi_portal_group *tpg;
 438        struct iscsi_tpg_np *tpg_np;
 439        struct iscsi_np *np;
 440        bool match = false;
 441
 442        spin_lock(&tiqn->tiqn_tpg_lock);
 443        list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
 444
 445                spin_lock(&tpg->tpg_np_lock);
 446                list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 447                        np = tpg_np->tpg_np;
 448
 449                        match = iscsit_check_np_match(sockaddr, np,
 450                                                network_transport);
 451                        if (match == true)
 452                                break;
 453                }
 454                spin_unlock(&tpg->tpg_np_lock);
 455        }
 456        spin_unlock(&tiqn->tiqn_tpg_lock);
 457
 458        return match;
 459}
 460
 461struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
 462        struct iscsi_portal_group *tpg,
 463        struct __kernel_sockaddr_storage *sockaddr,
 464        char *ip_str,
 465        struct iscsi_tpg_np *tpg_np_parent,
 466        int network_transport)
 467{
 468        struct iscsi_np *np;
 469        struct iscsi_tpg_np *tpg_np;
 470
 471        if (!tpg_np_parent) {
 472                if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
 473                                network_transport) == true) {
 474                        pr_err("Network Portal: %s already exists on a"
 475                                " different TPG on %s\n", ip_str,
 476                                tpg->tpg_tiqn->tiqn);
 477                        return ERR_PTR(-EEXIST);
 478                }
 479        }
 480
 481        tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
 482        if (!tpg_np) {
 483                pr_err("Unable to allocate memory for"
 484                                " struct iscsi_tpg_np.\n");
 485                return ERR_PTR(-ENOMEM);
 486        }
 487
 488        np = iscsit_add_np(sockaddr, ip_str, network_transport);
 489        if (IS_ERR(np)) {
 490                kfree(tpg_np);
 491                return ERR_CAST(np);
 492        }
 493
 494        INIT_LIST_HEAD(&tpg_np->tpg_np_list);
 495        INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
 496        INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
 497        spin_lock_init(&tpg_np->tpg_np_parent_lock);
 498        init_completion(&tpg_np->tpg_np_comp);
 499        kref_init(&tpg_np->tpg_np_kref);
 500        tpg_np->tpg_np          = np;
 501        tpg_np->tpg             = tpg;
 502
 503        spin_lock(&tpg->tpg_np_lock);
 504        list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
 505        tpg->num_tpg_nps++;
 506        if (tpg->tpg_tiqn)
 507                tpg->tpg_tiqn->tiqn_num_tpg_nps++;
 508        spin_unlock(&tpg->tpg_np_lock);
 509
 510        if (tpg_np_parent) {
 511                tpg_np->tpg_np_parent = tpg_np_parent;
 512                spin_lock(&tpg_np_parent->tpg_np_parent_lock);
 513                list_add_tail(&tpg_np->tpg_np_child_list,
 514                        &tpg_np_parent->tpg_np_parent_list);
 515                spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
 516        }
 517
 518        pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n",
 519                tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
 520                np->np_transport->name);
 521
 522        return tpg_np;
 523}
 524
 525static int iscsit_tpg_release_np(
 526        struct iscsi_tpg_np *tpg_np,
 527        struct iscsi_portal_group *tpg,
 528        struct iscsi_np *np)
 529{
 530        iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
 531
 532        pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
 533                tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
 534                np->np_transport->name);
 535
 536        tpg_np->tpg_np = NULL;
 537        tpg_np->tpg = NULL;
 538        kfree(tpg_np);
 539        /*
 540         * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
 541         */
 542        return iscsit_del_np(np);
 543}
 544
 545int iscsit_tpg_del_network_portal(
 546        struct iscsi_portal_group *tpg,
 547        struct iscsi_tpg_np *tpg_np)
 548{
 549        struct iscsi_np *np;
 550        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 551        int ret = 0;
 552
 553        np = tpg_np->tpg_np;
 554        if (!np) {
 555                pr_err("Unable to locate struct iscsi_np from"
 556                                " struct iscsi_tpg_np\n");
 557                return -EINVAL;
 558        }
 559
 560        if (!tpg_np->tpg_np_parent) {
 561                /*
 562                 * We are the parent tpg network portal.  Release all of the
 563                 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
 564                 * list first.
 565                 */
 566                list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 567                                &tpg_np->tpg_np_parent_list,
 568                                tpg_np_child_list) {
 569                        ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
 570                        if (ret < 0)
 571                                pr_err("iscsit_tpg_del_network_portal()"
 572                                        " failed: %d\n", ret);
 573                }
 574        } else {
 575                /*
 576                 * We are not the parent ISCSI_TCP tpg network portal.  Release
 577                 * our own network portals from the child list.
 578                 */
 579                spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 580                list_del(&tpg_np->tpg_np_child_list);
 581                spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 582        }
 583
 584        spin_lock(&tpg->tpg_np_lock);
 585        list_del(&tpg_np->tpg_np_list);
 586        tpg->num_tpg_nps--;
 587        if (tpg->tpg_tiqn)
 588                tpg->tpg_tiqn->tiqn_num_tpg_nps--;
 589        spin_unlock(&tpg->tpg_np_lock);
 590
 591        return iscsit_tpg_release_np(tpg_np, tpg, np);
 592}
 593
 594int iscsit_tpg_set_initiator_node_queue_depth(
 595        struct iscsi_portal_group *tpg,
 596        unsigned char *initiatorname,
 597        u32 queue_depth,
 598        int force)
 599{
 600        return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
 601                initiatorname, queue_depth, force);
 602}
 603
 604int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
 605{
 606        unsigned char buf1[256], buf2[256], *none = NULL;
 607        int len;
 608        struct iscsi_param *param;
 609        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 610
 611        if ((authentication != 1) && (authentication != 0)) {
 612                pr_err("Illegal value for authentication parameter:"
 613                        " %u, ignoring request.\n", authentication);
 614                return -EINVAL;
 615        }
 616
 617        memset(buf1, 0, sizeof(buf1));
 618        memset(buf2, 0, sizeof(buf2));
 619
 620        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 621        if (!param)
 622                return -EINVAL;
 623
 624        if (authentication) {
 625                snprintf(buf1, sizeof(buf1), "%s", param->value);
 626                none = strstr(buf1, NONE);
 627                if (!none)
 628                        goto out;
 629                if (!strncmp(none + 4, ",", 1)) {
 630                        if (!strcmp(buf1, none))
 631                                sprintf(buf2, "%s", none+5);
 632                        else {
 633                                none--;
 634                                *none = '\0';
 635                                len = sprintf(buf2, "%s", buf1);
 636                                none += 5;
 637                                sprintf(buf2 + len, "%s", none);
 638                        }
 639                } else {
 640                        none--;
 641                        *none = '\0';
 642                        sprintf(buf2, "%s", buf1);
 643                }
 644                if (iscsi_update_param_value(param, buf2) < 0)
 645                        return -EINVAL;
 646        } else {
 647                snprintf(buf1, sizeof(buf1), "%s", param->value);
 648                none = strstr(buf1, NONE);
 649                if (none)
 650                        goto out;
 651                strncat(buf1, ",", strlen(","));
 652                strncat(buf1, NONE, strlen(NONE));
 653                if (iscsi_update_param_value(param, buf1) < 0)
 654                        return -EINVAL;
 655        }
 656
 657out:
 658        a->authentication = authentication;
 659        pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
 660                a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
 661
 662        return 0;
 663}
 664
 665int iscsit_ta_login_timeout(
 666        struct iscsi_portal_group *tpg,
 667        u32 login_timeout)
 668{
 669        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 670
 671        if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
 672                pr_err("Requested Login Timeout %u larger than maximum"
 673                        " %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
 674                return -EINVAL;
 675        } else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
 676                pr_err("Requested Logout Timeout %u smaller than"
 677                        " minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
 678                return -EINVAL;
 679        }
 680
 681        a->login_timeout = login_timeout;
 682        pr_debug("Set Logout Timeout to %u for Target Portal Group"
 683                " %hu\n", a->login_timeout, tpg->tpgt);
 684
 685        return 0;
 686}
 687
 688int iscsit_ta_netif_timeout(
 689        struct iscsi_portal_group *tpg,
 690        u32 netif_timeout)
 691{
 692        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 693
 694        if (netif_timeout > TA_NETIF_TIMEOUT_MAX) {
 695                pr_err("Requested Network Interface Timeout %u larger"
 696                        " than maximum %u\n", netif_timeout,
 697                                TA_NETIF_TIMEOUT_MAX);
 698                return -EINVAL;
 699        } else if (netif_timeout < TA_NETIF_TIMEOUT_MIN) {
 700                pr_err("Requested Network Interface Timeout %u smaller"
 701                        " than minimum %u\n", netif_timeout,
 702                                TA_NETIF_TIMEOUT_MIN);
 703                return -EINVAL;
 704        }
 705
 706        a->netif_timeout = netif_timeout;
 707        pr_debug("Set Network Interface Timeout to %u for"
 708                " Target Portal Group %hu\n", a->netif_timeout, tpg->tpgt);
 709
 710        return 0;
 711}
 712
 713int iscsit_ta_generate_node_acls(
 714        struct iscsi_portal_group *tpg,
 715        u32 flag)
 716{
 717        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 718
 719        if ((flag != 0) && (flag != 1)) {
 720                pr_err("Illegal value %d\n", flag);
 721                return -EINVAL;
 722        }
 723
 724        a->generate_node_acls = flag;
 725        pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
 726                tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
 727
 728        if (flag == 1 && a->cache_dynamic_acls == 0) {
 729                pr_debug("Explicitly setting cache_dynamic_acls=1 when "
 730                        "generate_node_acls=1\n");
 731                a->cache_dynamic_acls = 1;
 732        }
 733
 734        return 0;
 735}
 736
 737int iscsit_ta_default_cmdsn_depth(
 738        struct iscsi_portal_group *tpg,
 739        u32 tcq_depth)
 740{
 741        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 742
 743        if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
 744                pr_err("Requested Default Queue Depth: %u larger"
 745                        " than maximum %u\n", tcq_depth,
 746                                TA_DEFAULT_CMDSN_DEPTH_MAX);
 747                return -EINVAL;
 748        } else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
 749                pr_err("Requested Default Queue Depth: %u smaller"
 750                        " than minimum %u\n", tcq_depth,
 751                                TA_DEFAULT_CMDSN_DEPTH_MIN);
 752                return -EINVAL;
 753        }
 754
 755        a->default_cmdsn_depth = tcq_depth;
 756        pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
 757                tpg->tpgt, a->default_cmdsn_depth);
 758
 759        return 0;
 760}
 761
 762int iscsit_ta_cache_dynamic_acls(
 763        struct iscsi_portal_group *tpg,
 764        u32 flag)
 765{
 766        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 767
 768        if ((flag != 0) && (flag != 1)) {
 769                pr_err("Illegal value %d\n", flag);
 770                return -EINVAL;
 771        }
 772
 773        if (a->generate_node_acls == 1 && flag == 0) {
 774                pr_debug("Skipping cache_dynamic_acls=0 when"
 775                        " generate_node_acls=1\n");
 776                return 0;
 777        }
 778
 779        a->cache_dynamic_acls = flag;
 780        pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
 781                " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
 782                "Enabled" : "Disabled");
 783
 784        return 0;
 785}
 786
 787int iscsit_ta_demo_mode_write_protect(
 788        struct iscsi_portal_group *tpg,
 789        u32 flag)
 790{
 791        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 792
 793        if ((flag != 0) && (flag != 1)) {
 794                pr_err("Illegal value %d\n", flag);
 795                return -EINVAL;
 796        }
 797
 798        a->demo_mode_write_protect = flag;
 799        pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
 800                tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
 801
 802        return 0;
 803}
 804
 805int iscsit_ta_prod_mode_write_protect(
 806        struct iscsi_portal_group *tpg,
 807        u32 flag)
 808{
 809        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 810
 811        if ((flag != 0) && (flag != 1)) {
 812                pr_err("Illegal value %d\n", flag);
 813                return -EINVAL;
 814        }
 815
 816        a->prod_mode_write_protect = flag;
 817        pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
 818                " %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
 819                "ON" : "OFF");
 820
 821        return 0;
 822}
 823