Instead of allocating the tpg_lun_list and each member of the list when
the tpg is created, just create the tpg_lun_list array, and use an
element being non-NULL to indicate an active LUN. This will save memory
if less than all the se_luns are actually configured.

Now that things are actually getting freed, split out core_tpg_free_lun
from core_tpg_remove_lun, because we don't want to free() the statically-
allocated virtual_lun0.

Remove array_free and array_zalloc.

Remove core_get_lun_from_tpg and core_dev_get_lun.

Change core_dev_add_lun to take a se_lun and return int

Signed-off-by: Andy Grover <agro...@redhat.com>
---
 drivers/target/sbp/sbp_target.c              |  6 +-
 drivers/target/target_core_device.c          | 80 +++---------------------
 drivers/target/target_core_fabric_configfs.c | 21 +++----
 drivers/target/target_core_internal.h        |  4 +-
 drivers/target/target_core_tpg.c             | 92 ++++++++++------------------
 include/target/target_core_base.h            |  8 ---
 6 files changed, 57 insertions(+), 154 deletions(-)

diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 24884ca..bee56e5 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -187,7 +187,7 @@ static struct se_lun *sbp_get_lun_from_tpg(struct sbp_tpg 
*tpg, int lun)
        spin_lock(&se_tpg->tpg_lun_lock);
        se_lun = se_tpg->tpg_lun_list[lun];
 
-       if (se_lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE)
+       if (!se_lun)
                se_lun = ERR_PTR(-ENODEV);
 
        spin_unlock(&se_tpg->tpg_lun_lock);
@@ -1942,7 +1942,7 @@ static int sbp_count_se_tpg_luns(struct se_portal_group 
*tpg)
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                struct se_lun *se_lun = tpg->tpg_lun_list[i];
 
-               if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE)
+               if (!se_lun)
                        continue;
 
                count++;
@@ -2022,7 +2022,7 @@ static int sbp_update_unit_directory(struct sbp_tport 
*tport)
                struct se_device *dev;
                int type;
 
-               if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE)
+               if (!se_lun)
                        continue;
 
                spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock);
diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index cb69413..afa7f6b 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1214,22 +1214,17 @@ int se_dev_set_block_size(struct se_device *dev, u32 
block_size)
        return 0;
 }
 
-struct se_lun *core_dev_add_lun(
+int core_dev_add_lun(
        struct se_portal_group *tpg,
        struct se_device *dev,
-       u32 unpacked_lun)
+       struct se_lun *lun)
 {
-       struct se_lun *lun;
        int rc;
 
-       lun = core_tpg_alloc_lun(tpg, unpacked_lun);
-       if (IS_ERR(lun))
-               return lun;
-
        rc = core_tpg_add_lun(tpg, lun,
                                TRANSPORT_LUNFLAGS_READ_WRITE, dev);
        if (rc < 0)
-               return ERR_PTR(rc);
+               return rc;
 
        pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from"
                " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(),
@@ -1254,7 +1249,7 @@ struct se_lun *core_dev_add_lun(
                spin_unlock_irq(&tpg->acl_node_lock);
        }
 
-       return lun;
+       return rc;
 }
 
 /*      core_dev_del_lun():
@@ -1271,68 +1266,7 @@ void core_dev_del_lun(
                tpg->se_tpg_tfo->get_fabric_name());
 
        core_tpg_remove_lun(tpg, lun);
-}
-
-struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32 
unpacked_lun)
-{
-       struct se_lun *lun;
-
-       spin_lock(&tpg->tpg_lun_lock);
-       if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
-               pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS"
-                       "_PER_TPG-1: %u for Target Portal Group: %hu\n",
-                       tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun,
-                       TRANSPORT_MAX_LUNS_PER_TPG-1,
-                       tpg->se_tpg_tfo->tpg_get_tag(tpg));
-               spin_unlock(&tpg->tpg_lun_lock);
-               return NULL;
-       }
-       lun = tpg->tpg_lun_list[unpacked_lun];
-
-       if (lun->lun_status != TRANSPORT_LUN_STATUS_FREE) {
-               pr_err("%s Logical Unit Number: %u is not free on"
-                       " Target Portal Group: %hu, ignoring request.\n",
-                       tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun,
-                       tpg->se_tpg_tfo->tpg_get_tag(tpg));
-               spin_unlock(&tpg->tpg_lun_lock);
-               return NULL;
-       }
-       spin_unlock(&tpg->tpg_lun_lock);
-
-       return lun;
-}
-
-/*      core_dev_get_lun():
- *
- *
- */
-static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 
unpacked_lun)
-{
-       struct se_lun *lun;
-
-       spin_lock(&tpg->tpg_lun_lock);
-       if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
-               pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER"
-                       "_TPG-1: %u for Target Portal Group: %hu\n",
-                       tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun,
-                       TRANSPORT_MAX_LUNS_PER_TPG-1,
-                       tpg->se_tpg_tfo->tpg_get_tag(tpg));
-               spin_unlock(&tpg->tpg_lun_lock);
-               return NULL;
-       }
-       lun = tpg->tpg_lun_list[unpacked_lun];
-
-       if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) {
-               pr_err("%s Logical Unit Number: %u is not active on"
-                       " Target Portal Group: %hu, ignoring request.\n",
-                       tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun,
-                       tpg->se_tpg_tfo->tpg_get_tag(tpg));
-               spin_unlock(&tpg->tpg_lun_lock);
-               return NULL;
-       }
-       spin_unlock(&tpg->tpg_lun_lock);
-
-       return lun;
+       core_tpg_free_lun(tpg, lun);
 }
 
 struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
