scsi: target: core: Add RTPI field to target port
authorDmitry Bogdanov <d.bogdanov@yadro.com>
Wed, 1 Mar 2023 08:45:09 +0000 (11:45 +0300)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 10 Mar 2023 02:29:23 +0000 (21:29 -0500)
SAM-5 4.6.5.2 (Relative Port Identifier attribute) defines the attribute as
unique across SCSI target ports.

The change introduces RTPI attribute to se_portal group. The value is
unique across all enabled SCSI target ports. It also limits number of SCSI
target ports to 65535.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Link: https://lore.kernel.org/r/20230301084512.21956-2-d.bogdanov@yadro.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/target/target_core_fabric_configfs.c
drivers/target/target_core_internal.h
drivers/target/target_core_tpg.c
include/target/target_core_base.h

index 67b18a67317a053720efc28a325d036be1d54be5..873da49ab704dab0c61219a2e5f0326b288b836c 100644 (file)
@@ -836,13 +836,12 @@ static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item,
 
        if (se_tpg->enabled == op)
                return count;
-
-       ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op);
+       if (op)
+               ret = target_tpg_enable(se_tpg);
+       else
+               ret = target_tpg_disable(se_tpg);
        if (ret)
                return ret;
-
-       se_tpg->enabled = op;
-
        return count;
 }
 
index 38a6d08f75b3427e9a738020291ac8de10705655..82fd5768a662ed26a8d39d5cd41f3eed217ca35b 100644 (file)
@@ -132,6 +132,8 @@ void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *);
 struct se_node_acl *core_tpg_add_initiator_node_acl(struct se_portal_group *tpg,
                const char *initiatorname);
 void core_tpg_del_initiator_node_acl(struct se_node_acl *acl);
+int target_tpg_enable(struct se_portal_group *se_tpg);
+int target_tpg_disable(struct se_portal_group *se_tpg);
 
 /* target_core_transport.c */
 int    init_se_kmem_caches(void);
index 736847c933e5c1b4c3ede82866875e6c09419eec..0de3385b94c53f03ca5aa88951201b22e385af22 100644 (file)
@@ -31,6 +31,7 @@
 #include "target_core_ua.h"
 
 extern struct se_device *g_lun0_dev;
+static DEFINE_XARRAY_ALLOC(tpg_xa);
 
 /*     __core_tpg_get_initiator_node_acl():
  *
@@ -439,6 +440,57 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref)
        complete(&lun->lun_shutdown_comp);
 }
 
+static int target_tpg_register_rtpi(struct se_portal_group *se_tpg)
+{
+       u32 val;
+       int ret;
+
+       ret = xa_alloc(&tpg_xa, &val, se_tpg,
+                      XA_LIMIT(1, USHRT_MAX), GFP_KERNEL);
+       if (!ret)
+               se_tpg->tpg_rtpi = val;
+
+       return ret;
+}
+
+static void target_tpg_deregister_rtpi(struct se_portal_group *se_tpg)
+{
+       if (se_tpg->tpg_rtpi && se_tpg->enabled)
+               xa_erase(&tpg_xa, se_tpg->tpg_rtpi);
+}
+
+int target_tpg_enable(struct se_portal_group *se_tpg)
+{
+       int ret;
+
+       ret = target_tpg_register_rtpi(se_tpg);
+       if (ret)
+               return ret;
+
+       ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, true);
+       if (ret) {
+               target_tpg_deregister_rtpi(se_tpg);
+               return ret;
+       }
+
+       se_tpg->enabled = true;
+
+       return 0;
+}
+
+int target_tpg_disable(struct se_portal_group *se_tpg)
+{
+       int ret;
+
+       target_tpg_deregister_rtpi(se_tpg);
+
+       ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, false);
+       if (!ret)
+               se_tpg->enabled = false;
+
+       return ret;
+}
+
 /* Does not change se_wwn->priv. */
 int core_tpg_register(
        struct se_wwn *se_wwn,
@@ -535,6 +587,8 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
                kfree_rcu(se_tpg->tpg_virt_lun0, rcu_head);
        }
 
+       target_tpg_deregister_rtpi(se_tpg);
+
        return 0;
 }
 EXPORT_SYMBOL(core_tpg_deregister);
index 12c9ba16217ef84818d207fdb94bce89f22ceb9b..814edf746395c9ee9a6ed8ef8e66e13bc5801b24 100644 (file)
@@ -920,6 +920,8 @@ struct se_portal_group {
         */
        int                     proto_id;
        bool                    enabled;
+       /* RELATIVE TARGET PORT IDENTIFIER */
+       u16                     tpg_rtpi;
        /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
        atomic_t                tpg_pr_ref_count;
        /* Spinlock for adding/removing ACLed Nodes */