scsi: target: core: Add RTPI attribute for target port
authorDmitry Bogdanov <d.bogdanov@yadro.com>
Wed, 1 Mar 2023 08:45:12 +0000 (11:45 +0300)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 10 Mar 2023 02:29:23 +0000 (21:29 -0500)
RELATIVE TARGET PORT IDENTIFIER can be read and configured via configfs:

$ echo 0x10 > $TARGET/tpgt_N/rtpi

RTPI can be changed only on disabled target ports.

Co-developed-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Link: https://lore.kernel.org/r/20230301084512.21956-5-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_tpg.c
include/target/target_core_base.h

index 873da49ab704dab0c61219a2e5f0326b288b836c..0ce47e21e0c8d94e61c4792f32ddbbf537e81738 100644 (file)
@@ -844,15 +844,48 @@ static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item,
                return ret;
        return count;
 }
+static ssize_t target_fabric_tpg_base_rtpi_show(struct config_item *item, char *page)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+
+       return sysfs_emit(page, "%#x\n", se_tpg->tpg_rtpi);
+}
+
+static ssize_t target_fabric_tpg_base_rtpi_store(struct config_item *item,
+                                  const char *page, size_t count)
+{
+       struct se_portal_group *se_tpg = to_tpg(item);
+       u16 val;
+       int ret;
+
+       ret = kstrtou16(page, 0, &val);
+       if (ret < 0)
+               return ret;
+       if (val == 0)
+               return -EINVAL;
+
+       if (se_tpg->enabled) {
+               pr_info("%s_TPG[%hu] - Can not change RTPI on enabled TPG",
+                       se_tpg->se_tpg_tfo->fabric_name,
+                       se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg));
+               return -EINVAL;
+       }
+
+       se_tpg->tpg_rtpi = val;
+       se_tpg->rtpi_manual = true;
+
+       return count;
+}
 
 CONFIGFS_ATTR(target_fabric_tpg_base_, enable);
+CONFIGFS_ATTR(target_fabric_tpg_base_, rtpi);
 
 static int
 target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf)
 {
        struct config_item_type *cit = &tf->tf_tpg_base_cit;
        struct configfs_attribute **attrs = NULL;
-       size_t nr_attrs = 0;
+       size_t nr_attrs = 1;
        int i = 0;
 
        if (tf->tf_ops->tfc_tpg_base_attrs)
@@ -875,7 +908,9 @@ target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf)
                        attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i];
 
        if (tf->tf_ops->fabric_enable_tpg)
-               attrs[i] = &target_fabric_tpg_base_attr_enable;
+               attrs[i++] = &target_fabric_tpg_base_attr_enable;
+
+       attrs[i++] = &target_fabric_tpg_base_attr_rtpi;
 
 done:
        cit->ct_item_ops = &target_fabric_tpg_base_item_ops;
index b1d9383386ec31552669f236df80385a78bdfabc..2e079c6a8e8c444a6aec3223dd30a7b73e0dbaec 100644 (file)
@@ -445,10 +445,21 @@ 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;
+       if (se_tpg->rtpi_manual) {
+               ret = xa_insert(&tpg_xa, se_tpg->tpg_rtpi, se_tpg, GFP_KERNEL);
+               if (ret) {
+                       pr_info("%s_TPG[%hu] - Can not set RTPI %#x, it is already busy",
+                               se_tpg->se_tpg_tfo->fabric_name,
+                               se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg),
+                               se_tpg->tpg_rtpi);
+                       return -EINVAL;
+               }
+       } else {
+               ret = xa_alloc(&tpg_xa, &val, se_tpg,
+                              XA_LIMIT(1, USHRT_MAX), GFP_KERNEL);
+               if (!ret)
+                       se_tpg->tpg_rtpi = val;
+       }
 
        return ret;
 }
index 008e0e4500d19a975d277904c8aba4f7728100aa..e52d0915b3d88038c85a72afb600b4756f74f480 100644 (file)
@@ -918,6 +918,7 @@ struct se_portal_group {
        bool                    enabled;
        /* RELATIVE TARGET PORT IDENTIFIER */
        u16                     tpg_rtpi;
+       bool                    rtpi_manual;
        /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
        atomic_t                tpg_pr_ref_count;
        /* Spinlock for adding/removing ACLed Nodes */