@@ -1374,7 +1308,9 @@ int core_dev_add_initiator_node_lun_acl(
        struct se_lun *lun;
        struct se_node_acl *nacl;
 
-       lun = core_dev_get_lun(tpg, unpacked_lun);
+       spin_lock(&tpg->tpg_lun_lock);
+       lun = tpg->tpg_lun_list[unpacked_lun];
+       spin_unlock(&tpg->tpg_lun_lock);
        if (!lun) {
                pr_err("%s Logical Unit Number: %u is not active on"
                        " Target Portal Group: %hu, ignoring request.\n",
diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index 35da34d..50a71bb 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -754,7 +754,6 @@ static int target_fabric_port_link(
        struct config_item *tpg_ci;
        struct se_lun *lun = container_of(to_config_group(lun_ci),
                                struct se_lun, lun_group);
-       struct se_lun *lun_p;
        struct se_portal_group *se_tpg;
        struct se_device *dev =
                container_of(to_config_group(se_dev_ci), struct se_device, 
dev_group);
@@ -782,11 +781,10 @@ static int target_fabric_port_link(
                return -EEXIST;
        }
 
-       lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun);
-       if (IS_ERR(lun_p)) {
+       ret = core_dev_add_lun(se_tpg, dev, lun);
+       if (ret < 0) {
                pr_err("core_dev_add_lun() failed\n");
-               ret = PTR_ERR(lun_p);
-               goto out;
+               return ret;
        }
 
        if (tf->tf_ops.fabric_post_link) {
@@ -799,8 +797,6 @@ static int target_fabric_port_link(
        }
 
        return 0;
-out:
-       return ret;
 }
 
 static int target_fabric_port_unlink(
@@ -886,16 +882,17 @@ static struct config_group *target_fabric_make_lun(
        if (unpacked_lun > UINT_MAX)
                return ERR_PTR(-EINVAL);
 
-       lun = core_get_lun_from_tpg(se_tpg, unpacked_lun);
-       if (!lun)
-               return ERR_PTR(-EINVAL);
+       lun = core_tpg_alloc_lun(se_tpg, unpacked_lun);
+       if (IS_ERR(lun))
+               return ERR_CAST(lun);
 
        lun_cg = &lun->lun_group;
        lun_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2,
                                GFP_KERNEL);
        if (!lun_cg->default_groups) {
                pr_err("Unable to allocate lun_cg->default_groups\n");
-               return ERR_PTR(-ENOMEM);
+               errno = -ENOMEM;
+               goto out;
        }
 
        config_group_init_type_name(&lun->lun_group, name,
@@ -917,6 +914,8 @@ static struct config_group *target_fabric_make_lun(
 
        return &lun->lun_group;
 out:
+       if (lun)
+               core_tpg_free_lun(se_tpg, lun);
        if (lun_cg)
                kfree(lun_cg->default_groups);
        return ERR_PTR(errno);
diff --git a/drivers/target/target_core_internal.h 
b/drivers/target/target_core_internal.h
index 42ef4ab..4f3e6d5 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -45,9 +45,8 @@ int   se_dev_set_max_sectors(struct se_device *, u32);
 int    se_dev_set_fabric_max_sectors(struct se_device *, u32);
 int    se_dev_set_optimal_sectors(struct se_device *, u32);
 int    se_dev_set_block_size(struct se_device *, u32);
-struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, 
u32);
+int    core_dev_add_lun(struct se_portal_group *, struct se_device *, struct 
se_lun *);
 void   core_dev_del_lun(struct se_portal_group *, struct se_lun *);
-struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32);
 struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group 
*,
                struct se_node_acl *, u32, int *);
 int    core_dev_add_initiator_node_lun_acl(struct se_portal_group *,
@@ -83,6 +82,7 @@ struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, 
u32);
 int    core_tpg_add_lun(struct se_portal_group *, struct se_lun *,
                u32, struct se_device *);
 void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *);
+void core_tpg_free_lun(struct se_portal_group *, struct se_lun *);
 
 /* target_core_transport.c */
 extern struct kmem_cache *se_tmr_req_cache;
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 914a0a6..25e3a8e 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -134,7 +134,7 @@ void core_tpg_add_node_to_devs(
        spin_lock(&tpg->tpg_lun_lock);
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                lun = tpg->tpg_lun_list[i];
-               if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE)
+               if (!lun)
                        continue;
 
                spin_unlock(&tpg->tpg_lun_lock);
@@ -189,34 +189,6 @@ static int core_set_queue_depth_for_node(
        return 0;
 }
 
-void array_free(void *array, int n)
-{
-       void **a = array;
-       int i;
-
-       for (i = 0; i < n; i++)
-               kfree(a[i]);
-       kfree(a);
-}
-
-static void *array_zalloc(int n, size_t size, gfp_t flags)
-{
-       void **a;
-       int i;
-
-       a = kzalloc(n * sizeof(void*), flags);
-       if (!a)
-               return NULL;
-       for (i = 0; i < n; i++) {
-               a[i] = kzalloc(size, flags);
-               if (!a[i]) {
-                       array_free(a, n);
-                       return NULL;
-               }
-       }
-       return a;
-}
-
 /*      core_create_device_list_for_node():
  *
  *
@@ -318,8 +290,7 @@ void core_tpg_clear_object_luns(struct se_portal_group *tpg)
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                lun = tpg->tpg_lun_list[i];
 
-               if ((lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) ||
-                   (lun->lun_se_dev == NULL))
+               if ((!lun) || (lun->lun_se_dev == NULL))
                        continue;
 
                spin_unlock(&tpg->tpg_lun_lock);
@@ -636,7 +607,6 @@ static int core_tpg_setup_virtual_lun0(struct 
se_portal_group *se_tpg)
        int ret;
 
        lun->unpacked_lun = 0;
-       lun->lun_status = TRANSPORT_LUN_STATUS_FREE;
        atomic_set(&lun->lun_acl_count, 0);
        init_completion(&lun->lun_shutdown_comp);
        INIT_LIST_HEAD(&lun->lun_acl_list);
@@ -665,30 +635,14 @@ int core_tpg_register(
        void *tpg_fabric_ptr,
        int se_tpg_type)
 {
-       struct se_lun *lun;
-       u32 i;
-
-       se_tpg->tpg_lun_list = array_zalloc(TRANSPORT_MAX_LUNS_PER_TPG,
-                       sizeof(struct se_lun), GFP_KERNEL);
+       se_tpg->tpg_lun_list = kzalloc(TRANSPORT_MAX_LUNS_PER_TPG * 
sizeof(void*),
+                                      GFP_KERNEL);
        if (!se_tpg->tpg_lun_list) {
                pr_err("Unable to allocate struct se_portal_group->"
                                "tpg_lun_list\n");
                return -ENOMEM;
        }
 
-       for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
-               lun = se_tpg->tpg_lun_list[i];
-               lun->unpacked_lun = i;
-               lun->lun_link_magic = SE_LUN_LINK_MAGIC;
-               lun->lun_status = TRANSPORT_LUN_STATUS_FREE;
-               atomic_set(&lun->lun_acl_count, 0);
-               init_completion(&lun->lun_shutdown_comp);
-               INIT_LIST_HEAD(&lun->lun_acl_list);
-               spin_lock_init(&lun->lun_acl_lock);
-               spin_lock_init(&lun->lun_sep_lock);
-               init_completion(&lun->lun_ref_comp);
-       }
-
        se_tpg->se_tpg_type = se_tpg_type;
        se_tpg->se_tpg_fabric_ptr = tpg_fabric_ptr;
        se_tpg->se_tpg_tfo = tfo;
@@ -703,8 +657,7 @@ int core_tpg_register(
 
        if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) {
                if (core_tpg_setup_virtual_lun0(se_tpg) < 0) {
-                       array_free(se_tpg->tpg_lun_list,
-                                  TRANSPORT_MAX_LUNS_PER_TPG);
+                       kfree(se_tpg->tpg_lun_list);
                        return -ENOMEM;
                }
        }
@@ -764,7 +717,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
                core_tpg_release_virtual_lun0(se_tpg);
 
        se_tpg->se_tpg_fabric_ptr = NULL;
-       array_free(se_tpg->tpg_lun_list, TRANSPORT_MAX_LUNS_PER_TPG);
+       kfree(se_tpg->tpg_lun_list);
        return 0;
 }
 EXPORT_SYMBOL(core_tpg_deregister);
@@ -773,7 +726,7 @@ struct se_lun *core_tpg_alloc_lun(
        struct se_portal_group *tpg,
        u32 unpacked_lun)
 {
-       struct se_lun *lun;
+       struct se_lun *lun, *new_lun;
 
        if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
                pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER_TPG"
@@ -784,9 +737,14 @@ struct se_lun *core_tpg_alloc_lun(
                return ERR_PTR(-EOVERFLOW);
        }
 
+       new_lun = kzalloc(sizeof(*lun), GFP_KERNEL);
+       if (!new_lun)
+               return ERR_PTR(-ENOMEM);
+
        spin_lock(&tpg->tpg_lun_lock);
        lun = tpg->tpg_lun_list[unpacked_lun];
-       if (lun->lun_status == TRANSPORT_LUN_STATUS_ACTIVE) {
+       if (lun) {
+               kfree(new_lun);
                pr_err("TPG Logical Unit Number: %u is already active"
                        " on %s Target Portal Group: %u, ignoring request.\n",
                        unpacked_lun, tpg->se_tpg_tfo->get_fabric_name(),
@@ -794,9 +752,21 @@ struct se_lun *core_tpg_alloc_lun(
                spin_unlock(&tpg->tpg_lun_lock);
                return ERR_PTR(-EINVAL);
        }
+
+       new_lun->unpacked_lun = unpacked_lun;
+       new_lun->lun_link_magic = SE_LUN_LINK_MAGIC;
+       atomic_set(&new_lun->lun_acl_count, 0);
+       init_completion(&new_lun->lun_shutdown_comp);
+       INIT_LIST_HEAD(&new_lun->lun_acl_list);
+       spin_lock_init(&new_lun->lun_acl_lock);
+       spin_lock_init(&new_lun->lun_sep_lock);
+       init_completion(&new_lun->lun_ref_comp);
+
+       tpg->tpg_lun_list[unpacked_lun] = new_lun;
+
        spin_unlock(&tpg->tpg_lun_lock);
 
-       return lun;
+       return new_lun;
 }
 
 int core_tpg_add_lun(
@@ -819,7 +789,6 @@ int core_tpg_add_lun(
 
        spin_lock(&tpg->tpg_lun_lock);
        lun->lun_access = lun_access;
-       lun->lun_status = TRANSPORT_LUN_STATUS_ACTIVE;
        spin_unlock(&tpg->tpg_lun_lock);
 
        return 0;
@@ -832,8 +801,15 @@ void core_tpg_remove_lun(
        core_clear_lun_from_tpg(lun, tpg);
        transport_clear_lun_ref(lun);
        core_dev_unexport(lun->lun_se_dev, tpg, lun);
+}
 
+void core_tpg_free_lun(
+       struct se_portal_group *tpg,
+       struct se_lun *lun)
+{
        spin_lock(&tpg->tpg_lun_lock);
-       lun->lun_status = TRANSPORT_LUN_STATUS_FREE;
+       tpg->tpg_lun_list[lun->unpacked_lun] = NULL;
        spin_unlock(&tpg->tpg_lun_lock);
+
+       kfree(lun);
 }
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 0c10d75..6981642 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -125,12 +125,6 @@ enum hba_flags_table {
        HBA_FLAGS_PSCSI_MODE    = 0x02,
 };
 
-/* struct se_lun->lun_status */
-enum transport_lun_status_table {
-       TRANSPORT_LUN_STATUS_FREE = 0,
-       TRANSPORT_LUN_STATUS_ACTIVE = 1,
-};
-
 /* struct se_portal_group->se_tpg_type */
 enum transport_tpg_type_table {
        TRANSPORT_TPG_TYPE_NORMAL = 0,
@@ -702,8 +696,6 @@ struct se_port_stat_grps {
 struct se_lun {
 #define SE_LUN_LINK_MAGIC                      0xffff7771
        u32                     lun_link_magic;
-       /* See transport_lun_status_table */
-       enum transport_lun_status_table lun_status;
        u32                     lun_access;
        u32                     lun_flags;
        u32                     unpacked_lun;
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to