~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/target/target_core_configfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * This file contains ConfigFS logic for the Generic Target Engine project.
5
5
 *
6
 
 * Copyright (c) 2008-2010 Rising Tide Systems
7
 
 * Copyright (c) 2008-2010 Linux-iSCSI.org
 
6
 * Copyright (c) 2008-2011 Rising Tide Systems
 
7
 * Copyright (c) 2008-2011 Linux-iSCSI.org
8
8
 *
9
9
 * Nicholas A. Bellinger <nab@kernel.org>
10
10
 *
50
50
#include "target_core_hba.h"
51
51
#include "target_core_pr.h"
52
52
#include "target_core_rd.h"
 
53
#include "target_core_stat.h"
53
54
 
54
55
static struct list_head g_tf_list;
55
56
static struct mutex g_tf_lock;
303
304
                printk(KERN_ERR "Unable to locate passed fabric name\n");
304
305
                return NULL;
305
306
        }
306
 
        if (strlen(name) > TARGET_FABRIC_NAME_SIZE) {
 
307
        if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) {
307
308
                printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
308
309
                        "_NAME_SIZE\n", name);
309
310
                return NULL;
311
312
 
312
313
        tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
313
314
        if (!(tf))
314
 
                return ERR_PTR(-ENOMEM);
 
315
                return NULL;
315
316
 
316
317
        INIT_LIST_HEAD(&tf->tf_list);
317
318
        atomic_set(&tf->tf_access_cnt, 0);
496
497
                printk(KERN_ERR "Missing tfo->is_state_remove()\n");
497
498
                return -EINVAL;
498
499
        }
499
 
        if (!(tfo->pack_lun)) {
500
 
                printk(KERN_ERR "Missing tfo->pack_lun()\n");
501
 
                return -EINVAL;
502
 
        }
503
500
        /*
504
501
         * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn()
505
502
         * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
854
851
                return -EOPNOTSUPP;
855
852
        }
856
853
 
857
 
        if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) {
 
854
        if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) {
858
855
                printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
859
856
                " INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
860
857
                return -EOVERFLOW;
920
917
 
921
918
                transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
922
919
 
923
 
                if ((len + strlen(buf) > PAGE_SIZE))
 
920
                if ((len + strlen(buf) >= PAGE_SIZE))
924
921
                        break;
925
922
 
926
923
                len += sprintf(page+len, "%s", buf);
965
962
                                                                        \
966
963
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
967
964
                transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE);   \
968
 
                if ((len + strlen(buf) > PAGE_SIZE))                    \
 
965
                if ((len + strlen(buf) >= PAGE_SIZE))                   \
969
966
                        break;                                          \
970
967
                len += sprintf(page+len, "%s", buf);                    \
971
968
                                                                        \
972
969
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
973
970
                transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \
974
 
                if ((len + strlen(buf) > PAGE_SIZE))                    \
 
971
                if ((len + strlen(buf) >= PAGE_SIZE))                   \
975
972
                        break;                                          \
976
973
                len += sprintf(page+len, "%s", buf);                    \
977
974
                                                                        \
978
975
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
979
976
                transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \
980
 
                if ((len + strlen(buf) > PAGE_SIZE))                    \
 
977
                if ((len + strlen(buf) >= PAGE_SIZE))                   \
981
978
                        break;                                          \
982
979
                len += sprintf(page+len, "%s", buf);                    \
983
980
        }                                                               \
1302
1299
                        &i_buf[0] : "", pr_reg->pr_res_key,
1303
1300
                        pr_reg->pr_res_generation);
1304
1301
 
1305
 
                if ((len + strlen(buf) > PAGE_SIZE))
 
1302
                if ((len + strlen(buf) >= PAGE_SIZE))
1306
1303
                        break;
1307
1304
 
1308
1305
                len += sprintf(page+len, "%s", buf);
1451
1448
        size_t count)
1452
1449
{
1453
1450
        struct se_device *dev;
1454
 
        unsigned char *i_fabric, *t_fabric, *i_port = NULL, *t_port = NULL;
1455
 
        unsigned char *isid = NULL;
 
1451
        unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
 
1452
        unsigned char *t_fabric = NULL, *t_port = NULL;
1456
1453
        char *orig, *ptr, *arg_p, *opts;
1457
1454
        substring_t args[MAX_OPT_ARGS];
1458
1455
        unsigned long long tmp_ll;
1488
1485
                switch (token) {
1489
1486
                case Opt_initiator_fabric:
1490
1487
                        i_fabric = match_strdup(&args[0]);
 
1488
                        if (!i_fabric) {
 
1489
                                ret = -ENOMEM;
 
1490
                                goto out;
 
1491
                        }
1491
1492
                        break;
1492
1493
                case Opt_initiator_node:
1493
1494
                        i_port = match_strdup(&args[0]);
1494
 
                        if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
 
1495
                        if (!i_port) {
 
1496
                                ret = -ENOMEM;
 
1497
                                goto out;
 
1498
                        }
 
1499
                        if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) {
1495
1500
                                printk(KERN_ERR "APTPL metadata initiator_node="
1496
1501
                                        " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
1497
1502
                                        PR_APTPL_MAX_IPORT_LEN);
1501
1506
                        break;
1502
1507
                case Opt_initiator_sid:
1503
1508
                        isid = match_strdup(&args[0]);
1504
 
                        if (strlen(isid) > PR_REG_ISID_LEN) {
 
1509
                        if (!isid) {
 
1510
                                ret = -ENOMEM;
 
1511
                                goto out;
 
1512
                        }
 
1513
                        if (strlen(isid) >= PR_REG_ISID_LEN) {
1505
1514
                                printk(KERN_ERR "APTPL metadata initiator_isid"
1506
1515
                                        "= exceeds PR_REG_ISID_LEN: %d\n",
1507
1516
                                        PR_REG_ISID_LEN);
1511
1520
                        break;
1512
1521
                case Opt_sa_res_key:
1513
1522
                        arg_p = match_strdup(&args[0]);
 
1523
                        if (!arg_p) {
 
1524
                                ret = -ENOMEM;
 
1525
                                goto out;
 
1526
                        }
1514
1527
                        ret = strict_strtoull(arg_p, 0, &tmp_ll);
1515
1528
                        if (ret < 0) {
1516
1529
                                printk(KERN_ERR "strict_strtoull() failed for"
1547
1560
                 */
