]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/target/target_core_configfs.c
target: transport_subsystem_check_init cleanups
[linux-2.6.git] / drivers / target / target_core_configfs.c
index 2764510798b0ff80f11ef57fb71f88fad40c048c..1511a2ff86d8b2c75b63a600a1c1fce179509f84 100644 (file)
@@ -3,8 +3,8 @@
  *
  * This file contains ConfigFS logic for the Generic Target Engine project.
  *
- * Copyright (c) 2008-2010 Rising Tide Systems
- * Copyright (c) 2008-2010 Linux-iSCSI.org
+ * Copyright (c) 2008-2011 Rising Tide Systems
+ * Copyright (c) 2008-2011 Linux-iSCSI.org
  *
  * Nicholas A. Bellinger <nab@kernel.org>
  *
@@ -23,7 +23,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
@@ -37,7 +36,7 @@
 #include <linux/parser.h>
 #include <linux/syscalls.h>
 #include <linux/configfs.h>
-#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_device.h>
@@ -51,6 +50,9 @@
 #include "target_core_hba.h"
 #include "target_core_pr.h"
 #include "target_core_rd.h"
+#include "target_core_stat.h"
+
+extern struct t10_alua_lu_gp *default_lu_gp;
 
 static struct list_head g_tf_list;
 static struct mutex g_tf_lock;
@@ -61,6 +63,13 @@ struct target_core_configfs_attribute {
        ssize_t (*store)(void *, const char *, size_t);
 };
 
