Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: target: core: Add common tpg/enable attribute

Many fabric modules provide their own implementation of enable attribute in
tpg.

Provide a way to remove code duplication in the fabric modules and
automatically add "enable" attribute if a fabric module has an
implementation of fabric_enable_tpg().

Link: https://lore.kernel.org/r/20210910084133.17956-2-d.bogdanov@yadro.com
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Dmitry Bogdanov and committed by
Martin K. Petersen
80ed33c8 cdf7f6a1

+79 -2
+1
drivers/target/target_core_configfs.c
··· 490 490 * fabric driver unload of TFO->module to proceed. 491 491 */ 492 492 rcu_barrier(); 493 + kfree(t->tf_tpg_base_cit.ct_attrs); 493 494 kfree(t); 494 495 return; 495 496 }
+76 -2
drivers/target/target_core_fabric_configfs.c
··· 815 815 .release = target_fabric_tpg_release, 816 816 }; 817 817 818 - TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL); 818 + static ssize_t target_fabric_tpg_base_enable_show(struct config_item *item, 819 + char *page) 820 + { 821 + return sysfs_emit(page, "%d\n", to_tpg(item)->enabled); 822 + } 819 823 824 + static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item, 825 + const char *page, 826 + size_t count) 827 + { 828 + struct se_portal_group *se_tpg = to_tpg(item); 829 + int ret; 830 + bool op; 831 + 832 + ret = strtobool(page, &op); 833 + if (ret) 834 + return ret; 835 + 836 + if (se_tpg->enabled == op) 837 + return count; 838 + 839 + ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op); 840 + if (ret) 841 + return ret; 842 + 843 + se_tpg->enabled = op; 844 + 845 + return count; 846 + } 847 + 848 + CONFIGFS_ATTR(target_fabric_tpg_base_, enable); 849 + 850 + static int 851 + target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) 852 + { 853 + struct config_item_type *cit = &tf->tf_tpg_base_cit; 854 + struct configfs_attribute **attrs = NULL; 855 + size_t nr_attrs = 0; 856 + int i = 0; 857 + 858 + if (tf->tf_ops->tfc_tpg_base_attrs) 859 + while (tf->tf_ops->tfc_tpg_base_attrs[nr_attrs] != NULL) 860 + nr_attrs++; 861 + 862 + if (tf->tf_ops->fabric_enable_tpg) 863 + nr_attrs++; 864 + 865 + if (nr_attrs == 0) 866 + goto done; 867 + 868 + /* + 1 for final NULL in the array */ 869 + attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL); 870 + if (!attrs) 871 + return -ENOMEM; 872 + 873 + if (tf->tf_ops->tfc_tpg_base_attrs) 874 + for (; tf->tf_ops->tfc_tpg_base_attrs[i] != NULL; i++) 875 + attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i]; 876 + 877 + if (tf->tf_ops->fabric_enable_tpg) 878 + attrs[i] = &target_fabric_tpg_base_attr_enable; 879 + 880 + done: 881 + cit->ct_item_ops = &target_fabric_tpg_base_item_ops; 882 + cit->ct_attrs = attrs; 883 + cit->ct_owner = tf->tf_ops->module; 884 + pr_debug("Setup generic tpg_base\n"); 885 + 886 + return 0; 887 + } 820 888 /* End of tfc_tpg_base_cit */ 821 889 822 890 /* Start of tfc_tpg_cit */ ··· 1096 1028 1097 1029 int target_fabric_setup_cits(struct target_fabric_configfs *tf) 1098 1030 { 1031 + int ret; 1032 + 1099 1033 target_fabric_setup_discovery_cit(tf); 1100 1034 target_fabric_setup_wwn_cit(tf); 1101 1035 target_fabric_setup_wwn_fabric_stats_cit(tf); 1102 1036 target_fabric_setup_wwn_param_cit(tf); 1103 1037 target_fabric_setup_tpg_cit(tf); 1104 - target_fabric_setup_tpg_base_cit(tf); 1038 + 1039 + ret = target_fabric_setup_tpg_base_cit(tf); 1040 + if (ret) 1041 + return ret; 1042 + 1105 1043 target_fabric_setup_tpg_port_cit(tf); 1106 1044 target_fabric_setup_tpg_port_stat_cit(tf); 1107 1045 target_fabric_setup_tpg_lun_cit(tf);
+1
include/target/target_core_base.h
··· 900 900 * Negative values can be used by fabric drivers for internal use TPGs. 901 901 */ 902 902 int proto_id; 903 + bool enabled; 903 904 /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ 904 905 atomic_t tpg_pr_ref_count; 905 906 /* Spinlock for adding/removing ACLed Nodes */
+1
include/target/target_core_fabric.h
··· 89 89 void (*add_wwn_groups)(struct se_wwn *); 90 90 struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *, 91 91 const char *); 92 + int (*fabric_enable_tpg)(struct se_portal_group *se_tpg, bool enable); 92 93 void (*fabric_drop_tpg)(struct se_portal_group *); 93 94 int (*fabric_post_link)(struct se_portal_group *, 94 95 struct se_lun *);