1548
1561
                case Opt_target_fabric:
1549
1562
                        t_fabric = match_strdup(&args[0]);
 
1563
                        if (!t_fabric) {
 
1564
                                ret = -ENOMEM;
 
1565
                                goto out;
 
1566
                        }
1550
1567
                        break;
1551
1568
                case Opt_target_node:
1552
1569
                        t_port = match_strdup(&args[0]);
1553
 
                        if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
 
1570
                        if (!t_port) {
 
1571
                                ret = -ENOMEM;
 
1572
                                goto out;
 
1573
                        }
 
1574
                        if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) {
1554
1575
                                printk(KERN_ERR "APTPL metadata target_node="
1555
1576
                                        " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
1556
1577
                                        PR_APTPL_MAX_TPORT_LEN);
1592
1613
                        i_port, isid, mapped_lun, t_port, tpgt, target_lun,
1593
1614
                        res_holder, all_tg_pt, type);
1594
1615
out:
 
1616
        kfree(i_fabric);
 
1617
        kfree(i_port);
 
1618
        kfree(isid);
 
1619
        kfree(t_fabric);
 
1620
        kfree(t_port);
1595
1621
        kfree(orig);
1596
1622
        return (ret == 0) ? count : ret;
1597
1623
}
1798
1824
                return -EINVAL;
1799
1825
 
1800
1826
        dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
1801
 
        if (!(dev) || IS_ERR(dev))
 
1827
        if (IS_ERR(dev))
 
1828
                return PTR_ERR(dev);
 
1829
        else if (!dev)
1802
1830
                return -EINVAL;
1803
1831
 
1804
1832
        se_dev->se_dev_ptr = dev;
2678
2706
 
2679
2707
/* End functions for struct config_item_type target_core_alua_cit */
2680
2708
 
 
2709
/* Start functions for struct config_item_type target_core_stat_cit */
 
2710
 
 
2711
static struct config_group *target_core_stat_mkdir(
 
2712
        struct config_group *group,
 
2713
        const char *name)
 
2714
{
 
2715
        return ERR_PTR(-ENOSYS);
 
2716
}
 
2717
 
 
2718
static void target_core_stat_rmdir(
 
2719
        struct config_group *group,
 
2720
        struct config_item *item)
 
2721
{
 
2722
        return;
 
2723
}
 
2724
 
 
2725
static struct configfs_group_operations target_core_stat_group_ops = {
 
2726
        .make_group             = &target_core_stat_mkdir,
 
2727
        .drop_item              = &target_core_stat_rmdir,
 
2728
};
 
2729
 
 
2730
static struct config_item_type target_core_stat_cit = {
 
2731
        .ct_group_ops           = &target_core_stat_group_ops,
 
2732
        .ct_owner               = THIS_MODULE,
 
2733
};
 
2734
 
 
2735
/* End functions for struct config_item_type target_core_stat_cit */
 
2736
 
2681
2737
/* Start functions for struct config_item_type target_core_hba_cit */
2682
2738
 