+static struct config_group target_core_hbagroup;
+static struct config_group alua_group;
+static struct config_group alua_lu_gps_group;
+
+static DEFINE_SPINLOCK(se_device_lock);
+static LIST_HEAD(se_dev_list);
+
 static inline struct se_hba *
 item_to_hba(struct config_item *item)
 {
@@ -94,12 +103,12 @@ static struct target_fabric_configfs *target_core_get_fabric(
 {
        struct target_fabric_configfs *tf;
 
-       if (!(name))
+       if (!name)
                return NULL;
 
        mutex_lock(&g_tf_lock);
        list_for_each_entry(tf, &g_tf_list, tf_list) {
-               if (!(strcmp(tf->tf_name, name))) {
+               if (!strcmp(tf->tf_name, name)) {
                        atomic_inc(&tf->tf_access_cnt);
                        mutex_unlock(&g_tf_lock);
                        return tf;
@@ -120,16 +129,8 @@ static struct config_group *target_core_register_fabric(
        struct target_fabric_configfs *tf;
        int ret;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: REGISTER -> group: %p name:"
+       pr_debug("Target_Core_ConfigFS: REGISTER -> group: %p name:"
                        " %s\n", group, name);
-       /*
-        * Ensure that TCM subsystem plugins are loaded at this point for
-        * using the RAMDISK_DR virtual LUN 0 and all other struct se_port
-        * LUN symlinks.
-        */
-       if (transport_subsystem_check_init() < 0)
-               return ERR_PTR(-EINVAL);
-
        /*
         * Below are some hardcoded request_module() calls to automatically
         * local fabric modules when the following is called:
@@ -140,7 +141,7 @@ static struct config_group *target_core_register_fabric(
         * registered, but simply provids auto loading logic for modules with
         * mkdir(2) system calls with known TCM fabric modules.
         */
-       if (!(strncmp(name, "iscsi", 5))) {
+       if (!strncmp(name, "iscsi", 5)) {
                /*
                 * Automatically load the LIO Target fabric module when the
                 * following is called:
@@ -149,11 +150,11 @@ static struct config_group *target_core_register_fabric(
                 */
                ret = request_module("iscsi_target_mod");
                if (ret < 0) {
-                       printk(KERN_ERR "request_module() failed for"
+                       pr_err("request_module() failed for"
                                " iscsi_target_mod.ko: %d\n", ret);
                        return ERR_PTR(-EINVAL);
                }
-       } else if (!(strncmp(name, "loopback", 8))) {
+       } else if (!strncmp(name, "loopback", 8)) {
                /*
                 * Automatically load the tcm_loop fabric module when the
                 * following is called:
@@ -162,25 +163,25 @@ static struct config_group *target_core_register_fabric(
                 */
                ret = request_module("tcm_loop");
                if (ret < 0) {
-                       printk(KERN_ERR "request_module() failed for"
+                       pr_err("request_module() failed for"
                                " tcm_loop.ko: %d\n", ret);
                        return ERR_PTR(-EINVAL);
                }
        }
 
        tf = target_core_get_fabric(name);
-       if (!(tf)) {
-               printk(KERN_ERR "target_core_get_fabric() failed for %s\n",
+       if (!tf) {
+               pr_err("target_core_get_fabric() failed for %s\n",
                        name);
                return ERR_PTR(-EINVAL);
        }
-       printk(KERN_INFO "Target_Core_ConfigFS: REGISTER -> Located fabric:"
+       pr_debug("Target_Core_ConfigFS: REGISTER -> Located fabric:"
                        " %s\n", tf->tf_name);
        /*
         * On a successful target_core_get_fabric() look, the returned
         * struct target_fabric_configfs *tf will contain a usage reference.
         */
-       printk(KERN_INFO "Target_Core_ConfigFS: REGISTER tfc_wwn_cit -> %p\n",
+       pr_debug("Target_Core_ConfigFS: REGISTER tfc_wwn_cit -> %p\n",
                        &TF_CIT_TMPL(tf)->tfc_wwn_cit);
 
        tf->tf_group.default_groups = tf->tf_default_groups;
@@ -192,14 +193,14 @@ static struct config_group *target_core_register_fabric(
        config_group_init_type_name(&tf->tf_disc_group, "discovery_auth",
                        &TF_CIT_TMPL(tf)->tfc_discovery_cit);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: REGISTER -> Allocated Fabric:"
+       pr_debug("Target_Core_ConfigFS: REGISTER -> Allocated Fabric:"
                        " %s\n", tf->tf_group.cg_item.ci_name);
        /*
         * Setup tf_ops.tf_subsys pointer for usage with configfs_depend_item()
         */
        tf->tf_ops.tf_subsys = tf->tf_subsys;
        tf->tf_fabric = &tf->tf_group.cg_item;
-       printk(KERN_INFO "Target_Core_ConfigFS: REGISTER -> Set tf->tf_fabric"
+       pr_debug("Target_Core_ConfigFS: REGISTER -> Set tf->tf_fabric"
                        " for %s\n", name);
 
        return &tf->tf_group;
@@ -218,18 +219,18 @@ static void target_core_deregister_fabric(
        struct config_item *df_item;
        int i;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: DEREGISTER -> Looking up %s in"
+       pr_debug("Target_Core_ConfigFS: DEREGISTER -> Looking up %s in"
                " tf list\n", config_item_name(item));
 
-       printk(KERN_INFO "Target_Core_ConfigFS: DEREGISTER -> located fabric:"
+       pr_debug("Target_Core_ConfigFS: DEREGISTER -> located fabric:"
                        " %s\n", tf->tf_name);
        atomic_dec(&tf->tf_access_cnt);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: DEREGISTER -> Releasing"
+       pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing"
                        " tf->tf_fabric for %s\n", tf->tf_name);
        tf->tf_fabric = NULL;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: DEREGISTER -> Releasing ci"
+       pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing ci"
                        " %s\n", config_item_name(item));
 
        tf_group = &tf->tf_group;
@@ -296,22 +297,18 @@ struct target_fabric_configfs *target_fabric_configfs_init(
 {
        struct target_fabric_configfs *tf;
 
-       if (!(fabric_mod)) {
-               printk(KERN_ERR "Missing struct module *fabric_mod pointer\n");
-               return NULL;
-       }
        if (!(name)) {
-               printk(KERN_ERR "Unable to locate passed fabric name\n");
-               return NULL;
+               pr_err("Unable to locate passed fabric name\n");
+               return ERR_PTR(-EINVAL);
        }
-       if (strlen(name) > TARGET_FABRIC_NAME_SIZE) {
-               printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
+       if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) {
+               pr_err("Passed name: %s exceeds TARGET_FABRIC"
                        "_NAME_SIZE\n", name);
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
 
        tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
-       if (!(tf))
+       if (!tf)
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&tf->tf_list);
@@ -330,9 +327,9 @@ struct target_fabric_configfs *target_fabric_configfs_init(
        list_add_tail(&tf->tf_list, &g_tf_list);
        mutex_unlock(&g_tf_lock);
 
-       printk(KERN_INFO "<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>"
+       pr_debug("<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>"
                        ">>>>>>>>>>>>>>\n");
-       printk(KERN_INFO "Initialized struct target_fabric_configfs: %p for"
+       pr_debug("Initialized struct target_fabric_configfs: %p for"
                        " %s\n", tf, tf->tf_name);
        return tf;
 }
@@ -361,144 +358,132 @@ static int target_fabric_tf_ops_check(
 {
        struct target_core_fabric_ops *tfo = &tf->tf_ops;
 
-       if (!(tfo->get_fabric_name)) {
-               printk(KERN_ERR "Missing tfo->get_fabric_name()\n");
-               return -EINVAL;
-       }
-       if (!(tfo->get_fabric_proto_ident)) {
-               printk(KERN_ERR "Missing tfo->get_fabric_proto_ident()\n");
-               return -EINVAL;
-       }
-       if (!(tfo->tpg_get_wwn)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_wwn()\n");
-               return -EINVAL;
-       }
-       if (!(tfo->tpg_get_tag)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_tag()\n");
+       if (!tfo->get_fabric_name) {
+               pr_err("Missing tfo->get_fabric_name()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_get_default_depth)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_default_depth()\n");
+       if (!tfo->get_fabric_proto_ident) {
+               pr_err("Missing tfo->get_fabric_proto_ident()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_get_pr_transport_id)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_pr_transport_id()\n");
+       if (!tfo->tpg_get_wwn) {
+               pr_err("Missing tfo->tpg_get_wwn()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_get_pr_transport_id_len)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_pr_transport_id_len()\n");
+       if (!tfo->tpg_get_tag) {
+               pr_err("Missing tfo->tpg_get_tag()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_check_demo_mode)) {
-               printk(KERN_ERR "Missing tfo->tpg_check_demo_mode()\n");
+       if (!tfo->tpg_get_default_depth) {
+               pr_err("Missing tfo->tpg_get_default_depth()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_check_demo_mode_cache)) {
-               printk(KERN_ERR "Missing tfo->tpg_check_demo_mode_cache()\n");
+       if (!tfo->tpg_get_pr_transport_id) {
+               pr_err("Missing tfo->tpg_get_pr_transport_id()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_check_demo_mode_write_protect)) {
-               printk(KERN_ERR "Missing tfo->tpg_check_demo_mode_write_protect()\n");
+       if (!tfo->tpg_get_pr_transport_id_len) {
+               pr_err("Missing tfo->tpg_get_pr_transport_id_len()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_check_prod_mode_write_protect)) {
-               printk(KERN_ERR "Missing tfo->tpg_check_prod_mode_write_protect()\n");
+       if (!tfo->tpg_check_demo_mode) {
+               pr_err("Missing tfo->tpg_check_demo_mode()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_alloc_fabric_acl)) {
-               printk(KERN_ERR "Missing tfo->tpg_alloc_fabric_acl()\n");
+       if (!tfo->tpg_check_demo_mode_cache) {
+               pr_err("Missing tfo->tpg_check_demo_mode_cache()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_release_fabric_acl)) {
-               printk(KERN_ERR "Missing tfo->tpg_release_fabric_acl()\n");
+       if (!tfo->tpg_check_demo_mode_write_protect) {
+               pr_err("Missing tfo->tpg_check_demo_mode_write_protect()\n");
                return -EINVAL;
        }
-       if (!(tfo->tpg_get_inst_index)) {
-               printk(KERN_ERR "Missing tfo->tpg_get_inst_index()\n");
+       if (!tfo->tpg_check_prod_mode_write_protect) {
+               pr_err("Missing tfo->tpg_check_prod_mode_write_protect()\n");
                return -EINVAL;
        }
-       if (!(tfo->release_cmd_to_pool)) {
-               printk(KERN_ERR "Missing tfo->release_cmd_to_pool()\n");
+       if (!tfo->tpg_alloc_fabric_acl) {
+               pr_err("Missing tfo->tpg_alloc_fabric_acl()\n");
                return -EINVAL;
        }
-       if (!(tfo->release_cmd_direct)) {
-               printk(KERN_ERR "Missing tfo->release_cmd_direct()\n");
+       if (!tfo->tpg_release_fabric_acl) {
+               pr_err("Missing tfo->tpg_release_fabric_acl()\n");
                return -EINVAL;
        }
-       if (!(tfo->shutdown_session)) {
-               printk(KERN_ERR "Missing tfo->shutdown_session()\n");
+       if (!tfo->tpg_get_inst_index) {
+               pr_err("Missing tfo->tpg_get_inst_index()\n");
                return -EINVAL;
        }
-       if (!(tfo->close_session)) {
-               printk(KERN_ERR "Missing tfo->close_session()\n");
+       if (!tfo->release_cmd) {
+               pr_err("Missing tfo->release_cmd()\n");
                return -EINVAL;
        }
-       if (!(tfo->stop_session)) {
-               printk(KERN_ERR "Missing tfo->stop_session()\n");
+       if (!tfo->shutdown_session) {
+               pr_err("Missing tfo->shutdown_session()\n");
                return -EINVAL;
        }
-       if (!(tfo->fall_back_to_erl0)) {
-               printk(KERN_ERR "Missing tfo->fall_back_to_erl0()\n");
+       if (!tfo->close_session) {
+               pr_err("Missing tfo->close_session()\n");
                return -EINVAL;
        }
-       if (!(tfo->sess_logged_in)) {
-               printk(KERN_ERR "Missing tfo->sess_logged_in()\n");
+       if (!tfo->stop_session) {
+               pr_err("Missing tfo->stop_session()\n");
                return -EINVAL;
        }
-       if (!(tfo->sess_get_index)) {
-               printk(KERN_ERR "Missing tfo->sess_get_index()\n");
+       if (!tfo->fall_back_to_erl0) {
+               pr_err("Missing tfo->fall_back_to_erl0()\n");
                return -EINVAL;
        }
-       if (!(tfo->write_pending)) {
-               printk(KERN_ERR "Missing tfo->write_pending()\n");
+       if (!tfo->sess_logged_in) {
+               pr_err("Missing tfo->sess_logged_in()\n");
                return -EINVAL;
        }
-       if (!(tfo->write_pending_status)) {
-               printk(KERN_ERR "Missing tfo->write_pending_status()\n");
+       if (!tfo->sess_get_index) {
+               pr_err("Missing tfo->sess_get_index()\n");
                return -EINVAL;
        }
-       if (!(tfo->set_default_node_attributes)) {
-               printk(KERN_ERR "Missing tfo->set_default_node_attributes()\n");
+       if (!tfo->write_pending) {
+               pr_err("Missing tfo->write_pending()\n");
                return -EINVAL;
        }
-       if (!(tfo->get_task_tag)) {
-               printk(KERN_ERR "Missing tfo->get_task_tag()\n");
+       if (!tfo->write_pending_status) {
+               pr_err("Missing tfo->write_pending_status()\n");
                return -EINVAL;
        }
-       if (!(tfo->get_cmd_state)) {
-               printk(KERN_ERR "Missing tfo->get_cmd_state()\n");
+       if (!tfo->set_default_node_attributes) {
+               pr_err("Missing tfo->set_default_node_attributes()\n");
                return -EINVAL;
        }
-       if (!(tfo->new_cmd_failure)) {
-               printk(KERN_ERR "Missing tfo->new_cmd_failure()\n");
+       if (!tfo->get_task_tag) {
+               pr_err("Missing tfo->get_task_tag()\n");
                return -EINVAL;
        }
-       if (!(tfo->queue_data_in)) {
-               printk(KERN_ERR "Missing tfo->queue_data_in()\n");
+       if (!tfo->get_cmd_state) {
+               pr_err("Missing tfo->get_cmd_state()\n");
                return -EINVAL;
        }
-       if (!(tfo->queue_status)) {
-               printk(KERN_ERR "Missing tfo->queue_status()\n");
+       if (!tfo->queue_data_in) {
+               pr_err("Missing tfo->queue_data_in()\n");
                return -EINVAL;
        }
-       if (!(tfo->queue_tm_rsp)) {
-               printk(KERN_ERR "Missing tfo->queue_tm_rsp()\n");
+       if (!tfo->queue_status) {
+               pr_err("Missing tfo->queue_status()\n");
                return -EINVAL;
        }
-       if (!(tfo->set_fabric_sense_len)) {
-               printk(KERN_ERR "Missing tfo->set_fabric_sense_len()\n");
+       if (!tfo->queue_tm_rsp) {
+               pr_err("Missing tfo->queue_tm_rsp()\n");
                return -EINVAL;
        }
-       if (!(tfo->get_fabric_sense_len)) {
-               printk(KERN_ERR "Missing tfo->get_fabric_sense_len()\n");
+       if (!tfo->set_fabric_sense_len) {
+               pr_err("Missing tfo->set_fabric_sense_len()\n");
                return -EINVAL;
        }
-       if (!(tfo->is_state_remove)) {
-               printk(KERN_ERR "Missing tfo->is_state_remove()\n");
+       if (!tfo->get_fabric_sense_len) {
+               pr_err("Missing tfo->get_fabric_sense_len()\n");
                return -EINVAL;
        }
-       if (!(tfo->pack_lun)) {
-               printk(KERN_ERR "Missing tfo->pack_lun()\n");
+       if (!tfo->is_state_remove) {
+               pr_err("Missing tfo->is_state_remove()\n");
                return -EINVAL;
        }
        /*
@@ -506,20 +491,20 @@ static int target_fabric_tf_ops_check(
         * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
         * target_core_fabric_configfs.c WWN+TPG group context code.
         */
-       if (!(tfo->fabric_make_wwn)) {
-               printk(KERN_ERR "Missing tfo->fabric_make_wwn()\n");
+       if (!tfo->fabric_make_wwn) {
+               pr_err("Missing tfo->fabric_make_wwn()\n");
                return -EINVAL;
        }
-       if (!(tfo->fabric_drop_wwn)) {
-               printk(KERN_ERR "Missing tfo->fabric_drop_wwn()\n");
+       if (!tfo->fabric_drop_wwn) {
+               pr_err("Missing tfo->fabric_drop_wwn()\n");
                return -EINVAL;
        }
-       if (!(tfo->fabric_make_tpg)) {
-               printk(KERN_ERR "Missing tfo->fabric_make_tpg()\n");
+       if (!tfo->fabric_make_tpg) {
+               pr_err("Missing tfo->fabric_make_tpg()\n");
                return -EINVAL;
        }
-       if (!(tfo->fabric_drop_tpg)) {
-               printk(KERN_ERR "Missing tfo->fabric_drop_tpg()\n");
+       if (!tfo->fabric_drop_tpg) {
+               pr_err("Missing tfo->fabric_drop_tpg()\n");
                return -EINVAL;
        }
 
@@ -537,22 +522,15 @@ static int target_fabric_tf_ops_check(
 int target_fabric_configfs_register(
        struct target_fabric_configfs *tf)
 {
-       struct config_group *su_group;
        int ret;
 
-       if (!(tf)) {
-               printk(KERN_ERR "Unable to locate target_fabric_configfs"
-                       " pointer\n");
-               return -EINVAL;
-       }
-       if (!(tf->tf_subsys)) {
-               printk(KERN_ERR "Unable to target struct config_subsystem"
+       if (!tf) {
+               pr_err("Unable to locate target_fabric_configfs"
                        " pointer\n");
                return -EINVAL;
        }
-       su_group = &tf->tf_subsys->su_group;
-       if (!(su_group)) {
-               printk(KERN_ERR "Unable to locate target struct config_group"
+       if (!tf->tf_subsys) {
+               pr_err("Unable to target struct config_subsystem"
                        " pointer\n");
                return -EINVAL;
        }
@@ -560,7 +538,7 @@ int target_fabric_configfs_register(
        if (ret < 0)
                return ret;
 
-       printk(KERN_INFO "<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>"
+       pr_debug("<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>"
                ">>>>>>>>>>\n");
        return 0;
 }
@@ -569,48 +547,39 @@ EXPORT_SYMBOL(target_fabric_configfs_register);
 void target_fabric_configfs_deregister(
        struct target_fabric_configfs *tf)
 {
-       struct config_group *su_group;
        struct configfs_subsystem *su;
 
-       if (!(tf)) {
-               printk(KERN_ERR "Unable to locate passed target_fabric_"
+       if (!tf) {
+               pr_err("Unable to locate passed target_fabric_"
                        "configfs\n");
                return;
        }
        su = tf->tf_subsys;
-       if (!(su)) {
-               printk(KERN_ERR "Unable to locate passed tf->tf_subsys"
-                       " pointer\n");
-               return;
-       }
-       su_group = &tf->tf_subsys->su_group;
-       if (!(su_group)) {
-               printk(KERN_ERR "Unable to locate target struct config_group"
+       if (!su) {
+               pr_err("Unable to locate passed tf->tf_subsys"
                        " pointer\n");
                return;
        }
-
-       printk(KERN_INFO "<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>>>"
+       pr_debug("<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>>>"
                        ">>>>>>>>>>>>\n");
        mutex_lock(&g_tf_lock);
        if (atomic_read(&tf->tf_access_cnt)) {
                mutex_unlock(&g_tf_lock);
-               printk(KERN_ERR "Non zero tf->tf_access_cnt for fabric %s\n",
+               pr_err("Non zero tf->tf_access_cnt for fabric %s\n",
                        tf->tf_name);
                BUG();
        }
        list_del(&tf->tf_list);
        mutex_unlock(&g_tf_lock);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: DEREGISTER -> Releasing tf:"
+       pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing tf:"
                        " %s\n", tf->tf_name);
        tf->tf_module = NULL;
        tf->tf_subsys = NULL;
        kfree(tf);
 
-       printk("<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>>>>>>"
+       pr_debug("<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>>>>>>"
                        ">>>>>\n");
-       return;
 }
 EXPORT_SYMBOL(target_fabric_configfs_deregister);
 
@@ -631,11 +600,12 @@ static ssize_t target_core_dev_show_attr_##_name(                 \
                                                                        \
        spin_lock(&se_dev->se_dev_lock);                                \
        dev = se_dev->se_dev_ptr;                                       \
-       if (!(dev)) {                                                   \
+       if (!dev) {                                                     \
                spin_unlock(&se_dev->se_dev_lock);                      \
                return -ENODEV;                                         \
        }                                                               \
-       rb = snprintf(page, PAGE_SIZE, "%u\n", (u32)DEV_ATTRIB(dev)->_name); \
+       rb = snprintf(page, PAGE_SIZE, "%u\n",                          \
+               (u32)dev->se_sub_dev->se_dev_attrib._name);             \
        spin_unlock(&se_dev->se_dev_lock);                              \
                                                                        \
        return rb;                                                      \
@@ -654,14 +624,14 @@ static ssize_t target_core_dev_store_attr_##_name(                        \
                                                                        \
        spin_lock(&se_dev->se_dev_lock);                                \
        dev = se_dev->se_dev_ptr;                                       \
-       if (!(dev)) {                                                   \
+       if (!dev) {                                                     \
                spin_unlock(&se_dev->se_dev_lock);                      \
                return -ENODEV;                                         \
        }                                                               \
        ret = strict_strtoul(page, 0, &val);                            \
        if (ret < 0) {                                                  \
                spin_unlock(&se_dev->se_dev_lock);                      \
-               printk(KERN_ERR "strict_strtoul() failed with"          \
+               pr_err("strict_strtoul() failed with"           \
                        " ret: %d\n", ret);                             \
                return -EINVAL;                                         \
        }                                                               \
@@ -719,6 +689,12 @@ SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR);
 DEF_DEV_ATTRIB(enforce_pr_isids);
 SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);
 
+DEF_DEV_ATTRIB(is_nonrot);
+SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);
+
+DEF_DEV_ATTRIB(emulate_rest_reord);
+SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR);
+
 DEF_DEV_ATTRIB_RO(hw_block_size);
 SE_DEV_ATTR_RO(hw_block_size);
 
@@ -767,6 +743,8 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
        &target_core_dev_attrib_emulate_tpu.attr,
        &target_core_dev_attrib_emulate_tpws.attr,
        &target_core_dev_attrib_enforce_pr_isids.attr,
+       &target_core_dev_attrib_is_nonrot.attr,
+       &target_core_dev_attrib_emulate_rest_reord.attr,
        &target_core_dev_attrib_hw_block_size.attr,
        &target_core_dev_attrib_block_size.attr,
        &target_core_dev_attrib_hw_max_sectors.attr,
@@ -823,7 +801,7 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_unit_serial(
        struct se_device *dev;
 
        dev = se_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
        return sprintf(page, "T10 VPD Unit Serial Number: %s\n",
@@ -850,13 +828,13 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
         * VPD Unit Serial Number that OS dependent multipath can depend on.
         */
        if (su_dev->su_dev_flags & SDF_FIRMWARE_VPD_UNIT_SERIAL) {
-               printk(KERN_ERR "Underlying SCSI device firmware provided VPD"
+               pr_err("Underlying SCSI device firmware provided VPD"
                        " Unit Serial, ignoring request\n");
                return -EOPNOTSUPP;
        }
 
-       if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) {
-               printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
+       if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) {
+               pr_err("Emulated VPD Unit Serial exceeds"
                " INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
                return -EOVERFLOW;
        }
@@ -867,9 +845,9 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
         * could cause negative effects.
         */
        dev = su_dev->se_dev_ptr;
-       if ((dev)) {
+       if (dev) {
                if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
-                       printk(KERN_ERR "Unable to set VPD Unit Serial while"
+                       pr_err("Unable to set VPD Unit Serial while"
                                " active %d $FABRIC_MOD exports exist\n",
                                atomic_read(&dev->dev_export_obj.obj_access_count));
                        return -EINVAL;
@@ -887,7 +865,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
                        "%s", strstrip(buf));
        su_dev->su_dev_flags |= SDF_EMULATED_VPD_UNIT_SERIAL;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Set emulated VPD Unit Serial:"
+       pr_debug("Target_Core_ConfigFS: Set emulated VPD Unit Serial:"
                        " %s\n", su_dev->t10_wwn.unit_serial);
 
        return count;
@@ -909,19 +887,19 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier(
        ssize_t len = 0;
 
        dev = se_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
        memset(buf, 0, VPD_TMP_BUF_SIZE);
 
        spin_lock(&t10_wwn->t10_vpd_lock);
        list_for_each_entry(vpd, &t10_wwn->t10_vpd_list, vpd_list) {
-               if (!(vpd->protocol_identifier_set))
+               if (!vpd->protocol_identifier_set)
                        continue;
 
                transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
 
-               if ((len + strlen(buf) > PAGE_SIZE))
+               if (len + strlen(buf) >= PAGE_SIZE)
                        break;
 
                len += sprintf(page+len, "%s", buf);
@@ -956,7 +934,7 @@ static ssize_t target_core_dev_wwn_show_attr_##_name(                       \
        ssize_t len = 0;                                                \
                                                                        \
        dev = se_dev->se_dev_ptr;                                       \
-       if (!(dev))                                                     \
+       if (!dev)                                                       \
                return -ENODEV;                                         \
                                                                        \
        spin_lock(&t10_wwn->t10_vpd_lock);                              \
@@ -966,19 +944,19 @@ static ssize_t target_core_dev_wwn_show_attr_##_name(                     \
                                                                        \
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
                transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE);   \
-               if ((len + strlen(buf) > PAGE_SIZE))                    \
+               if (len + strlen(buf) >= PAGE_SIZE)                     \
                        break;                                          \
                len += sprintf(page+len, "%s", buf);                    \
                                                                        \
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
                transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \
-               if ((len + strlen(buf) > PAGE_SIZE))                    \
+               if (len + strlen(buf) >= PAGE_SIZE)                     \
                        break;                                          \
                len += sprintf(page+len, "%s", buf);                    \
                                                                        \
                memset(buf, 0, VPD_TMP_BUF_SIZE);                       \
                transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \
-               if ((len + strlen(buf) > PAGE_SIZE))                    \
+               if (len + strlen(buf) >= PAGE_SIZE)                     \
                        break;                                          \
                len += sprintf(page+len, "%s", buf);                    \
        }                                                               \
@@ -988,7 +966,7 @@ static ssize_t target_core_dev_wwn_show_attr_##_name(                       \
 }
 
 /*
- * VPD page 0x83 Assoication: Logical Unit
+ * VPD page 0x83 Association: Logical Unit
  */
 DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_logical_unit, 0x00);
 
@@ -1087,7 +1065,7 @@ static ssize_t target_core_dev_pr_show_spc3_res(
 
        spin_lock(&dev->dev_reservation_lock);
        pr_reg = dev->dev_pr_res_holder;
-       if (!(pr_reg)) {
+       if (!pr_reg) {
                *len += sprintf(page + *len, "No SPC-3 Reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
                return *len;
@@ -1097,7 +1075,7 @@ static ssize_t target_core_dev_pr_show_spc3_res(
                                PR_REG_ISID_ID_LEN);
 
        *len += sprintf(page + *len, "SPC-3 Reservation: %s Initiator: %s%s\n",
-               TPG_TFO(se_nacl->se_tpg)->get_fabric_name(),
+               se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
                se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : "");
        spin_unlock(&dev->dev_reservation_lock);
 
@@ -1113,13 +1091,13 @@ static ssize_t target_core_dev_pr_show_spc2_res(
 
        spin_lock(&dev->dev_reservation_lock);
        se_nacl = dev->dev_reserved_node_acl;
-       if (!(se_nacl)) {
+       if (!se_nacl) {
                *len += sprintf(page + *len, "No SPC-2 Reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
                return *len;
        }
        *len += sprintf(page + *len, "SPC-2 Reservation: %s Initiator: %s\n",
-               TPG_TFO(se_nacl->se_tpg)->get_fabric_name(),
+               se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
                se_nacl->initiatorname);
        spin_unlock(&dev->dev_reservation_lock);
 
@@ -1132,10 +1110,10 @@ static ssize_t target_core_dev_pr_show_attr_res_holder(
 {
        ssize_t len = 0;
 
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       switch (T10_RES(su_dev)->res_type) {
+       switch (su_dev->t10_pr.res_type) {
        case SPC3_PERSISTENT_RESERVATIONS:
                target_core_dev_pr_show_spc3_res(su_dev->se_dev_ptr,
                                page, &len);
@@ -1169,15 +1147,15 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
        ssize_t len = 0;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return len;
 
        spin_lock(&dev->dev_reservation_lock);
        pr_reg = dev->dev_pr_res_holder;
-       if (!(pr_reg)) {
+       if (!pr_reg) {
                len = sprintf(page, "No SPC-3 Reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
                return len;
@@ -1206,13 +1184,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_generation(
        struct se_subsystem_dev *su_dev,
        char *page)
 {
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return 0;
 
-       return sprintf(page, "0x%08x\n", T10_RES(su_dev)->pr_generation);
+       return sprintf(page, "0x%08x\n", su_dev->t10_pr.pr_generation);
 }
 
 SE_DEV_PR_ATTR_RO(res_pr_generation);
@@ -1233,15 +1211,15 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
        ssize_t len = 0;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return len;
 
        spin_lock(&dev->dev_reservation_lock);
        pr_reg = dev->dev_pr_res_holder;
-       if (!(pr_reg)) {
+       if (!pr_reg) {
                len = sprintf(page, "No SPC-3 Reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
                return len;
@@ -1249,7 +1227,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
        se_nacl = pr_reg->pr_reg_nacl;
        se_tpg = se_nacl->se_tpg;
        lun = pr_reg->pr_reg_tg_pt_lun;
-       tfo = TPG_TFO(se_tpg);
+       tfo = se_tpg->se_tpg_tfo;
 
        len += sprintf(page+len, "SPC-3 Reservation: %s"
                " Target Node Endpoint: %s\n", tfo->get_fabric_name(),
@@ -1280,16 +1258,16 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
        ssize_t len = 0;
        int reg_count = 0, prf_isid;
 
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return len;
 
        len += sprintf(page+len, "SPC-3 PR Registrations:\n");
 
-       spin_lock(&T10_RES(su_dev)->registration_lock);
-       list_for_each_entry(pr_reg, &T10_RES(su_dev)->registration_list,
+       spin_lock(&su_dev->t10_pr.registration_lock);
+       list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
                        pr_reg_list) {
 
                memset(buf, 0, 384);
@@ -1303,15 +1281,15 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
                        &i_buf[0] : "", pr_reg->pr_res_key,
                        pr_reg->pr_res_generation);
 
-               if ((len + strlen(buf) > PAGE_SIZE))
+               if (len + strlen(buf) >= PAGE_SIZE)
                        break;
 
                len += sprintf(page+len, "%s", buf);
                reg_count++;
        }
-       spin_unlock(&T10_RES(su_dev)->registration_lock);
+       spin_unlock(&su_dev->t10_pr.registration_lock);
 
-       if (!(reg_count))
+       if (!reg_count)
                len += sprintf(page+len, "None\n");
 
        return len;
@@ -1331,15 +1309,15 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_type(
        ssize_t len = 0;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return len;
 
        spin_lock(&dev->dev_reservation_lock);
        pr_reg = dev->dev_pr_res_holder;
-       if (!(pr_reg)) {
+       if (!pr_reg) {
                len = sprintf(page, "No SPC-3 Reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
                return len;
@@ -1362,10 +1340,10 @@ static ssize_t target_core_dev_pr_show_attr_res_type(
 {
        ssize_t len = 0;
 
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       switch (T10_RES(su_dev)->res_type) {
+       switch (su_dev->t10_pr.res_type) {
        case SPC3_PERSISTENT_RESERVATIONS:
                len = sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n");
                break;
@@ -1393,14 +1371,14 @@ static ssize_t target_core_dev_pr_show_attr_res_aptpl_active(
        struct se_subsystem_dev *su_dev,
        char *page)
 {
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return 0;
 
        return sprintf(page, "APTPL Bit Status: %s\n",
-               (T10_RES(su_dev)->pr_aptpl_active) ? "Activated" : "Disabled");
+               (su_dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled");
 }
 
 SE_DEV_PR_ATTR_RO(res_aptpl_active);
@@ -1412,10 +1390,10 @@ static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata(
        struct se_subsystem_dev *su_dev,
        char *page)
 {
-       if (!(su_dev->se_dev_ptr))
+       if (!su_dev->se_dev_ptr)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return 0;
 
        return sprintf(page, "Ready to process PR APTPL metadata..\n");
@@ -1452,8 +1430,8 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
        size_t count)
 {
        struct se_device *dev;
-       unsigned char *i_fabric, *t_fabric, *i_port = NULL, *t_port = NULL;
-       unsigned char *isid = NULL;
+       unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
+       unsigned char *t_fabric = NULL, *t_port = NULL;
        char *orig, *ptr, *arg_p, *opts;
        substring_t args[MAX_OPT_ARGS];
        unsigned long long tmp_ll;
@@ -1464,14 +1442,14 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
        u8 type = 0, scope;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_RES(su_dev)->res_type != SPC3_PERSISTENT_RESERVATIONS)
+       if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
                return 0;
 
        if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
-               printk(KERN_INFO "Unable to process APTPL metadata while"
+               pr_debug("Unable to process APTPL metadata while"
                        " active fabric exports exist\n");
                return -EINVAL;
        }
@@ -1489,11 +1467,19 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
                switch (token) {
                case Opt_initiator_fabric:
                        i_fabric = match_strdup(&args[0]);
+                       if (!i_fabric) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        break;
                case Opt_initiator_node:
                        i_port = match_strdup(&args[0]);
-                       if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
-                               printk(KERN_ERR "APTPL metadata initiator_node="
+                       if (!i_port) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) {
+                               pr_err("APTPL metadata initiator_node="
                                        " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
                                        PR_APTPL_MAX_IPORT_LEN);
                                ret = -EINVAL;
@@ -1502,8 +1488,12 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
                        break;
                case Opt_initiator_sid:
                        isid = match_strdup(&args[0]);
-                       if (strlen(isid) > PR_REG_ISID_LEN) {
-                               printk(KERN_ERR "APTPL metadata initiator_isid"
+                       if (!isid) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       if (strlen(isid) >= PR_REG_ISID_LEN) {
+                               pr_err("APTPL metadata initiator_isid"
                                        "= exceeds PR_REG_ISID_LEN: %d\n",
                                        PR_REG_ISID_LEN);
                                ret = -EINVAL;
@@ -1512,9 +1502,13 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
                        break;
                case Opt_sa_res_key:
                        arg_p = match_strdup(&args[0]);
+                       if (!arg_p) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        ret = strict_strtoull(arg_p, 0, &tmp_ll);
                        if (ret < 0) {
-                               printk(KERN_ERR "strict_strtoull() failed for"
+                               pr_err("strict_strtoull() failed for"
                                        " sa_res_key=\n");
                                goto out;
                        }
@@ -1548,11 +1542,19 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
                 */
                case Opt_target_fabric:
                        t_fabric = match_strdup(&args[0]);
+                       if (!t_fabric) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
                        break;
                case Opt_target_node:
                        t_port = match_strdup(&args[0]);
-                       if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
-                               printk(KERN_ERR "APTPL metadata target_node="
+                       if (!t_port) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) {
+                               pr_err("APTPL metadata target_node="
                                        " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
                                        PR_APTPL_MAX_TPORT_LEN);
                                ret = -EINVAL;
@@ -1576,23 +1578,28 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
                }
        }
 
-       if (!(i_port) || !(t_port) || !(sa_res_key)) {
-               printk(KERN_ERR "Illegal parameters for APTPL registration\n");
+       if (!i_port || !t_port || !sa_res_key) {
+               pr_err("Illegal parameters for APTPL registration\n");
                ret = -EINVAL;
                goto out;
        }
 
        if (res_holder && !(type)) {
-               printk(KERN_ERR "Illegal PR type: 0x%02x for reservation"
+               pr_err("Illegal PR type: 0x%02x for reservation"
                                " holder\n", type);
                ret = -EINVAL;
                goto out;
        }
 
-       ret = core_scsi3_alloc_aptpl_registration(T10_RES(su_dev), sa_res_key,
+       ret = core_scsi3_alloc_aptpl_registration(&su_dev->t10_pr, sa_res_key,
                        i_port, isid, mapped_lun, t_port, tpgt, target_lun,
                        res_holder, all_tg_pt, type);
 out:
+       kfree(i_fabric);
+       kfree(i_port);
+       kfree(isid);
+       kfree(t_fabric);
+       kfree(t_port);
        kfree(orig);
        return (ret == 0) ? count : ret;
 }
@@ -1637,7 +1644,7 @@ static ssize_t target_core_show_dev_info(void *p, char *page)
        int bl = 0;
        ssize_t read_bytes = 0;
 
-       if (!(se_dev->se_dev_ptr))
+       if (!se_dev->se_dev_ptr)
                return -ENODEV;
 
        transport_dump_dev_state(se_dev->se_dev_ptr, page, &bl);
@@ -1663,8 +1670,8 @@ static ssize_t target_core_store_dev_control(
        struct se_hba *hba = se_dev->se_dev_hba;
        struct se_subsystem_api *t = hba->transport;
 
-       if (!(se_dev->se_dev_su_ptr)) {
-               printk(KERN_ERR "Unable to locate struct se_subsystem_dev>se"
+       if (!se_dev->se_dev_su_ptr) {
+               pr_err("Unable to locate struct se_subsystem_dev>se"
                                "_dev_su_ptr\n");
                return -EINVAL;
        }
@@ -1700,7 +1707,7 @@ static ssize_t target_core_store_dev_alias(
        ssize_t read_bytes;
 
        if (count > (SE_DEV_ALIAS_LEN-1)) {
-               printk(KERN_ERR "alias count: %d exceeds"
+               pr_err("alias count: %d exceeds"
                        " SE_DEV_ALIAS_LEN-1: %u\n", (int)count,
                        SE_DEV_ALIAS_LEN-1);
                return -EINVAL;
@@ -1710,7 +1717,7 @@ static ssize_t target_core_store_dev_alias(
        read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN,
                        "%s", page);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: %s/%s set alias: %s\n",
+       pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n",
                config_item_name(&hba->hba_group.cg_item),
                config_item_name(&se_dev->se_dev_group.cg_item),
                se_dev->se_dev_alias);
@@ -1746,7 +1753,7 @@ static ssize_t target_core_store_dev_udev_path(
        ssize_t read_bytes;
 
        if (count > (SE_UDEV_PATH_LEN-1)) {
-               printk(KERN_ERR "udev_path count: %d exceeds"
+               pr_err("udev_path count: %d exceeds"
                        " SE_UDEV_PATH_LEN-1: %u\n", (int)count,
                        SE_UDEV_PATH_LEN-1);
                return -EINVAL;
@@ -1756,7 +1763,7 @@ static ssize_t target_core_store_dev_udev_path(
        read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN,
                        "%s", page);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: %s/%s set udev_path: %s\n",
+       pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n",
                config_item_name(&hba->hba_group.cg_item),
                config_item_name(&se_dev->se_dev_group.cg_item),
                se_dev->se_dev_udev_path);
@@ -1784,13 +1791,13 @@ static ssize_t target_core_store_dev_enable(
        char *ptr;
 
        ptr = strstr(page, "1");
-       if (!(ptr)) {
-               printk(KERN_ERR "For dev_enable ops, only valid value"
+       if (!ptr) {
+               pr_err("For dev_enable ops, only valid value"
                                " is \"1\"\n");
                return -EINVAL;
        }
-       if ((se_dev->se_dev_ptr)) {
-               printk(KERN_ERR "se_dev->se_dev_ptr already set for storage"
+       if (se_dev->se_dev_ptr) {
+               pr_err("se_dev->se_dev_ptr already set for storage"
                                " object\n");
                return -EEXIST;
        }
@@ -1799,11 +1806,13 @@ static ssize_t target_core_store_dev_enable(
                return -EINVAL;
 
        dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
-       if (!(dev) || IS_ERR(dev))
+       if (IS_ERR(dev))
+               return PTR_ERR(dev);
+       else if (!dev)
                return -EINVAL;
 
        se_dev->se_dev_ptr = dev;
-       printk(KERN_INFO "Target_Core_ConfigFS: Registered se_dev->se_dev_ptr:"
+       pr_debug("Target_Core_ConfigFS: Registered se_dev->se_dev_ptr:"
                " %p\n", se_dev->se_dev_ptr);
 
        return count;
@@ -1827,22 +1836,22 @@ static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
        ssize_t len = 0;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_ALUA(su_dev)->alua_type != SPC3_ALUA_EMULATED)
+       if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
                return len;
 
        lu_gp_mem = dev->dev_alua_lu_gp_mem;
-       if (!(lu_gp_mem)) {
-               printk(KERN_ERR "NULL struct se_device->dev_alua_lu_gp_mem"
+       if (!lu_gp_mem) {
+               pr_err("NULL struct se_device->dev_alua_lu_gp_mem"
                                " pointer\n");
                return -EINVAL;
        }
 
        spin_lock(&lu_gp_mem->lu_gp_mem_lock);
        lu_gp = lu_gp_mem->lu_gp;
-       if ((lu_gp)) {
+       if (lu_gp) {
                lu_ci = &lu_gp->lu_gp_group.cg_item;
                len += sprintf(page, "LU Group Alias: %s\nLU Group ID: %hu\n",
                        config_item_name(lu_ci), lu_gp->lu_gp_id);
@@ -1866,17 +1875,17 @@ static ssize_t target_core_store_alua_lu_gp(
        int move = 0;
 
        dev = su_dev->se_dev_ptr;
-       if (!(dev))
+       if (!dev)
                return -ENODEV;
 
-       if (T10_ALUA(su_dev)->alua_type != SPC3_ALUA_EMULATED) {
-               printk(KERN_WARNING "SPC3_ALUA_EMULATED not enabled for %s/%s\n",
+       if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
+               pr_warn("SPC3_ALUA_EMULATED not enabled for %s/%s\n",
                        config_item_name(&hba->hba_group.cg_item),
                        config_item_name(&su_dev->se_dev_group.cg_item));
                return -EINVAL;
        }
        if (count > LU_GROUP_NAME_BUF) {
-               printk(KERN_ERR "ALUA LU Group Alias too large!\n");
+               pr_err("ALUA LU Group Alias too large!\n");
                return -EINVAL;
        }
        memset(buf, 0, LU_GROUP_NAME_BUF);
@@ -1892,27 +1901,27 @@ static ssize_t target_core_store_alua_lu_gp(
                 * core_alua_get_lu_gp_by_name below().
                 */
                lu_gp_new = core_alua_get_lu_gp_by_name(strstrip(buf));
-               if (!(lu_gp_new))
+               if (!lu_gp_new)
                        return -ENODEV;
        }
        lu_gp_mem = dev->dev_alua_lu_gp_mem;
-       if (!(lu_gp_mem)) {
+       if (!lu_gp_mem) {
                if (lu_gp_new)
                        core_alua_put_lu_gp_from_name(lu_gp_new);
-               printk(KERN_ERR "NULL struct se_device->dev_alua_lu_gp_mem"
+               pr_err("NULL struct se_device->dev_alua_lu_gp_mem"
                                " pointer\n");
                return -EINVAL;
        }
 
        spin_lock(&lu_gp_mem->lu_gp_mem_lock);
        lu_gp = lu_gp_mem->lu_gp;
-       if ((lu_gp)) {
+       if (lu_gp) {
                /*
                 * Clearing an existing lu_gp association, and replacing
                 * with NULL
                 */
-               if (!(lu_gp_new)) {
-                       printk(KERN_INFO "Target_Core_ConfigFS: Releasing %s/%s"
+               if (!lu_gp_new) {
+                       pr_debug("Target_Core_ConfigFS: Releasing %s/%s"
                                " from ALUA LU Group: core/alua/lu_gps/%s, ID:"
                                " %hu\n",
                                config_item_name(&hba->hba_group.cg_item),
@@ -1937,7 +1946,7 @@ static ssize_t target_core_store_alua_lu_gp(
        __core_alua_attach_lu_gp_mem(lu_gp_mem, lu_gp_new);
        spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: %s %s/%s to ALUA LU Group:"
+       pr_debug("Target_Core_ConfigFS: %s %s/%s to ALUA LU Group:"
                " core/alua/lu_gps/%s, ID: %hu\n",
                (move) ? "Moving" : "Adding",
                config_item_name(&hba->hba_group.cg_item),
@@ -1971,13 +1980,35 @@ static void target_core_dev_release(struct config_item *item)
 {
        struct se_subsystem_dev *se_dev = container_of(to_config_group(item),
                                struct se_subsystem_dev, se_dev_group);
-       struct config_group *dev_cg;
-
-       if (!(se_dev))
-               return;
+       struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
+       struct se_subsystem_api *t = hba->transport;
+       struct config_group *dev_cg = &se_dev->se_dev_group;
 
-       dev_cg = &se_dev->se_dev_group;
        kfree(dev_cg->default_groups);
+       /*
+        * This pointer will set when the storage is enabled with:
+        *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable`
+        */
+       if (se_dev->se_dev_ptr) {
+               pr_debug("Target_Core_ConfigFS: Calling se_free_"
+                       "virtual_device() for se_dev_ptr: %p\n",
+                       se_dev->se_dev_ptr);
+
+               se_free_virtual_device(se_dev->se_dev_ptr, hba);
+       } else {
+               /*
+                * Release struct se_subsystem_dev->se_dev_su_ptr..
+                */
+               pr_debug("Target_Core_ConfigFS: Calling t->free_"
+                       "device() for se_dev_su_ptr: %p\n",
+                       se_dev->se_dev_su_ptr);
+
+               t->free_device(se_dev->se_dev_su_ptr);
+       }
+
+       pr_debug("Target_Core_ConfigFS: Deallocating se_subsystem"
+                       "_dev_t: %p\n", se_dev);
+       kfree(se_dev);
 }
 
 static ssize_t target_core_dev_show(struct config_item *item,
@@ -1990,10 +2021,10 @@ static ssize_t target_core_dev_show(struct config_item *item,
        struct target_core_configfs_attribute *tc_attr = container_of(
                        attr, struct target_core_configfs_attribute, attr);
 
-       if (!(tc_attr->show))
+       if (!tc_attr->show)
                return -EINVAL;
 
-       return tc_attr->show((void *)se_dev, page);
+       return tc_attr->show(se_dev, page);
 }
 
 static ssize_t target_core_dev_store(struct config_item *item,
@@ -2006,10 +2037,10 @@ static ssize_t target_core_dev_store(struct config_item *item,
        struct target_core_configfs_attribute *tc_attr = container_of(
                        attr, struct target_core_configfs_attribute, attr);
 
-       if (!(tc_attr->store))
+       if (!tc_attr->store)
                return -EINVAL;
 
-       return tc_attr->store((void *)se_dev, page, count);
+       return tc_attr->store(se_dev, page, count);
 }
 
 static struct configfs_item_operations target_core_dev_item_ops = {
@@ -2049,7 +2080,7 @@ static ssize_t target_core_alua_lu_gp_show_attr_lu_gp_id(
        struct t10_alua_lu_gp *lu_gp,
        char *page)
 {
-       if (!(lu_gp->lu_gp_valid_id))
+       if (!lu_gp->lu_gp_valid_id)
                return 0;
 
        return sprintf(page, "%hu\n", lu_gp->lu_gp_id);
@@ -2066,12 +2097,12 @@ static ssize_t target_core_alua_lu_gp_store_attr_lu_gp_id(
 
        ret = strict_strtoul(page, 0, &lu_gp_id);
        if (ret < 0) {
-               printk(KERN_ERR "strict_strtoul() returned %d for"
+               pr_err("strict_strtoul() returned %d for"
                        " lu_gp_id\n", ret);
                return -EINVAL;
        }
        if (lu_gp_id > 0x0000ffff) {
-               printk(KERN_ERR "ALUA lu_gp_id: %lu exceeds maximum:"
+               pr_err("ALUA lu_gp_id: %lu exceeds maximum:"
                        " 0x0000ffff\n", lu_gp_id);
                return -EINVAL;
        }
@@ -2080,7 +2111,7 @@ static ssize_t target_core_alua_lu_gp_store_attr_lu_gp_id(
        if (ret < 0)
                return -EINVAL;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Set ALUA Logical Unit"
+       pr_debug("Target_Core_ConfigFS: Set ALUA Logical Unit"
                " Group: core/alua/lu_gps/%s to ID: %hu\n",
                config_item_name(&alua_lu_gp_cg->cg_item),
                lu_gp->lu_gp_id);
@@ -2118,7 +2149,7 @@ static ssize_t target_core_alua_lu_gp_show_attr_members(
                cur_len++; /* Extra byte for NULL terminator */
 
                if ((cur_len + len) > PAGE_SIZE) {
-                       printk(KERN_WARNING "Ran out of lu_gp_show_attr"
+                       pr_warn("Ran out of lu_gp_show_attr"
                                "_members buffer\n");
                        break;
                }
@@ -2140,7 +2171,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = {
        NULL,
 };
 
+static void target_core_alua_lu_gp_release(struct config_item *item)
+{
+       struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item),
+                       struct t10_alua_lu_gp, lu_gp_group);
+
+       core_alua_free_lu_gp(lu_gp);
+}
+
 static struct configfs_item_operations target_core_alua_lu_gp_ops = {
+       .release                = target_core_alua_lu_gp_release,
        .show_attribute         = target_core_alua_lu_gp_attr_show,
        .store_attribute        = target_core_alua_lu_gp_attr_store,
 };
@@ -2173,7 +2213,7 @@ static struct config_group *target_core_alua_create_lu_gp(
        config_group_init_type_name(alua_lu_gp_cg, name,
                        &target_core_alua_lu_gp_cit);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Allocated ALUA Logical Unit"
+       pr_debug("Target_Core_ConfigFS: Allocated ALUA Logical Unit"
                " Group: core/alua/lu_gps/%s\n",
                config_item_name(alua_lu_gp_ci));
 
@@ -2188,12 +2228,14 @@ static void target_core_alua_drop_lu_gp(
        struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item),
                        struct t10_alua_lu_gp, lu_gp_group);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit"
+       pr_debug("Target_Core_ConfigFS: Releasing ALUA Logical Unit"
                " Group: core/alua/lu_gps/%s, ID: %hu\n",
                config_item_name(item), lu_gp->lu_gp_id);
-
+       /*
+        * core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release()
+        * -> target_core_alua_lu_gp_release()
+        */
        config_item_put(item);
-       core_alua_free_lu_gp(lu_gp);
 }
 
 static struct configfs_group_operations target_core_alua_lu_gps_group_ops = {
@@ -2245,22 +2287,22 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
        unsigned long tmp;
        int new_state, ret;
 
-       if (!(tg_pt_gp->tg_pt_gp_valid_id)) {
-               printk(KERN_ERR "Unable to do implict ALUA on non valid"
+       if (!tg_pt_gp->tg_pt_gp_valid_id) {
+               pr_err("Unable to do implict ALUA on non valid"
                        " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
                return -EINVAL;
        }
 
        ret = strict_strtoul(page, 0, &tmp);
        if (ret < 0) {
-               printk("Unable to extract new ALUA access state from"
+               pr_err("Unable to extract new ALUA access state from"
                                " %s\n", page);
                return -EINVAL;
        }
        new_state = (int)tmp;
 
        if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICT_ALUA)) {
-               printk(KERN_ERR "Unable to process implict configfs ALUA"
+               pr_err("Unable to process implict configfs ALUA"
                        " transition while TPGS_IMPLICT_ALUA is diabled\n");
                return -EINVAL;
        }
@@ -2291,8 +2333,8 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
        unsigned long tmp;
        int new_status, ret;
 
-       if (!(tg_pt_gp->tg_pt_gp_valid_id)) {
-               printk(KERN_ERR "Unable to do set ALUA access status on non"
+       if (!tg_pt_gp->tg_pt_gp_valid_id) {
+               pr_err("Unable to do set ALUA access status on non"
                        " valid tg_pt_gp ID: %hu\n",
                        tg_pt_gp->tg_pt_gp_valid_id);
                return -EINVAL;
@@ -2300,7 +2342,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
 
        ret = strict_strtoul(page, 0, &tmp);
        if (ret < 0) {
-               printk(KERN_ERR "Unable to extract new ALUA access status"
+               pr_err("Unable to extract new ALUA access status"
                                " from %s\n", page);
                return -EINVAL;
        }
@@ -2309,7 +2351,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_status(
        if ((new_status != ALUA_STATUS_NONE) &&
            (new_status != ALUA_STATUS_ALTERED_BY_EXPLICT_STPG) &&
            (new_status != ALUA_STATUS_ALTERED_BY_IMPLICT_ALUA)) {
-               printk(KERN_ERR "Illegal ALUA access status: 0x%02x\n",
+               pr_err("Illegal ALUA access status: 0x%02x\n",
                                new_status);
                return -EINVAL;
        }
@@ -2360,12 +2402,12 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_write_metadata(
 
        ret = strict_strtoul(page, 0, &tmp);
        if (ret < 0) {
-               printk(KERN_ERR "Unable to extract alua_write_metadata\n");
+               pr_err("Unable to extract alua_write_metadata\n");
                return -EINVAL;
        }
 
        if ((tmp != 0) && (tmp != 1)) {
-               printk(KERN_ERR "Illegal value for alua_write_metadata:"
+               pr_err("Illegal value for alua_write_metadata:"
                        " %lu\n", tmp);
                return -EINVAL;
        }
@@ -2447,7 +2489,7 @@ static ssize_t target_core_alua_tg_pt_gp_show_attr_tg_pt_gp_id(
        struct t10_alua_tg_pt_gp *tg_pt_gp,
        char *page)
 {
-       if (!(tg_pt_gp->tg_pt_gp_valid_id))
+       if (!tg_pt_gp->tg_pt_gp_valid_id)
                return 0;
 
        return sprintf(page, "%hu\n", tg_pt_gp->tg_pt_gp_id);
@@ -2464,12 +2506,12 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_tg_pt_gp_id(
 
        ret = strict_strtoul(page, 0, &tg_pt_gp_id);
        if (ret < 0) {
-               printk(KERN_ERR "strict_strtoul() returned %d for"
+               pr_err("strict_strtoul() returned %d for"
                        " tg_pt_gp_id\n", ret);
                return -EINVAL;
        }
        if (tg_pt_gp_id > 0x0000ffff) {
-               printk(KERN_ERR "ALUA tg_pt_gp_id: %lu exceeds maximum:"
+               pr_err("ALUA tg_pt_gp_id: %lu exceeds maximum:"
                        " 0x0000ffff\n", tg_pt_gp_id);
                return -EINVAL;
        }
@@ -2478,7 +2520,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_tg_pt_gp_id(
        if (ret < 0)
                return -EINVAL;
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Set ALUA Target Port Group: "
+       pr_debug("Target_Core_ConfigFS: Set ALUA Target Port Group: "
                "core/alua/tg_pt_gps/%s to ID: %hu\n",
                config_item_name(&alua_tg_pt_gp_cg->cg_item),
                tg_pt_gp->tg_pt_gp_id);
@@ -2512,14 +2554,14 @@ static ssize_t target_core_alua_tg_pt_gp_show_attr_members(
                lun = port->sep_lun;
 
                cur_len = snprintf(buf, TG_PT_GROUP_NAME_BUF, "%s/%s/tpgt_%hu"
-                       "/%s\n", TPG_TFO(tpg)->get_fabric_name(),
-                       TPG_TFO(tpg)->tpg_get_wwn(tpg),
-                       TPG_TFO(tpg)->tpg_get_tag(tpg),
+                       "/%s\n", tpg->se_tpg_tfo->get_fabric_name(),
+                       tpg->se_tpg_tfo->tpg_get_wwn(tpg),
+                       tpg->se_tpg_tfo->tpg_get_tag(tpg),
                        config_item_name(&lun->lun_group.cg_item));
                cur_len++; /* Extra byte for NULL terminator */
 
                if ((cur_len + len) > PAGE_SIZE) {
-                       printk(KERN_WARNING "Ran out of lu_gp_show_attr"
+                       pr_warn("Ran out of lu_gp_show_attr"
                                "_members buffer\n");
                        break;
                }
@@ -2549,7 +2591,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
        NULL,
 };
 
+static void target_core_alua_tg_pt_gp_release(struct config_item *item)
+{
+       struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item),
+                       struct t10_alua_tg_pt_gp, tg_pt_gp_group);
+
+       core_alua_free_tg_pt_gp(tg_pt_gp);
+}
+
 static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = {
+       .release                = target_core_alua_tg_pt_gp_release,
        .show_attribute         = target_core_alua_tg_pt_gp_attr_show,
        .store_attribute        = target_core_alua_tg_pt_gp_attr_store,
 };
@@ -2576,7 +2627,7 @@ static struct config_group *target_core_alua_create_tg_pt_gp(
        struct config_item *alua_tg_pt_gp_ci = NULL;
 
        tg_pt_gp = core_alua_allocate_tg_pt_gp(su_dev, name, 0);
-       if (!(tg_pt_gp))
+       if (!tg_pt_gp)
                return NULL;
 
        alua_tg_pt_gp_cg = &tg_pt_gp->tg_pt_gp_group;
@@ -2585,7 +2636,7 @@ static struct config_group *target_core_alua_create_tg_pt_gp(
        config_group_init_type_name(alua_tg_pt_gp_cg, name,
                        &target_core_alua_tg_pt_gp_cit);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Allocated ALUA Target Port"
+       pr_debug("Target_Core_ConfigFS: Allocated ALUA Target Port"
                " Group: alua/tg_pt_gps/%s\n",
                config_item_name(alua_tg_pt_gp_ci));
 
@@ -2599,12 +2650,14 @@ static void target_core_alua_drop_tg_pt_gp(
        struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item),
                        struct t10_alua_tg_pt_gp, tg_pt_gp_group);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port"
+       pr_debug("Target_Core_ConfigFS: Releasing ALUA Target Port"
                " Group: alua/tg_pt_gps/%s, ID: %hu\n",
                config_item_name(item), tg_pt_gp->tg_pt_gp_id);
-
+       /*
+        * core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release()
+        * -> target_core_alua_tg_pt_gp_release().
+        */
        config_item_put(item);
-       core_alua_free_tg_pt_gp(tg_pt_gp);
 }
 
 static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = {
@@ -2635,6 +2688,34 @@ static struct config_item_type target_core_alua_cit = {
 
 /* End functions for struct config_item_type target_core_alua_cit */
 
+/* Start functions for struct config_item_type target_core_stat_cit */
+
+static struct config_group *target_core_stat_mkdir(
+       struct config_group *group,
+       const char *name)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static void target_core_stat_rmdir(
+       struct config_group *group,
+       struct config_item *item)
+{
+       return;
+}
+
+static struct configfs_group_operations target_core_stat_group_ops = {
+       .make_group             = &target_core_stat_mkdir,
+       .drop_item              = &target_core_stat_rmdir,
+};
+
+static struct config_item_type target_core_stat_cit = {
+       .ct_group_ops           = &target_core_stat_group_ops,
+       .ct_owner               = THIS_MODULE,
+};
+
+/* End functions for struct config_item_type target_core_stat_cit */
+
 /* Start functions for struct config_item_type target_core_hba_cit */
 
 static struct config_group *target_core_make_subdev(
@@ -2647,10 +2728,12 @@ static struct config_group *target_core_make_subdev(
        struct config_item *hba_ci = &group->cg_item;
        struct se_hba *hba = item_to_hba(hba_ci);
        struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
+       struct config_group *dev_stat_grp = NULL;
+       int errno = -ENOMEM, ret;
 
-       if (mutex_lock_interruptible(&hba->hba_access_mutex))
-               return NULL;
-
+       ret = mutex_lock_interruptible(&hba->hba_access_mutex);
+       if (ret)
+               return ERR_PTR(ret);
        /*
         * Locate the struct se_subsystem_api from parent's struct se_hba.
         */
@@ -2658,21 +2741,21 @@ static struct config_group *target_core_make_subdev(
 
        se_dev = kzalloc(sizeof(struct se_subsystem_dev), GFP_KERNEL);
        if (!se_dev) {
-               printk(KERN_ERR "Unable to allocate memory for"
+               pr_err("Unable to allocate memory for"
                                " struct se_subsystem_dev\n");
                goto unlock;
        }
-       INIT_LIST_HEAD(&se_dev->g_se_dev_list);
+       INIT_LIST_HEAD(&se_dev->se_dev_node);
        INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list);
        spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock);
-       INIT_LIST_HEAD(&se_dev->t10_reservation.registration_list);
-       INIT_LIST_HEAD(&se_dev->t10_reservation.aptpl_reg_list);
-       spin_lock_init(&se_dev->t10_reservation.registration_lock);
-       spin_lock_init(&se_dev->t10_reservation.aptpl_reg_lock);
+       INIT_LIST_HEAD(&se_dev->t10_pr.registration_list);
+       INIT_LIST_HEAD(&se_dev->t10_pr.aptpl_reg_list);
+       spin_lock_init(&se_dev->t10_pr.registration_lock);
+       spin_lock_init(&se_dev->t10_pr.aptpl_reg_lock);
        INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list);
        spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock);
        spin_lock_init(&se_dev->se_dev_lock);
-       se_dev->t10_reservation.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
+       se_dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
        se_dev->t10_wwn.t10_sub_dev = se_dev;
        se_dev->t10_alua.t10_sub_dev = se_dev;
        se_dev->se_dev_attrib.da_sub_dev = se_dev;
@@ -2680,9 +2763,9 @@ static struct config_group *target_core_make_subdev(
        se_dev->se_dev_hba = hba;
        dev_cg = &se_dev->se_dev_group;
 
-       dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 6,
+       dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7,
                        GFP_KERNEL);
-       if (!(dev_cg->default_groups))
+       if (!dev_cg->default_groups)
                goto out;
        /*
         * Set se_dev_su_ptr from struct se_subsystem_api returned void ptr
@@ -2693,14 +2776,14 @@ static struct config_group *target_core_make_subdev(
         * configfs tree for device object's struct config_group.
         */
        se_dev->se_dev_su_ptr = t->allocate_virtdevice(hba, name);
-       if (!(se_dev->se_dev_su_ptr)) {
-               printk(KERN_ERR "Unable to locate subsystem dependent pointer"
+       if (!se_dev->se_dev_su_ptr) {
+               pr_err("Unable to locate subsystem dependent pointer"
                        " from allocate_virtdevice()\n");
                goto out;
        }
-       spin_lock(&se_global->g_device_lock);
-       list_add_tail(&se_dev->g_se_dev_list, &se_global->g_se_dev_list);
-       spin_unlock(&se_global->g_device_lock);
+       spin_lock(&se_device_lock);
+       list_add_tail(&se_dev->se_dev_node, &se_dev_list);
+       spin_unlock(&se_device_lock);
 
        config_group_init_type_name(&se_dev->se_dev_group, name,
                        &target_core_dev_cit);
@@ -2712,23 +2795,27 @@ static struct config_group *target_core_make_subdev(
                        &target_core_dev_wwn_cit);
        config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
                        "alua", &target_core_alua_tg_pt_gps_cit);
+       config_group_init_type_name(&se_dev->dev_stat_grps.stat_group,
+                       "statistics", &target_core_stat_cit);
+
        dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
        dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
        dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group;
        dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group;
-       dev_cg->default_groups[4] = NULL;
+       dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group;
+       dev_cg->default_groups[5] = NULL;
        /*
-        * Add core/$HBA/$DEV/alua/tg_pt_gps/default_tg_pt_gp
+        * Add core/$HBA/$DEV/alua/default_tg_pt_gp
         */
        tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
-       if (!(tg_pt_gp))
+       if (!tg_pt_gp)
                goto out;
 
-       tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
+       tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group;
        tg_pt_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
                                GFP_KERNEL);
-       if (!(tg_pt_gp_cg->default_groups)) {
-               printk(KERN_ERR "Unable to allocate tg_pt_gp_cg->"
+       if (!tg_pt_gp_cg->default_groups) {
+               pr_err("Unable to allocate tg_pt_gp_cg->"
                                "default_groups\n");
                goto out;
        }
@@ -2737,18 +2824,31 @@ static struct config_group *target_core_make_subdev(
                        "default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit);
        tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
        tg_pt_gp_cg->default_groups[1] = NULL;
-       T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp;
+       se_dev->t10_alua.default_tg_pt_gp = tg_pt_gp;
+       /*
+        * Add core/$HBA/$DEV/statistics/ default groups
+        */
+       dev_stat_grp = &se_dev->dev_stat_grps.stat_group;
+       dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4,
+                               GFP_KERNEL);
+       if (!dev_stat_grp->default_groups) {
+               pr_err("Unable to allocate dev_stat_grp->default_groups\n");
+               goto out;
+       }
+       target_stat_setup_dev_default_groups(se_dev);
 
-       printk(KERN_INFO "Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
+       pr_debug("Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
                " %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
 
        mutex_unlock(&hba->hba_access_mutex);
        return &se_dev->se_dev_group;
 out:
-       if (T10_ALUA(se_dev)->default_tg_pt_gp) {
-               core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
-               T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
+       if (se_dev->t10_alua.default_tg_pt_gp) {
+               core_alua_free_tg_pt_gp(se_dev->t10_alua.default_tg_pt_gp);
+               se_dev->t10_alua.default_tg_pt_gp = NULL;
        }
+       if (dev_stat_grp)
+               kfree(dev_stat_grp->default_groups);
        if (tg_pt_gp_cg)
                kfree(tg_pt_gp_cg->default_groups);
        if (dev_cg)
@@ -2758,7 +2858,7 @@ out:
        kfree(se_dev);
 unlock:
        mutex_unlock(&hba->hba_access_mutex);
-       return NULL;
+       return ERR_PTR(errno);
 }
 
 static void target_core_drop_subdev(
@@ -2770,29 +2870,38 @@ static void target_core_drop_subdev(
        struct se_hba *hba;
        struct se_subsystem_api *t;
        struct config_item *df_item;
-       struct config_group *dev_cg, *tg_pt_gp_cg;
-       int i, ret;
+       struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp;
+       int i;
 
        hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
 
-       if (mutex_lock_interruptible(&hba->hba_access_mutex))
-               goto out;
-
+       mutex_lock(&hba->hba_access_mutex);
        t = hba->transport;
 
-       spin_lock(&se_global->g_device_lock);
-       list_del(&se_dev->g_se_dev_list);
-       spin_unlock(&se_global->g_device_lock);
+       spin_lock(&se_device_lock);
+       list_del(&se_dev->se_dev_node);
+       spin_unlock(&se_device_lock);
 
-       tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
+       dev_stat_grp = &se_dev->dev_stat_grps.stat_group;
+       for (i = 0; dev_stat_grp->default_groups[i]; i++) {
+               df_item = &dev_stat_grp->default_groups[i]->cg_item;
+               dev_stat_grp->default_groups[i] = NULL;
+               config_item_put(df_item);
+       }
+       kfree(dev_stat_grp->default_groups);
+
+       tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group;
        for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
                df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
                tg_pt_gp_cg->default_groups[i] = NULL;
                config_item_put(df_item);
        }
        kfree(tg_pt_gp_cg->default_groups);
-       core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
-       T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
+       /*
+        * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp
+        * directly from target_core_alua_tg_pt_gp_release().
+        */
+       se_dev->t10_alua.default_tg_pt_gp = NULL;
 
        dev_cg = &se_dev->se_dev_group;
        for (i = 0; dev_cg->default_groups[i]; i++) {
@@ -2800,38 +2909,12 @@ static void target_core_drop_subdev(
                dev_cg->default_groups[i] = NULL;
                config_item_put(df_item);
        }
-
-       config_item_put(item);
        /*
-        * This pointer will set when the storage is enabled with:
-        * `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable`
+        * The releasing of se_dev and associated se_dev->se_dev_ptr is done
+        * from target_core_dev_item_ops->release() ->target_core_dev_release().
         */
-       if (se_dev->se_dev_ptr) {
-               printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_"
-                       "virtual_device() for se_dev_ptr: %p\n",
-                               se_dev->se_dev_ptr);
-
-               ret = se_free_virtual_device(se_dev->se_dev_ptr, hba);
-               if (ret < 0)
-                       goto hba_out;
-       } else {
-               /*
-                * Release struct se_subsystem_dev->se_dev_su_ptr..
-                */
-               printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_"
-                       "device() for se_dev_su_ptr: %p\n",
-                       se_dev->se_dev_su_ptr);
-
-               t->free_device(se_dev->se_dev_su_ptr);
-       }
-
-       printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem"
-               "_dev_t: %p\n", se_dev);
-
-hba_out:
+       config_item_put(item);
        mutex_unlock(&hba->hba_access_mutex);
-out:
-       kfree(se_dev);
 }
 
 static struct configfs_group_operations target_core_hba_group_ops = {
@@ -2887,13 +2970,13 @@ static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
 
        ret = strict_strtoul(page, 0, &mode_flag);
        if (ret < 0) {
-               printk(KERN_ERR "Unable to extract hba mode flag: %d\n", ret);
+               pr_err("Unable to extract hba mode flag: %d\n", ret);
                return -EINVAL;
        }
 
        spin_lock(&hba->device_lock);
-       if (!(list_empty(&hba->hba_dev_list))) {
-               printk(KERN_ERR "Unable to set hba_mode with active devices\n");
+       if (!list_empty(&hba->hba_dev_list)) {
+               pr_err("Unable to set hba_mode with active devices\n");
                spin_unlock(&hba->device_lock);
                return -EINVAL;
        }
@@ -2914,6 +2997,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR);
 
 CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group);
 
+static void target_core_hba_release(struct config_item *item)
+{
+       struct se_hba *hba = container_of(to_config_group(item),
+                               struct se_hba, hba_group);
+       core_delete_hba(hba);
+}
+
 static struct configfs_attribute *target_core_hba_attrs[] = {
        &target_core_hba_hba_info.attr,
        &target_core_hba_hba_mode.attr,
@@ -2921,6 +3011,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = {
 };
 
 static struct configfs_item_operations target_core_hba_item_ops = {
+       .release                = target_core_hba_release,
        .show_attribute         = target_core_hba_attr_show,
        .store_attribute        = target_core_hba_attr_store,
 };
@@ -2943,8 +3034,8 @@ static struct config_group *target_core_call_addhbatotarget(
        int ret;
 
        memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
-       if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) {
-               printk(KERN_ERR "Passed *name strlen(): %d exceeds"
+       if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) {
+               pr_err("Passed *name strlen(): %d exceeds"
                        " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
                        TARGET_CORE_NAME_MAX_LEN);
                return ERR_PTR(-ENAMETOOLONG);
@@ -2952,8 +3043,8 @@ static struct config_group *target_core_call_addhbatotarget(
        snprintf(buf, TARGET_CORE_NAME_MAX_LEN, "%s", name);
 
        str = strstr(buf, "_");
-       if (!(str)) {
-               printk(KERN_ERR "Unable to locate \"_\" for $SUBSYSTEM_PLUGIN_$HOST_ID\n");
+       if (!str) {
+               pr_err("Unable to locate \"_\" for $SUBSYSTEM_PLUGIN_$HOST_ID\n");
                return ERR_PTR(-EINVAL);
        }
        se_plugin_str = buf;
@@ -2962,7 +3053,7 @@ static struct config_group *target_core_call_addhbatotarget(
         * Namely rd_direct and rd_mcp..
         */
        str2 = strstr(str+1, "_");
-       if ((str2)) {
+       if (str2) {
                *str2 = '\0'; /* Terminate for *se_plugin_str */
                str2++; /* Skip to start of plugin dependent ID */
                str = str2;
@@ -2973,15 +3064,14 @@ static struct config_group *target_core_call_addhbatotarget(
 
        ret = strict_strtoul(str, 0, &plugin_dep_id);
        if (ret < 0) {
-               printk(KERN_ERR "strict_strtoul() returned %d for"
+               pr_err("strict_strtoul() returned %d for"
                                " plugin_dep_id\n", ret);
                return ERR_PTR(-EINVAL);
        }
        /*
         * Load up TCM subsystem plugins if they have not already been loaded.
         */
-       if (transport_subsystem_check_init() < 0)
-               return ERR_PTR(-EINVAL);
+       transport_subsystem_check_init();
 
        hba = core_alloc_hba(se_plugin_str, plugin_dep_id, 0);
        if (IS_ERR(hba))
@@ -2997,10 +3087,11 @@ static void target_core_call_delhbafromtarget(
        struct config_group *group,
        struct config_item *item)
 {
-       struct se_hba *hba = item_to_hba(item);
-
+       /*
+        * core_delete_hba() is called from target_core_hba_item_ops->release()
+        * -> target_core_hba_release()
+        */
        config_item_put(item);
-       core_delete_hba(hba);
 }
 
 static struct configfs_group_operations target_core_group_ops = {
@@ -3017,16 +3108,15 @@ static struct config_item_type target_core_cit = {
 
 /* Stop functions for struct config_item_type target_core_hba_cit */
 
-static int target_core_init_configfs(void)
+static int __init target_core_init_configfs(void)
 {
        struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
        struct config_group *lu_gp_cg = NULL;
        struct configfs_subsystem *subsys;
-       struct proc_dir_entry *scsi_target_proc = NULL;
        struct t10_alua_lu_gp *lu_gp;
        int ret;
 
-       printk(KERN_INFO "TARGET_CORE[0]: Loading Generic Kernel Storage"
+       pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage"
                " Engine: %s on %s/%s on "UTS_RELEASE"\n",
                TARGET_CORE_VERSION, utsname()->sysname, utsname()->machine);
 
@@ -3036,10 +3126,9 @@ static int target_core_init_configfs(void)
 
        INIT_LIST_HEAD(&g_tf_list);
        mutex_init(&g_tf_lock);
-       init_scsi_index_table();
-       ret = init_se_global();
+       ret = init_se_kmem_caches();
        if (ret < 0)
-               return -1;
+               return ret;
        /*
         * Create $CONFIGFS/target/core default group for HBA <-> Storage Object
         * and ALUA Logical Unit Group and Target Port Group infrastructure.
@@ -3047,44 +3136,44 @@ static int target_core_init_configfs(void)
        target_cg = &subsys->su_group;
        target_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
                                GFP_KERNEL);
-       if (!(target_cg->default_groups)) {
-               printk(KERN_ERR "Unable to allocate target_cg->default_groups\n");
+       if (!target_cg->default_groups) {
+               pr_err("Unable to allocate target_cg->default_groups\n");
                goto out_global;
        }
 
-       config_group_init_type_name(&se_global->target_core_hbagroup,
+       config_group_init_type_name(&target_core_hbagroup,
                        "core", &target_core_cit);
-       target_cg->default_groups[0] = &se_global->target_core_hbagroup;
+       target_cg->default_groups[0] = &target_core_hbagroup;
        target_cg->default_groups[1] = NULL;
        /*
         * Create ALUA infrastructure under /sys/kernel/config/target/core/alua/
         */
-       hba_cg = &se_global->target_core_hbagroup;
+       hba_cg = &target_core_hbagroup;
        hba_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
                                GFP_KERNEL);
-       if (!(hba_cg->default_groups)) {
-               printk(KERN_ERR "Unable to allocate hba_cg->default_groups\n");
+       if (!hba_cg->default_groups) {
+               pr_err("Unable to allocate hba_cg->default_groups\n");
                goto out_global;
        }
-       config_group_init_type_name(&se_global->alua_group,
+       config_group_init_type_name(&alua_group,
                        "alua", &target_core_alua_cit);
-       hba_cg->default_groups[0] = &se_global->alua_group;
+       hba_cg->default_groups[0] = &alua_group;
        hba_cg->default_groups[1] = NULL;
        /*
         * Add ALUA Logical Unit Group and Target Port Group ConfigFS
         * groups under /sys/kernel/config/target/core/alua/
         */
-       alua_cg = &se_global->alua_group;
+       alua_cg = &alua_group;
        alua_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
                        GFP_KERNEL);
-       if (!(alua_cg->default_groups)) {
-               printk(KERN_ERR "Unable to allocate alua_cg->default_groups\n");
+       if (!alua_cg->default_groups) {
+               pr_err("Unable to allocate alua_cg->default_groups\n");
                goto out_global;
        }
 
-       config_group_init_type_name(&se_global->alua_lu_gps_group,
+       config_group_init_type_name(&alua_lu_gps_group,
                        "lu_gps", &target_core_alua_lu_gps_cit);
-       alua_cg->default_groups[0] = &se_global->alua_lu_gps_group;
+       alua_cg->default_groups[0] = &alua_lu_gps_group;
        alua_cg->default_groups[1] = NULL;
        /*
         * Add core/alua/lu_gps/default_lu_gp
@@ -3093,11 +3182,11 @@ static int target_core_init_configfs(void)
        if (IS_ERR(lu_gp))
                goto out_global;
 
-       lu_gp_cg = &se_global->alua_lu_gps_group;
+       lu_gp_cg = &alua_lu_gps_group;
        lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
                        GFP_KERNEL);
-       if (!(lu_gp_cg->default_groups)) {
-               printk(KERN_ERR "Unable to allocate lu_gp_cg->default_groups\n");
+       if (!lu_gp_cg->default_groups) {
+               pr_err("Unable to allocate lu_gp_cg->default_groups\n");
                goto out_global;
        }
 
@@ -3105,17 +3194,17 @@ static int target_core_init_configfs(void)
                                &target_core_alua_lu_gp_cit);
        lu_gp_cg->default_groups[0] = &lu_gp->lu_gp_group;
        lu_gp_cg->default_groups[1] = NULL;
-       se_global->default_lu_gp = lu_gp;
+       default_lu_gp = lu_gp;
        /*
         * Register the target_core_mod subsystem with configfs.
         */
        ret = configfs_register_subsystem(subsys);
        if (ret < 0) {
-               printk(KERN_ERR "Error %d while registering subsystem %s\n",
+               pr_err("Error %d while registering subsystem %s\n",
                        ret, subsys->su_group.cg_item.ci_namebuf);
                goto out_global;
        }
-       printk(KERN_INFO "TARGET_CORE[0]: Initialized ConfigFS Fabric"
+       pr_debug("TARGET_CORE[0]: Initialized ConfigFS Fabric"
                " Infrastructure: "TARGET_CORE_CONFIGFS_VERSION" on %s/%s"
                " on "UTS_RELEASE"\n", utsname()->sysname, utsname()->machine);
        /*
@@ -3128,27 +3217,16 @@ static int target_core_init_configfs(void)
        if (core_dev_setup_virtual_lun0() < 0)
                goto out;
 
-       scsi_target_proc = proc_mkdir("scsi_target", 0);
-       if (!(scsi_target_proc)) {
-               printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n");
-               goto out;
-       }
-       ret = init_scsi_target_mib();
-       if (ret < 0)
-               goto out;
-
        return 0;
 
 out:
        configfs_unregister_subsystem(subsys);
-       if (scsi_target_proc)
-               remove_proc_entry("scsi_target", 0);
        core_dev_release_virtual_lun0();
        rd_module_exit();
 out_global:
-       if (se_global->default_lu_gp) {
-               core_alua_free_lu_gp(se_global->default_lu_gp);
-               se_global->default_lu_gp = NULL;
+       if (default_lu_gp) {
+               core_alua_free_lu_gp(default_lu_gp);
+               default_lu_gp = NULL;
        }
        if (lu_gp_cg)
                kfree(lu_gp_cg->default_groups);
@@ -3157,64 +3235,61 @@ out_global:
        if (hba_cg)
                kfree(hba_cg->default_groups);
        kfree(target_cg->default_groups);
-       release_se_global();
-       return -1;
+       release_se_kmem_caches();
+       return ret;
 }
 
-static void target_core_exit_configfs(void)
+static void __exit target_core_exit_configfs(void)
 {
        struct configfs_subsystem *subsys;
        struct config_group *hba_cg, *alua_cg, *lu_gp_cg;
        struct config_item *item;
        int i;
 
-       se_global->in_shutdown = 1;
        subsys = target_core_subsystem[0];
 
-       lu_gp_cg = &se_global->alua_lu_gps_group;
+       lu_gp_cg = &alua_lu_gps_group;
        for (i = 0; lu_gp_cg->default_groups[i]; i++) {
                item = &lu_gp_cg->default_groups[i]->cg_item;
                lu_gp_cg->default_groups[i] = NULL;
                config_item_put(item);
        }
        kfree(lu_gp_cg->default_groups);
-       core_alua_free_lu_gp(se_global->default_lu_gp);
-       se_global->default_lu_gp = NULL;
+       lu_gp_cg->default_groups = NULL;
 
-       alua_cg = &se_global->alua_group;
+       alua_cg = &alua_group;
        for (i = 0; alua_cg->default_groups[i]; i++) {
                item = &alua_cg->default_groups[i]->cg_item;
                alua_cg->default_groups[i] = NULL;
                config_item_put(item);
        }
        kfree(alua_cg->default_groups);
+       alua_cg->default_groups = NULL;
 
-       hba_cg = &se_global->target_core_hbagroup;
+       hba_cg = &target_core_hbagroup;
        for (i = 0; hba_cg->default_groups[i]; i++) {
                item = &hba_cg->default_groups[i]->cg_item;
                hba_cg->default_groups[i] = NULL;
                config_item_put(item);
        }
        kfree(hba_cg->default_groups);
-
-       for (i = 0; subsys->su_group.default_groups[i]; i++) {
-               item = &subsys->su_group.default_groups[i]->cg_item;
-               subsys->su_group.default_groups[i] = NULL;
-               config_item_put(item);
-       }
+       hba_cg->default_groups = NULL;
+       /*
+        * We expect subsys->su_group.default_groups to be released
+        * by configfs subsystem provider logic..
+        */
+       configfs_unregister_subsystem(subsys);
        kfree(subsys->su_group.default_groups);
 
-       configfs_unregister_subsystem(subsys);
-       printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric"
+       core_alua_free_lu_gp(default_lu_gp);
+       default_lu_gp = NULL;
+
+       pr_debug("TARGET_CORE[0]: Released ConfigFS Fabric"
                        " Infrastructure\n");
 
-       remove_scsi_target_mib();
-       remove_proc_entry("scsi_target", 0);
        core_dev_release_virtual_lun0();
        rd_module_exit();
-       release_se_global();
-
-       return;
+       release_se_kmem_caches();
 }
 
 MODULE_DESCRIPTION("Target_Core_Mod/ConfigFS");