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