2683
2739
static struct config_group *target_core_make_subdev(
2690
2746
        struct config_item *hba_ci = &group->cg_item;
2691
2747
        struct se_hba *hba = item_to_hba(hba_ci);
2692
2748
        struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
2693
 
 
2694
 
        if (mutex_lock_interruptible(&hba->hba_access_mutex))
2695
 
                return NULL;
2696
 
 
 
2749
        struct config_group *dev_stat_grp = NULL;
 
2750
        int errno = -ENOMEM, ret;
 
2751
 
 
2752
        ret = mutex_lock_interruptible(&hba->hba_access_mutex);
 
2753
        if (ret)
 
2754
                return ERR_PTR(ret);
2697
2755
        /*
2698
2756
         * Locate the struct se_subsystem_api from parent's struct se_hba.
2699
2757
         */
2723
2781
        se_dev->se_dev_hba = hba;
2724
2782
        dev_cg = &se_dev->se_dev_group;
2725
2783
 
2726
 
        dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 6,
 
2784
        dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7,
2727
2785
                        GFP_KERNEL);
2728
2786
        if (!(dev_cg->default_groups))
2729
2787
                goto out;
2755
2813
                        &target_core_dev_wwn_cit);
2756
2814
        config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
2757
2815
                        "alua", &target_core_alua_tg_pt_gps_cit);
 
2816
        config_group_init_type_name(&se_dev->dev_stat_grps.stat_group,
 
2817
                        "statistics", &target_core_stat_cit);
 
2818
 
2758
2819
        dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
2759
2820
        dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
2760
2821
        dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group;
2761
2822
        dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group;
2762
 
        dev_cg->default_groups[4] = NULL;
 
2823
        dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group;
 
2824
        dev_cg->default_groups[5] = NULL;
2763
2825
        /*
2764
 
         * Add core/$HBA/$DEV/alua/tg_pt_gps/default_tg_pt_gp
 
2826
         * Add core/$HBA/$DEV/alua/default_tg_pt_gp
2765
2827
         */
2766
2828
        tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
2767
2829
        if (!(tg_pt_gp))
2781
2843
        tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
2782
2844
        tg_pt_gp_cg->default_groups[1] = NULL;
2783
2845
        T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp;
 
2846
        /*
 
2847
         * Add core/$HBA/$DEV/statistics/ default groups
 
2848
         */
 
2849
        dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
 
2850
        dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4,
 
2851
                                GFP_KERNEL);
 
2852
        if (!dev_stat_grp->default_groups) {
 
2853
                printk(KERN_ERR "Unable to allocate dev_stat_grp->default_groups\n");
 
2854
                goto out;
 
2855
        }
 
2856
        target_stat_setup_dev_default_groups(se_dev);
2784
2857
 
2785
2858
        printk(KERN_INFO "Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
2786
2859
                " %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
2792
2865
                core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
2793
2866
                T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
2794
2867
        }
 
2868
        if (dev_stat_grp)
 
2869
                kfree(dev_stat_grp->default_groups);
2795
2870
        if (tg_pt_gp_cg)
2796
2871
                kfree(tg_pt_gp_cg->default_groups);
2797
2872
        if (dev_cg)
2801
2876
        kfree(se_dev);
2802
2877
unlock:
2803
2878
        mutex_unlock(&hba->hba_access_mutex);
2804
 
        return NULL;
 
2879
        return ERR_PTR(errno);
2805
2880
}
2806
2881
 
2807
2882
static void target_core_drop_subdev(
2813
2888
        struct se_hba *hba;
2814
2889
        struct se_subsystem_api *t;
2815
2890
        struct config_item *df_item;
2816
 
        struct config_group *dev_cg, *tg_pt_gp_cg;
 
2891
        struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp;
2817
2892
        int i;
2818
2893
 
2819
2894
        hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
2825
2900
        list_del(&se_dev->g_se_dev_list);
2826
2901
        spin_unlock(&se_global->g_device_lock);
2827
2902
 
 
2903
        dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
 
2904
        for (i = 0; dev_stat_grp->default_groups[i]; i++) {
 
2905
                df_item = &dev_stat_grp->default_groups[i]->cg_item;
 
2906
                dev_stat_grp->default_groups[i] = NULL;
 
2907
                config_item_put(df_item);
 
2908
        }
 
2909
        kfree(dev_stat_grp->default_groups);
 
2910
 
2828
2911
        tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
2829
2912
        for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
2830
2913
                df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
2969
3052
        int ret;
2970
3053
 
2971
3054
        memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
2972
 
        if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) {
 
3055
        if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) {
2973
3056
                printk(KERN_ERR "Passed *name strlen(): %d exceeds"
2974
3057
                        " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
2975
3058
                        TARGET_CORE_NAME_MAX_LEN);
3044
3127
 
3045
3128
/* Stop functions for struct config_item_type target_core_hba_cit */
3046
3129
 
3047
 
static int target_core_init_configfs(void)
 
3130
static int __init target_core_init_configfs(void)
3048
3131
{
3049
3132
        struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
3050
3133
        struct config_group *lu_gp_cg = NULL;
3176
3259
        return -1;
3177
3260
}
3178
3261
 
3179
 
static void target_core_exit_configfs(void)
 
3262
static void __exit target_core_exit_configfs(void)
3180
3263
{
3181
3264
        struct configfs_subsystem *subsys;
3182
3265
        struct config_group *hba_cg, *alua_cg, *lu_gp_cg;