Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "This series contains HCH's changes to absorb configfs attribute ->show() + ->store() function pointer usage from it's original tree-wide consumers, into common configfs code. It includes usb-gadget, target w/ drivers, netconsole and ocfs2 changes to realize the improved simplicity, that now renders the original include/target/configfs_macros.h CPP magic for fabric drivers and others, unnecessary and obsolete. And with common code in place, new configfs attributes can be added easier than ever before. Note, there are further improvements in-flight from other folks for v4.5 code in configfs land, plus number of target fixes for post -rc1 code" In the meantime, a new user of the now-removed old configfs API came in through the char/misc tree in commit7bd1d4093c
("stm class: Introduce an abstraction for System Trace Module devices"). This merge resolution comes from Alexander Shishkin, who updated his stm class tracing abstraction to account for the removal of the old show_attribute and store_attribute methods in commit517982229f
("configfs: remove old API") from this pull. As Alexander says about that patch: "There's no need to keep an extra wrapper structure per item and the awkward show_attribute/store_attribute item ops are no longer needed. This patch converts policy code to the new api, all the while making the code quite a bit smaller and easier on the eyes. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>" That patch was folded into the merge so that the tree should be fully bisectable. * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (23 commits) configfs: remove old API ocfs2/cluster: use per-attribute show and store methods ocfs2/cluster: move locking into attribute store methods netconsole: use per-attribute show and store methods target: use per-attribute show and store methods spear13xx_pcie_gadget: use per-attribute show and store methods dlm: use per-attribute show and store methods usb-gadget/f_serial: use per-attribute show and store methods usb-gadget/f_phonet: use per-attribute show and store methods usb-gadget/f_obex: use per-attribute show and store methods usb-gadget/f_uac2: use per-attribute show and store methods usb-gadget/f_uac1: use per-attribute show and store methods usb-gadget/f_mass_storage: use per-attribute show and store methods usb-gadget/f_sourcesink: use per-attribute show and store methods usb-gadget/f_printer: use per-attribute show and store methods usb-gadget/f_midi: use per-attribute show and store methods usb-gadget/f_loopback: use per-attribute show and store methods usb-gadget/ether: use per-attribute show and store methods usb-gadget/f_acm: use per-attribute show and store methods usb-gadget/f_hid: use per-attribute show and store methods ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
|
||||
#include "tcm_loop.h"
|
||||
|
||||
@@ -763,21 +762,20 @@ static void tcm_loop_port_unlink(
|
||||
|
||||
/* End items for tcm_loop_port_cit */
|
||||
|
||||
static ssize_t tcm_loop_tpg_attrib_show_fabric_prot_type(
|
||||
struct se_portal_group *se_tpg,
|
||||
char *page)
|
||||
static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_show(
|
||||
struct config_item *item, char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
|
||||
tl_se_tpg);
|
||||
|
||||
return sprintf(page, "%d\n", tl_tpg->tl_fabric_prot_type);
|
||||
}
|
||||
|
||||
static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
|
||||
struct config_item *item, const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
|
||||
tl_se_tpg);
|
||||
unsigned long val;
|
||||
@@ -796,10 +794,10 @@ static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type(
|
||||
return count;
|
||||
}
|
||||
|
||||
TF_TPG_ATTRIB_ATTR(tcm_loop, fabric_prot_type, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(tcm_loop_tpg_attrib_, fabric_prot_type);
|
||||
|
||||
static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = {
|
||||
&tcm_loop_tpg_attrib_fabric_prot_type.attr,
|
||||
&tcm_loop_tpg_attrib_attr_fabric_prot_type,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -894,10 +892,9 @@ static int tcm_loop_drop_nexus(
|
||||
|
||||
/* End items for tcm_loop_nexus_cit */
|
||||
|
||||
static ssize_t tcm_loop_tpg_show_nexus(
|
||||
struct se_portal_group *se_tpg,
|
||||
char *page)
|
||||
static ssize_t tcm_loop_tpg_nexus_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
|
||||
struct tcm_loop_tpg, tl_se_tpg);
|
||||
struct tcm_loop_nexus *tl_nexus;
|
||||
@@ -913,11 +910,10 @@ static ssize_t tcm_loop_tpg_show_nexus(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t tcm_loop_tpg_store_nexus(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t tcm_loop_tpg_nexus_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
|
||||
struct tcm_loop_tpg, tl_se_tpg);
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
@@ -992,12 +988,10 @@ check_newline:
|
||||
return count;
|
||||
}
|
||||
|
||||
TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
|
||||
|
||||
static ssize_t tcm_loop_tpg_show_transport_status(
|
||||
struct se_portal_group *se_tpg,
|
||||
char *page)
|
||||
static ssize_t tcm_loop_tpg_transport_status_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
|
||||
struct tcm_loop_tpg, tl_se_tpg);
|
||||
const char *status = NULL;
|
||||
@@ -1020,11 +1014,10 @@ static ssize_t tcm_loop_tpg_show_transport_status(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t tcm_loop_tpg_store_transport_status(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t tcm_loop_tpg_transport_status_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
|
||||
struct tcm_loop_tpg, tl_se_tpg);
|
||||
|
||||
@@ -1044,11 +1037,12 @@ static ssize_t tcm_loop_tpg_store_transport_status(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(tcm_loop_tpg_, nexus);
|
||||
CONFIGFS_ATTR(tcm_loop_tpg_, transport_status);
|
||||
|
||||
static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
|
||||
&tcm_loop_tpg_nexus.attr,
|
||||
&tcm_loop_tpg_transport_status.attr,
|
||||
&tcm_loop_tpg_attr_nexus,
|
||||
&tcm_loop_tpg_attr_transport_status,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -1216,17 +1210,15 @@ static void tcm_loop_drop_scsi_hba(
|
||||
}
|
||||
|
||||
/* Start items for tcm_loop_cit */
|
||||
static ssize_t tcm_loop_wwn_show_attr_version(
|
||||
struct target_fabric_configfs *tf,
|
||||
char *page)
|
||||
static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
|
||||
{
|
||||
return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
|
||||
}
|
||||
|
||||
TF_WWN_ATTR_RO(tcm_loop, version);
|
||||
CONFIGFS_ATTR_RO(tcm_loop_wwn_, version);
|
||||
|
||||
static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
|
||||
&tcm_loop_wwn_version.attr,
|
||||
&tcm_loop_wwn_attr_version,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@@ -35,8 +35,6 @@
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_backend.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/configfs_macros.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "sbp_target.h"
|
||||
@@ -2111,24 +2109,21 @@ static void sbp_drop_tport(struct se_wwn *wwn)
|
||||
kfree(tport);
|
||||
}
|
||||
|
||||
static ssize_t sbp_wwn_show_attr_version(
|
||||
struct target_fabric_configfs *tf,
|
||||
char *page)
|
||||
static ssize_t sbp_wwn_version_show(struct config_item *item, char *page)
|
||||
{
|
||||
return sprintf(page, "FireWire SBP fabric module %s\n", SBP_VERSION);
|
||||
}
|
||||
|
||||
TF_WWN_ATTR_RO(sbp, version);
|
||||
CONFIGFS_ATTR_RO(sbp_wwn_, version);
|
||||
|
||||
static struct configfs_attribute *sbp_wwn_attrs[] = {
|
||||
&sbp_wwn_version.attr,
|
||||
&sbp_wwn_attr_version,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static ssize_t sbp_tpg_show_directory_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
char *page)
|
||||
static ssize_t sbp_tpg_directory_id_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
|
||||
@@ -2138,11 +2133,10 @@ static ssize_t sbp_tpg_show_directory_id(
|
||||
return sprintf(page, "%06x\n", tport->directory_id);
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_store_directory_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t sbp_tpg_directory_id_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
unsigned long val;
|
||||
@@ -2166,20 +2160,18 @@ static ssize_t sbp_tpg_store_directory_id(
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_show_enable(
|
||||
struct se_portal_group *se_tpg,
|
||||
char *page)
|
||||
static ssize_t sbp_tpg_enable_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
return sprintf(page, "%d\n", tport->enable);
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_store_enable(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t sbp_tpg_enable_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
unsigned long val;
|
||||
@@ -2219,29 +2211,28 @@ static ssize_t sbp_tpg_store_enable(
|
||||
return count;
|
||||
}
|
||||
|
||||
TF_TPG_BASE_ATTR(sbp, directory_id, S_IRUGO | S_IWUSR);
|
||||
TF_TPG_BASE_ATTR(sbp, enable, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(sbp_tpg_, directory_id);
|
||||
CONFIGFS_ATTR(sbp_tpg_, enable);
|
||||
|
||||
static struct configfs_attribute *sbp_tpg_base_attrs[] = {
|
||||
&sbp_tpg_directory_id.attr,
|
||||
&sbp_tpg_enable.attr,
|
||||
&sbp_tpg_attr_directory_id,
|
||||
&sbp_tpg_attr_enable,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static ssize_t sbp_tpg_attrib_show_mgt_orb_timeout(
|
||||
struct se_portal_group *se_tpg,
|
||||
static ssize_t sbp_tpg_attrib_mgt_orb_timeout_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
return sprintf(page, "%d\n", tport->mgt_orb_timeout);
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_attrib_store_mgt_orb_timeout(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t sbp_tpg_attrib_mgt_orb_timeout_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
unsigned long val;
|
||||
@@ -2264,20 +2255,19 @@ static ssize_t sbp_tpg_attrib_store_mgt_orb_timeout(
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_attrib_show_max_reconnect_timeout(
|
||||
struct se_portal_group *se_tpg,
|
||||
static ssize_t sbp_tpg_attrib_max_reconnect_timeout_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
return sprintf(page, "%d\n", tport->max_reconnect_timeout);
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_attrib_store_max_reconnect_timeout(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t sbp_tpg_attrib_max_reconnect_timeout_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
unsigned long val;
|
||||
@@ -2300,20 +2290,19 @@ static ssize_t sbp_tpg_attrib_store_max_reconnect_timeout(
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_attrib_show_max_logins_per_lun(
|
||||
struct se_portal_group *se_tpg,
|
||||
static ssize_t sbp_tpg_attrib_max_logins_per_lun_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
return sprintf(page, "%d\n", tport->max_logins_per_lun);
|
||||
}
|
||||
|
||||
static ssize_t sbp_tpg_attrib_store_max_logins_per_lun(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t sbp_tpg_attrib_max_logins_per_lun_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_portal_group *se_tpg = attrib_to_tpg(item);
|
||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||
struct sbp_tport *tport = tpg->tport;
|
||||
unsigned long val;
|
||||
@@ -2330,14 +2319,14 @@ static ssize_t sbp_tpg_attrib_store_max_logins_per_lun(
|
||||
return count;
|
||||
}
|
||||
|
||||
TF_TPG_ATTRIB_ATTR(sbp, mgt_orb_timeout, S_IRUGO | S_IWUSR);
|
||||
TF_TPG_ATTRIB_ATTR(sbp, max_reconnect_timeout, S_IRUGO | S_IWUSR);
|
||||
TF_TPG_ATTRIB_ATTR(sbp, max_logins_per_lun, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(sbp_tpg_attrib_, mgt_orb_timeout);
|
||||
CONFIGFS_ATTR(sbp_tpg_attrib_, max_reconnect_timeout);
|
||||
CONFIGFS_ATTR(sbp_tpg_attrib_, max_logins_per_lun);
|
||||
|
||||
static struct configfs_attribute *sbp_tpg_attrib_attrs[] = {
|
||||
&sbp_tpg_attrib_mgt_orb_timeout.attr,
|
||||
&sbp_tpg_attrib_max_reconnect_timeout.attr,
|
||||
&sbp_tpg_attrib_max_logins_per_lun.attr,
|
||||
&sbp_tpg_attrib_attr_mgt_orb_timeout,
|
||||
&sbp_tpg_attrib_attr_max_reconnect_timeout,
|
||||
&sbp_tpg_attrib_attr_max_logins_per_lun,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -35,8 +35,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/configfs_macros.h>
|
||||
|
||||
#include "target_core_internal.h"
|
||||
#include "target_core_alua.h"
|
||||
@@ -152,17 +150,16 @@ static int target_fabric_mappedlun_unlink(
|
||||
return core_dev_del_initiator_node_lun_acl(lun, lacl);
|
||||
}
|
||||
|
||||
CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl);
|
||||
#define TCM_MAPPEDLUN_ATTR(_name, _mode) \
|
||||
static struct target_fabric_mappedlun_attribute target_fabric_mappedlun_##_name = \
|
||||
__CONFIGFS_EATTR(_name, _mode, \
|
||||
target_fabric_mappedlun_show_##_name, \
|
||||
target_fabric_mappedlun_store_##_name);
|
||||
|
||||
static ssize_t target_fabric_mappedlun_show_write_protect(
|
||||
struct se_lun_acl *lacl,
|
||||
char *page)
|
||||
static struct se_lun_acl *item_to_lun_acl(struct config_item *item)
|
||||
{
|
||||
return container_of(to_config_group(item), struct se_lun_acl,
|
||||
se_lun_group);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_mappedlun_write_protect_show(
|
||||
struct config_item *item, char *page)
|
||||
{
|
||||
struct se_lun_acl *lacl = item_to_lun_acl(item);
|
||||
struct se_node_acl *se_nacl = lacl->se_lun_nacl;
|
||||
struct se_dev_entry *deve;
|
||||
ssize_t len = 0;
|
||||
@@ -178,11 +175,10 @@ static ssize_t target_fabric_mappedlun_show_write_protect(
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_mappedlun_store_write_protect(
|
||||
struct se_lun_acl *lacl,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t target_fabric_mappedlun_write_protect_store(
|
||||
struct config_item *item, const char *page, size_t count)
|
||||
{
|
||||
struct se_lun_acl *lacl = item_to_lun_acl(item);
|
||||
struct se_node_acl *se_nacl = lacl->se_lun_nacl;
|
||||
struct se_portal_group *se_tpg = se_nacl->se_tpg;
|
||||
unsigned long op;
|
||||
@@ -209,9 +205,12 @@ static ssize_t target_fabric_mappedlun_store_write_protect(
|
||||
|
||||
}
|
||||
|
||||
TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect);
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group);
|
||||
static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
|
||||
&target_fabric_mappedlun_attr_write_protect,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void target_fabric_mappedlun_release(struct config_item *item)
|
||||
{
|
||||
@@ -222,15 +221,8 @@ static void target_fabric_mappedlun_release(struct config_item *item)
|
||||
core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
|
||||
}
|
||||
|
||||
static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
|
||||
&target_fabric_mappedlun_write_protect.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
|
||||
.release = target_fabric_mappedlun_release,
|
||||
.show_attribute = target_fabric_mappedlun_attr_show,
|
||||
.store_attribute = target_fabric_mappedlun_attr_store,
|
||||
.allow_link = target_fabric_mappedlun_link,
|
||||
.drop_link = target_fabric_mappedlun_unlink,
|
||||
};
|
||||
@@ -266,49 +258,12 @@ TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
|
||||
|
||||
/* End of tfc_tpg_mappedlun_port_cit */
|
||||
|
||||
/* Start of tfc_tpg_nacl_attrib_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_nacl_attrib_item_ops = {
|
||||
.show_attribute = target_fabric_nacl_attrib_attr_show,
|
||||
.store_attribute = target_fabric_nacl_attrib_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_nacl_attrib_cit */
|
||||
|
||||
/* Start of tfc_tpg_nacl_auth_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_nacl_auth, se_node_acl, acl_auth_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_nacl_auth_item_ops = {
|
||||
.show_attribute = target_fabric_nacl_auth_attr_show,
|
||||
.store_attribute = target_fabric_nacl_auth_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_nacl_auth_cit */
|
||||
|
||||
/* Start of tfc_tpg_nacl_param_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_nacl_param, se_node_acl, acl_param_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_nacl_param_item_ops = {
|
||||
.show_attribute = target_fabric_nacl_param_attr_show,
|
||||
.store_attribute = target_fabric_nacl_param_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_nacl_param_cit */
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL);
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL);
|
||||
TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL);
|
||||
|
||||
/* Start of tfc_tpg_nacl_base_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_nacl_base, se_node_acl, acl_group);
|
||||
|
||||
static struct config_group *target_fabric_make_mappedlun(
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
@@ -438,8 +393,6 @@ static void target_fabric_nacl_base_release(struct config_item *item)
|
||||
|
||||
static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
|
||||
.release = target_fabric_nacl_base_release,
|
||||
.show_attribute = target_fabric_nacl_base_attr_show,
|
||||
.store_attribute = target_fabric_nacl_base_attr_store,
|
||||
};
|
||||
|
||||
static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
|
||||
@@ -540,8 +493,6 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
|
||||
|
||||
/* Start of tfc_tpg_np_base_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group);
|
||||
|
||||
static void target_fabric_np_base_release(struct config_item *item)
|
||||
{
|
||||
struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
|
||||
@@ -554,8 +505,6 @@ static void target_fabric_np_base_release(struct config_item *item)
|
||||
|
||||
static struct configfs_item_operations target_fabric_np_base_item_ops = {
|
||||
.release = target_fabric_np_base_release,
|
||||
.show_attribute = target_fabric_np_base_attr_show,
|
||||
.store_attribute = target_fabric_np_base_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL);
|
||||
@@ -610,132 +559,113 @@ TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
|
||||
|
||||
/* Start of tfc_tpg_port_cit */
|
||||
|
||||
CONFIGFS_EATTR_STRUCT(target_fabric_port, se_lun);
|
||||
#define TCM_PORT_ATTR(_name, _mode) \
|
||||
static struct target_fabric_port_attribute target_fabric_port_##_name = \
|
||||
__CONFIGFS_EATTR(_name, _mode, \
|
||||
target_fabric_port_show_attr_##_name, \
|
||||
target_fabric_port_store_attr_##_name);
|
||||
|
||||
#define TCM_PORT_ATTOR_RO(_name) \
|
||||
__CONFIGFS_EATTR_RO(_name, \
|
||||
target_fabric_port_show_attr_##_name);
|
||||
|
||||
/*
|
||||
* alua_tg_pt_gp
|
||||
*/
|
||||
static ssize_t target_fabric_port_show_attr_alua_tg_pt_gp(
|
||||
struct se_lun *lun,
|
||||
char *page)
|
||||
static struct se_lun *item_to_lun(struct config_item *item)
|
||||
{
|
||||
return container_of(to_config_group(item), struct se_lun,
|
||||
lun_group);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_show_tg_pt_gp_info(lun, page);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_port_store_attr_alua_tg_pt_gp(
|
||||
struct se_lun *lun,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_store_tg_pt_gp_info(lun, page, count);
|
||||
}
|
||||
|
||||
TCM_PORT_ATTR(alua_tg_pt_gp, S_IRUGO | S_IWUSR);
|
||||
|
||||
/*
|
||||
* alua_tg_pt_offline
|
||||
*/
|
||||
static ssize_t target_fabric_port_show_attr_alua_tg_pt_offline(
|
||||
struct se_lun *lun,
|
||||
char *page)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_offline_show(
|
||||
struct config_item *item, char *page)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_show_offline_bit(lun, page);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_port_store_attr_alua_tg_pt_offline(
|
||||
struct se_lun *lun,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_offline_store(
|
||||
struct config_item *item, const char *page, size_t count)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_store_offline_bit(lun, page, count);
|
||||
}
|
||||
|
||||
TCM_PORT_ATTR(alua_tg_pt_offline, S_IRUGO | S_IWUSR);
|
||||
|
||||
/*
|
||||
* alua_tg_pt_status
|
||||
*/
|
||||
static ssize_t target_fabric_port_show_attr_alua_tg_pt_status(
|
||||
struct se_lun *lun,
|
||||
char *page)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_status_show(
|
||||
struct config_item *item, char *page)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_show_secondary_status(lun, page);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_port_store_attr_alua_tg_pt_status(
|
||||
struct se_lun *lun,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_status_store(
|
||||
struct config_item *item, const char *page, size_t count)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_store_secondary_status(lun, page, count);
|
||||
}
|
||||
|
||||
TCM_PORT_ATTR(alua_tg_pt_status, S_IRUGO | S_IWUSR);
|
||||
|
||||
/*
|
||||
* alua_tg_pt_write_md
|
||||
*/
|
||||
static ssize_t target_fabric_port_show_attr_alua_tg_pt_write_md(
|
||||
struct se_lun *lun,
|
||||
char *page)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
|
||||
struct config_item *item, char *page)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_show_secondary_write_metadata(lun, page);
|
||||
}
|
||||
|
||||
static ssize_t target_fabric_port_store_attr_alua_tg_pt_write_md(
|
||||
struct se_lun *lun,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
|
||||
struct config_item *item, const char *page, size_t count)
|
||||
{
|
||||
struct se_lun *lun = item_to_lun(item);
|
||||
|
||||
if (!lun || !lun->lun_se_dev)
|
||||
return -ENODEV;
|
||||
|
||||
return core_alua_store_secondary_write_metadata(lun, page, count);
|
||||
}
|
||||
|
||||
TCM_PORT_ATTR(alua_tg_pt_write_md, S_IRUGO | S_IWUSR);
|
||||
|
||||
CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp);
|
||||
CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline);
|
||||
CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status);
|
||||
CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md);
|
||||
|
||||
static struct configfs_attribute *target_fabric_port_attrs[] = {
|
||||
&target_fabric_port_alua_tg_pt_gp.attr,
|
||||
&target_fabric_port_alua_tg_pt_offline.attr,
|
||||
&target_fabric_port_alua_tg_pt_status.attr,
|
||||
&target_fabric_port_alua_tg_pt_write_md.attr,
|
||||
&target_fabric_port_attr_alua_tg_pt_gp,
|
||||
&target_fabric_port_attr_alua_tg_pt_offline,
|
||||
&target_fabric_port_attr_alua_tg_pt_status,
|
||||
&target_fabric_port_attr_alua_tg_pt_write_md,
|
||||
NULL,
|
||||
};
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_port, se_lun, lun_group);
|
||||
|
||||
static int target_fabric_port_link(
|
||||
struct config_item *lun_ci,
|
||||
struct config_item *se_dev_ci)
|
||||
@@ -821,8 +751,6 @@ static void target_fabric_port_release(struct config_item *item)
|
||||
}
|
||||
|
||||
static struct configfs_item_operations target_fabric_port_item_ops = {
|
||||
.show_attribute = target_fabric_port_attr_show,
|
||||
.store_attribute = target_fabric_port_attr_store,
|
||||
.release = target_fabric_port_release,
|
||||
.allow_link = target_fabric_port_link,
|
||||
.drop_link = target_fabric_port_unlink,
|
||||
@@ -952,50 +880,11 @@ TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_lun_cit */
|
||||
|
||||
/* Start of tfc_tpg_attrib_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_tpg_attrib, se_portal_group, tpg_attrib_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_tpg_attrib_item_ops = {
|
||||
.show_attribute = target_fabric_tpg_attrib_attr_show,
|
||||
.store_attribute = target_fabric_tpg_attrib_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_attrib_cit */
|
||||
|
||||
/* Start of tfc_tpg_auth_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_tpg_auth, se_portal_group, tpg_auth_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_tpg_auth_item_ops = {
|
||||
.show_attribute = target_fabric_tpg_auth_attr_show,
|
||||
.store_attribute = target_fabric_tpg_auth_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_auth, &target_fabric_tpg_auth_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_attrib_cit */
|
||||
|
||||
/* Start of tfc_tpg_param_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_tpg_param_item_ops = {
|
||||
.show_attribute = target_fabric_tpg_param_attr_show,
|
||||
.store_attribute = target_fabric_tpg_param_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_param, &target_fabric_tpg_param_item_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_param_cit */
|
||||
TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL);
|
||||
TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL);
|
||||
TF_CIT_SETUP_DRV(tpg_param, NULL, NULL);
|
||||
|
||||
/* Start of tfc_tpg_base_cit */
|
||||
/*
|
||||
* For use with TF_TPG_ATTR() and TF_TPG_ATTR_RO()
|
||||
*/
|
||||
CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group);
|
||||
|
||||
static void target_fabric_tpg_release(struct config_item *item)
|
||||
{
|
||||
@@ -1009,8 +898,6 @@ static void target_fabric_tpg_release(struct config_item *item)
|
||||
|
||||
static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
|
||||
.release = target_fabric_tpg_release,
|
||||
.show_attribute = target_fabric_tpg_attr_show,
|
||||
.store_attribute = target_fabric_tpg_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL);
|
||||
@@ -1176,33 +1063,9 @@ static struct configfs_group_operations target_fabric_wwn_group_ops = {
|
||||
.make_group = target_fabric_make_wwn,
|
||||
.drop_item = target_fabric_drop_wwn,
|
||||
};
|
||||
/*
|
||||
* For use with TF_WWN_ATTR() and TF_WWN_ATTR_RO()
|
||||
*/
|
||||
CONFIGFS_EATTR_OPS(target_fabric_wwn, target_fabric_configfs, tf_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_wwn_item_ops = {
|
||||
.show_attribute = target_fabric_wwn_attr_show,
|
||||
.store_attribute = target_fabric_wwn_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops);
|
||||
|
||||
/* End of tfc_wwn_cit */
|
||||
|
||||
/* Start of tfc_discovery_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_discovery, target_fabric_configfs,
|
||||
tf_disc_group);
|
||||
|
||||
static struct configfs_item_operations target_fabric_discovery_item_ops = {
|
||||
.show_attribute = target_fabric_discovery_attr_show,
|
||||
.store_attribute = target_fabric_discovery_attr_store,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP_DRV(discovery, &target_fabric_discovery_item_ops, NULL);
|
||||
|
||||
/* End of tfc_discovery_cit */
|
||||
TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops);
|
||||
TF_CIT_SETUP_DRV(discovery, NULL, NULL);
|
||||
|
||||
int target_fabric_setup_cits(struct target_fabric_configfs *tf)
|
||||
{
|
||||
|
@@ -87,6 +87,9 @@ void target_free_device(struct se_device *);
|
||||
/* target_core_configfs.c */
|
||||
void target_setup_backend_cits(struct target_backend *);
|
||||
|
||||
/* target_core_fabric_configfs.c */
|
||||
int target_fabric_setup_cits(struct target_fabric_configfs *);
|
||||
|
||||
/* target_core_fabric_lib.c */
|
||||
int target_get_pr_transport_id_len(struct se_node_acl *nacl,
|
||||
struct t10_pr_registration *pr_reg, int *format_code);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/configfs_macros.h>
|
||||
|
||||
#include "tcm_fc.h"
|
||||
|
||||
|
@@ -38,8 +38,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/configfs_macros.h>
|
||||
|
||||
#include "tcm_fc.h"
|
||||
|
||||
@@ -131,55 +129,51 @@ static ssize_t ft_wwn_store(void *arg, const char *buf, size_t len)
|
||||
* ACL auth ops.
|
||||
*/
|
||||
|
||||
static ssize_t ft_nacl_show_port_name(
|
||||
struct se_node_acl *se_nacl,
|
||||
char *page)
|
||||
static ssize_t ft_nacl_port_name_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct se_node_acl *se_nacl = acl_to_nacl(item);
|
||||
struct ft_node_acl *acl = container_of(se_nacl,
|
||||
struct ft_node_acl, se_node_acl);
|
||||
|
||||
return ft_wwn_show(&acl->node_auth.port_name, page);
|
||||
}
|
||||
|
||||
static ssize_t ft_nacl_store_port_name(
|
||||
struct se_node_acl *se_nacl,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t ft_nacl_port_name_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_node_acl *se_nacl = acl_to_nacl(item);
|
||||
struct ft_node_acl *acl = container_of(se_nacl,
|
||||
struct ft_node_acl, se_node_acl);
|
||||
|
||||
return ft_wwn_store(&acl->node_auth.port_name, page, count);
|
||||
}
|
||||
|
||||
TF_NACL_BASE_ATTR(ft, port_name, S_IRUGO | S_IWUSR);
|
||||
|
||||
static ssize_t ft_nacl_show_node_name(
|
||||
struct se_node_acl *se_nacl,
|
||||
char *page)
|
||||
static ssize_t ft_nacl_node_name_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct se_node_acl *se_nacl = acl_to_nacl(item);
|
||||
struct ft_node_acl *acl = container_of(se_nacl,
|
||||
struct ft_node_acl, se_node_acl);
|
||||
|
||||
return ft_wwn_show(&acl->node_auth.node_name, page);
|
||||
}
|
||||
|
||||
static ssize_t ft_nacl_store_node_name(
|
||||
struct se_node_acl *se_nacl,
|
||||
const char *page,
|
||||
size_t count)
|
||||
static ssize_t ft_nacl_node_name_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct se_node_acl *se_nacl = acl_to_nacl(item);
|
||||
struct ft_node_acl *acl = container_of(se_nacl,
|
||||
struct ft_node_acl, se_node_acl);
|
||||
|
||||
return ft_wwn_store(&acl->node_auth.node_name, page, count);
|
||||
}
|
||||
|
||||
TF_NACL_BASE_ATTR(ft, node_name, S_IRUGO | S_IWUSR);
|
||||
CONFIGFS_ATTR(ft_nacl_, node_name);
|
||||
CONFIGFS_ATTR(ft_nacl_, port_name);
|
||||
|
||||
static struct configfs_attribute *ft_nacl_base_attrs[] = {
|
||||
&ft_nacl_port_name.attr,
|
||||
&ft_nacl_node_name.attr,
|
||||
&ft_nacl_attr_port_name,
|
||||
&ft_nacl_attr_node_name,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -386,18 +380,16 @@ static void ft_del_wwn(struct se_wwn *wwn)
|
||||
kfree(ft_wwn);
|
||||
}
|
||||
|
||||
static ssize_t ft_wwn_show_attr_version(
|
||||
struct target_fabric_configfs *tf,
|
||||
char *page)
|
||||
static ssize_t ft_wwn_version_show(struct config_item *item, char *page)
|
||||
{
|
||||
return sprintf(page, "TCM FC " FT_VERSION " on %s/%s on "
|
||||
""UTS_RELEASE"\n", utsname()->sysname, utsname()->machine);
|
||||
}
|
||||
|
||||
TF_WWN_ATTR_RO(ft, version);
|
||||
CONFIGFS_ATTR_RO(ft_wwn_, version);
|
||||
|
||||
static struct configfs_attribute *ft_wwn_attrs[] = {
|
||||
&ft_wwn_version.attr,
|
||||
&ft_wwn_attr_version,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@@ -44,7 +44,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/configfs_macros.h>
|
||||
|
||||
#include "tcm_fc.h"
|
||||
|
||||
|
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/configfs_macros.h>
|
||||
|
||||
#include "tcm_fc.h"
|
||||
|
||||
|
Reference in New Issue
Block a user