diff options
Diffstat (limited to 'drivers/target/target_core_configfs.c')
| -rw-r--r-- | drivers/target/target_core_configfs.c | 155 |
1 files changed, 85 insertions, 70 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 2764510798b0..caf8dc18ee0a 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/parser.h> | 37 | #include <linux/parser.h> |
| 38 | #include <linux/syscalls.h> | 38 | #include <linux/syscalls.h> |
| 39 | #include <linux/configfs.h> | 39 | #include <linux/configfs.h> |
| 40 | #include <linux/proc_fs.h> | ||
| 41 | 40 | ||
| 42 | #include <target/target_core_base.h> | 41 | #include <target/target_core_base.h> |
| 43 | #include <target/target_core_device.h> | 42 | #include <target/target_core_device.h> |
| @@ -1971,13 +1970,35 @@ static void target_core_dev_release(struct config_item *item) | |||
| 1971 | { | 1970 | { |
| 1972 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), | 1971 | struct se_subsystem_dev *se_dev = container_of(to_config_group(item), |
| 1973 | struct se_subsystem_dev, se_dev_group); | 1972 | struct se_subsystem_dev, se_dev_group); |
| 1974 | struct config_group *dev_cg; | 1973 | struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); |
| 1975 | 1974 | struct se_subsystem_api *t = hba->transport; | |
| 1976 | if (!(se_dev)) | 1975 | struct config_group *dev_cg = &se_dev->se_dev_group; |
| 1977 | return; | ||
| 1978 | 1976 | ||
| 1979 | dev_cg = &se_dev->se_dev_group; | ||
| 1980 | kfree(dev_cg->default_groups); | 1977 | kfree(dev_cg->default_groups); |
| 1978 | /* | ||
| 1979 | * This pointer will set when the storage is enabled with: | ||
| 1980 | *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` | ||
| 1981 | */ | ||
| 1982 | if (se_dev->se_dev_ptr) { | ||
| 1983 | printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" | ||
| 1984 | "virtual_device() for se_dev_ptr: %p\n", | ||
| 1985 | se_dev->se_dev_ptr); | ||
| 1986 | |||
| 1987 | se_free_virtual_device(se_dev->se_dev_ptr, hba); | ||
| 1988 | } else { | ||
| 1989 | /* | ||
| 1990 | * Release struct se_subsystem_dev->se_dev_su_ptr.. | ||
| 1991 | */ | ||
| 1992 | printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" | ||
| 1993 | "device() for se_dev_su_ptr: %p\n", | ||
| 1994 | se_dev->se_dev_su_ptr); | ||
| 1995 | |||
| 1996 | t->free_device(se_dev->se_dev_su_ptr); | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" | ||
| 2000 | "_dev_t: %p\n", se_dev); | ||
| 2001 | kfree(se_dev); | ||
| 1981 | } | 2002 | } |
| 1982 | 2003 | ||
| 1983 | static ssize_t target_core_dev_show(struct config_item *item, | 2004 | static ssize_t target_core_dev_show(struct config_item *item, |
| @@ -2140,7 +2161,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = { | |||
| 2140 | NULL, | 2161 | NULL, |
| 2141 | }; | 2162 | }; |
| 2142 | 2163 | ||
| 2164 | static void target_core_alua_lu_gp_release(struct config_item *item) | ||
| 2165 | { | ||
| 2166 | struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item), | ||
| 2167 | struct t10_alua_lu_gp, lu_gp_group); | ||
| 2168 | |||
| 2169 | core_alua_free_lu_gp(lu_gp); | ||
| 2170 | } | ||
| 2171 | |||
| 2143 | static struct configfs_item_operations target_core_alua_lu_gp_ops = { | 2172 | static struct configfs_item_operations target_core_alua_lu_gp_ops = { |
| 2173 | .release = target_core_alua_lu_gp_release, | ||
| 2144 | .show_attribute = target_core_alua_lu_gp_attr_show, | 2174 | .show_attribute = target_core_alua_lu_gp_attr_show, |
| 2145 | .store_attribute = target_core_alua_lu_gp_attr_store, | 2175 | .store_attribute = target_core_alua_lu_gp_attr_store, |
| 2146 | }; | 2176 | }; |
| @@ -2191,9 +2221,11 @@ static void target_core_alua_drop_lu_gp( | |||
| 2191 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" | 2221 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" |
| 2192 | " Group: core/alua/lu_gps/%s, ID: %hu\n", | 2222 | " Group: core/alua/lu_gps/%s, ID: %hu\n", |
| 2193 | config_item_name(item), lu_gp->lu_gp_id); | 2223 | config_item_name(item), lu_gp->lu_gp_id); |
| 2194 | 2224 | /* | |
| 2225 | * core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release() | ||
| 2226 | * -> target_core_alua_lu_gp_release() | ||
| 2227 | */ | ||
| 2195 | config_item_put(item); | 2228 | config_item_put(item); |
| 2196 | core_alua_free_lu_gp(lu_gp); | ||
| 2197 | } | 2229 | } |
| 2198 | 2230 | ||
| 2199 | static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { | 2231 | static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { |
| @@ -2549,7 +2581,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { | |||
| 2549 | NULL, | 2581 | NULL, |
| 2550 | }; | 2582 | }; |
| 2551 | 2583 | ||
| 2584 | static void target_core_alua_tg_pt_gp_release(struct config_item *item) | ||
| 2585 | { | ||
| 2586 | struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item), | ||
| 2587 | struct t10_alua_tg_pt_gp, tg_pt_gp_group); | ||
| 2588 | |||
| 2589 | core_alua_free_tg_pt_gp(tg_pt_gp); | ||
| 2590 | } | ||
| 2591 | |||
| 2552 | static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { | 2592 | static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { |
| 2593 | .release = target_core_alua_tg_pt_gp_release, | ||
| 2553 | .show_attribute = target_core_alua_tg_pt_gp_attr_show, | 2594 | .show_attribute = target_core_alua_tg_pt_gp_attr_show, |
| 2554 | .store_attribute = target_core_alua_tg_pt_gp_attr_store, | 2595 | .store_attribute = target_core_alua_tg_pt_gp_attr_store, |
| 2555 | }; | 2596 | }; |
| @@ -2602,9 +2643,11 @@ static void target_core_alua_drop_tg_pt_gp( | |||
| 2602 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" | 2643 | printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" |
| 2603 | " Group: alua/tg_pt_gps/%s, ID: %hu\n", | 2644 | " Group: alua/tg_pt_gps/%s, ID: %hu\n", |
| 2604 | config_item_name(item), tg_pt_gp->tg_pt_gp_id); | 2645 | config_item_name(item), tg_pt_gp->tg_pt_gp_id); |
| 2605 | 2646 | /* | |
| 2647 | * core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release() | ||
| 2648 | * -> target_core_alua_tg_pt_gp_release(). | ||
| 2649 | */ | ||
| 2606 | config_item_put(item); | 2650 | config_item_put(item); |
| 2607 | core_alua_free_tg_pt_gp(tg_pt_gp); | ||
| 2608 | } | 2651 | } |
| 2609 | 2652 | ||
| 2610 | static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { | 2653 | static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { |
| @@ -2771,13 +2814,11 @@ static void target_core_drop_subdev( | |||
| 2771 | struct se_subsystem_api *t; | 2814 | struct se_subsystem_api *t; |
| 2772 | struct config_item *df_item; | 2815 | struct config_item *df_item; |
| 2773 | struct config_group *dev_cg, *tg_pt_gp_cg; | 2816 | struct config_group *dev_cg, *tg_pt_gp_cg; |
| 2774 | int i, ret; | 2817 | int i; |
| 2775 | 2818 | ||
| 2776 | hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); | 2819 | hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); |
| 2777 | 2820 | ||
| 2778 | if (mutex_lock_interruptible(&hba->hba_access_mutex)) | 2821 | mutex_lock(&hba->hba_access_mutex); |
| 2779 | goto out; | ||
| 2780 | |||
| 2781 | t = hba->transport; | 2822 | t = hba->transport; |
| 2782 | 2823 | ||
| 2783 | spin_lock(&se_global->g_device_lock); | 2824 | spin_lock(&se_global->g_device_lock); |
| @@ -2791,7 +2832,10 @@ static void target_core_drop_subdev( | |||
| 2791 | config_item_put(df_item); | 2832 | config_item_put(df_item); |
| 2792 | } | 2833 | } |
| 2793 | kfree(tg_pt_gp_cg->default_groups); | 2834 | kfree(tg_pt_gp_cg->default_groups); |
| 2794 | core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); | 2835 | /* |
| 2836 | * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp | ||
| 2837 | * directly from target_core_alua_tg_pt_gp_release(). | ||
| 2838 | */ | ||
| 2795 | T10_ALUA(se_dev)->default_tg_pt_gp = NULL; | 2839 | T10_ALUA(se_dev)->default_tg_pt_gp = NULL; |
| 2796 | 2840 | ||
| 2797 | dev_cg = &se_dev->se_dev_group; | 2841 | dev_cg = &se_dev->se_dev_group; |
| @@ -2800,38 +2844,12 @@ static void target_core_drop_subdev( | |||
| 2800 | dev_cg->default_groups[i] = NULL; | 2844 | dev_cg->default_groups[i] = NULL; |
| 2801 | config_item_put(df_item); | 2845 | config_item_put(df_item); |
| 2802 | } | 2846 | } |
| 2803 | |||
| 2804 | config_item_put(item); | ||
| 2805 | /* | 2847 | /* |
| 2806 | * This pointer will set when the storage is enabled with: | 2848 | * The releasing of se_dev and associated se_dev->se_dev_ptr is done |
| 2807 | * `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` | 2849 | * from target_core_dev_item_ops->release() ->target_core_dev_release(). |
| 2808 | */ | 2850 | */ |
| 2809 | if (se_dev->se_dev_ptr) { | 2851 | config_item_put(item); |
| 2810 | printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" | ||
| 2811 | "virtual_device() for se_dev_ptr: %p\n", | ||
| 2812 | se_dev->se_dev_ptr); | ||
| 2813 | |||
| 2814 | ret = se_free_virtual_device(se_dev->se_dev_ptr, hba); | ||
| 2815 | if (ret < 0) | ||
| 2816 | goto hba_out; | ||
| 2817 | } else { | ||
| 2818 | /* | ||
| 2819 | * Release struct se_subsystem_dev->se_dev_su_ptr.. | ||
| 2820 | */ | ||
| 2821 | printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" | ||
| 2822 | "device() for se_dev_su_ptr: %p\n", | ||
| 2823 | se_dev->se_dev_su_ptr); | ||
| 2824 | |||
| 2825 | t->free_device(se_dev->se_dev_su_ptr); | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" | ||
| 2829 | "_dev_t: %p\n", se_dev); | ||
| 2830 | |||
| 2831 | hba_out: | ||
| 2832 | mutex_unlock(&hba->hba_access_mutex); | 2852 | mutex_unlock(&hba->hba_access_mutex); |
| 2833 | out: | ||
| 2834 | kfree(se_dev); | ||
| 2835 | } | 2853 | } |
| 2836 | 2854 | ||
| 2837 | static struct configfs_group_operations target_core_hba_group_ops = { | 2855 | static struct configfs_group_operations target_core_hba_group_ops = { |
| @@ -2914,6 +2932,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR); | |||
| 2914 | 2932 | ||
| 2915 | CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); | 2933 | CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); |
| 2916 | 2934 | ||
| 2935 | static void target_core_hba_release(struct config_item *item) | ||
| 2936 | { | ||
| 2937 | struct se_hba *hba = container_of(to_config_group(item), | ||
| 2938 | struct se_hba, hba_group); | ||
| 2939 | core_delete_hba(hba); | ||
| 2940 | } | ||
| 2941 | |||
| 2917 | static struct configfs_attribute *target_core_hba_attrs[] = { | 2942 | static struct configfs_attribute *target_core_hba_attrs[] = { |
| 2918 | &target_core_hba_hba_info.attr, | 2943 | &target_core_hba_hba_info.attr, |
| 2919 | &target_core_hba_hba_mode.attr, | 2944 | &target_core_hba_hba_mode.attr, |
| @@ -2921,6 +2946,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = { | |||
| 2921 | }; | 2946 | }; |
| 2922 | 2947 | ||
| 2923 | static struct configfs_item_operations target_core_hba_item_ops = { | 2948 | static struct configfs_item_operations target_core_hba_item_ops = { |
| 2949 | .release = target_core_hba_release, | ||
| 2924 | .show_attribute = target_core_hba_attr_show, | 2950 | .show_attribute = target_core_hba_attr_show, |
| 2925 | .store_attribute = target_core_hba_attr_store, | 2951 | .store_attribute = target_core_hba_attr_store, |
| 2926 | }; | 2952 | }; |
| @@ -2997,10 +3023,11 @@ static void target_core_call_delhbafromtarget( | |||
| 2997 | struct config_group *group, | 3023 | struct config_group *group, |
| 2998 | struct config_item *item) | 3024 | struct config_item *item) |
| 2999 | { | 3025 | { |
| 3000 | struct se_hba *hba = item_to_hba(item); | 3026 | /* |
| 3001 | 3027 | * core_delete_hba() is called from target_core_hba_item_ops->release() | |
| 3028 | * -> target_core_hba_release() | ||
| 3029 | */ | ||
| 3002 | config_item_put(item); | 3030 | config_item_put(item); |
| 3003 | core_delete_hba(hba); | ||
| 3004 | } | 3031 | } |
| 3005 | 3032 | ||
| 3006 | static struct configfs_group_operations target_core_group_ops = { | 3033 | static struct configfs_group_operations target_core_group_ops = { |
| @@ -3022,7 +3049,6 @@ static int target_core_init_configfs(void) | |||
| 3022 | struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; | 3049 | struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; |
| 3023 | struct config_group *lu_gp_cg = NULL; | 3050 | struct config_group *lu_gp_cg = NULL; |
| 3024 | struct configfs_subsystem *subsys; | 3051 | struct configfs_subsystem *subsys; |
| 3025 | struct proc_dir_entry *scsi_target_proc = NULL; | ||
| 3026 | struct t10_alua_lu_gp *lu_gp; | 3052 | struct t10_alua_lu_gp *lu_gp; |
| 3027 | int ret; | 3053 | int ret; |
| 3028 | 3054 | ||
| @@ -3128,21 +3154,10 @@ static int target_core_init_configfs(void) | |||
| 3128 | if (core_dev_setup_virtual_lun0() < 0) | 3154 | if (core_dev_setup_virtual_lun0() < 0) |
| 3129 | goto out; | 3155 | goto out; |
| 3130 | 3156 | ||
| 3131 | scsi_target_proc = proc_mkdir("scsi_target", 0); | ||
| 3132 | if (!(scsi_target_proc)) { | ||
| 3133 | printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n"); | ||
| 3134 | goto out; | ||
| 3135 | } | ||
| 3136 | ret = init_scsi_target_mib(); | ||
| 3137 | if (ret < 0) | ||
| 3138 | goto out; | ||
| 3139 | |||
| 3140 | return 0; | 3157 | return 0; |
| 3141 | 3158 | ||
| 3142 | out: | 3159 | out: |
| 3143 | configfs_unregister_subsystem(subsys); | 3160 | configfs_unregister_subsystem(subsys); |
| 3144 | if (scsi_target_proc) | ||
| 3145 | remove_proc_entry("scsi_target", 0); | ||
| 3146 | core_dev_release_virtual_lun0(); | 3161 | core_dev_release_virtual_lun0(); |
| 3147 | rd_module_exit(); | 3162 | rd_module_exit(); |
| 3148 | out_global: | 3163 | out_global: |
| @@ -3178,8 +3193,7 @@ static void target_core_exit_configfs(void) | |||
| 3178 | config_item_put(item); | 3193 | config_item_put(item); |
| 3179 | } | 3194 | } |
| 3180 | kfree(lu_gp_cg->default_groups); | 3195 | kfree(lu_gp_cg->default_groups); |
| 3181 | core_alua_free_lu_gp(se_global->default_lu_gp); | 3196 | lu_gp_cg->default_groups = NULL; |
| 3182 | se_global->default_lu_gp = NULL; | ||
| 3183 | 3197 | ||
| 3184 | alua_cg = &se_global->alua_group; | 3198 | alua_cg = &se_global->alua_group; |
| 3185 | for (i = 0; alua_cg->default_groups[i]; i++) { | 3199 | for (i = 0; alua_cg->default_groups[i]; i++) { |
| @@ -3188,6 +3202,7 @@ static void target_core_exit_configfs(void) | |||
| 3188 | config_item_put(item); | 3202 | config_item_put(item); |
| 3189 | } | 3203 | } |
| 3190 | kfree(alua_cg->default_groups); | 3204 | kfree(alua_cg->default_groups); |
| 3205 | alua_cg->default_groups = NULL; | ||
| 3191 | 3206 | ||
| 3192 | hba_cg = &se_global->target_core_hbagroup; | 3207 | hba_cg = &se_global->target_core_hbagroup; |
| 3193 | for (i = 0; hba_cg->default_groups[i]; i++) { | 3208 | for (i = 0; hba_cg->default_groups[i]; i++) { |
| @@ -3196,20 +3211,20 @@ static void target_core_exit_configfs(void) | |||
| 3196 | config_item_put(item); | 3211 | config_item_put(item); |
| 3197 | } | 3212 | } |
| 3198 | kfree(hba_cg->default_groups); | 3213 | kfree(hba_cg->default_groups); |
| 3199 | 3214 | hba_cg->default_groups = NULL; | |
| 3200 | for (i = 0; subsys->su_group.default_groups[i]; i++) { | 3215 | /* |
| 3201 | item = &subsys->su_group.default_groups[i]->cg_item; | 3216 | * We expect subsys->su_group.default_groups to be released |
| 3202 | subsys->su_group.default_groups[i] = NULL; | 3217 | * by configfs subsystem provider logic.. |
| 3203 | config_item_put(item); | 3218 | */ |
| 3204 | } | 3219 | configfs_unregister_subsystem(subsys); |
| 3205 | kfree(subsys->su_group.default_groups); | 3220 | kfree(subsys->su_group.default_groups); |
| 3206 | 3221 | ||
| 3207 | configfs_unregister_subsystem(subsys); | 3222 | core_alua_free_lu_gp(se_global->default_lu_gp); |
| 3223 | se_global->default_lu_gp = NULL; | ||
| 3224 | |||
| 3208 | printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" | 3225 | printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" |
| 3209 | " Infrastructure\n"); | 3226 | " Infrastructure\n"); |
| 3210 | 3227 | ||
| 3211 | remove_scsi_target_mib(); | ||
| 3212 | remove_proc_entry("scsi_target", 0); | ||
| 3213 | core_dev_release_virtual_lun0(); | 3228 | core_dev_release_virtual_lun0(); |
| 3214 | rd_module_exit(); | 3229 | rd_module_exit(); |
| 3215 | release_se_global(); | 3230 | release_se_global(); |
