[PATCH 2/4] [Target_Core_Mod/ConfigFS]: Add implict ALUAattributes and move tg_pt_gp list

From: Nicholas A. Bellinger
Date: Tue Aug 18 2009 - 19:16:09 EST


Greetings,

This patch updates target_core_mod/ConfigFS to support to move the ALUA target port
group from the global location of /sys/kernel/config/target/core/alua/tg_pt_gps/ to
a per storage object location at /sys/kernel/config/target/core/$HBA/$DEV/alua/

This patch also adds the following new configfs attributes to
/sys/kernel/config/target/core/$HBA/$DEV/alua/

*) alua_access_state: Changing the implict ALUA primary access state.
*) alua_access_type: Currently available ALUA types (INQUIRY TPGS field)
*) nonop_delay_msecs: Millisecond delay for Active/NonOptimized path
*) preferred: Set preferred (PREF=1) bit for target port group

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/target/target_core_configfs.c | 240 ++++++++++++++++++++++++---------
1 files changed, 175 insertions(+), 65 deletions(-)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 847995a..e1b6154 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -1983,18 +1983,6 @@ static struct target_core_alua_lu_gp_attribute \
target_core_alua_lu_gp_show_attr_##_name);

/*
- * alua_access_state
- */
-static ssize_t target_core_alua_lu_gp_show_attr_alua_access_state(
- struct t10_alua_lu_gp_s *lu_gp,
- char *page)
-{
- return sprintf(page, "%d\n", lu_gp->lu_gp_alua_access_state);
-}
-
-SE_DEV_ALUA_LU_ATTR_RO(alua_access_state);
-
-/*
* lu_gp_id
*/
static ssize_t target_core_alua_lu_gp_show_attr_lu_gp_id(
@@ -2087,7 +2075,6 @@ SE_DEV_ALUA_LU_ATTR_RO(members);
CONFIGFS_EATTR_OPS(target_core_alua_lu_gp, t10_alua_lu_gp_s, lu_gp_group);

static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = {
- &target_core_alua_lu_gp_alua_access_state.attr,
&target_core_alua_lu_gp_lu_gp_id.attr,
&target_core_alua_lu_gp_members.attr,
NULL,
@@ -2187,7 +2174,116 @@ static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_state(
return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_alua_access_state);
}

-SE_DEV_ALUA_TG_PT_ATTR_RO(alua_access_state);
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ const char *page,
+ size_t count)
+{
+ se_subsystem_dev_t *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+ unsigned long tmp;
+ int new_state, ret;
+
+ if (!(tg_pt_gp->tg_pt_gp_valid_id)) {
+ printk(KERN_ERR "Unable to do implict ALUA on non valid"
+ " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
+ return -EINVAL;
+ }
+
+ ret = strict_strtoul(page, 0, &tmp);
+ if (ret < 0) {
+ printk("Unable to extract new ALUA access state from"
+ " %s\n", page);
+ return -EINVAL;
+ }
+ new_state = (int)tmp;
+
+ if (!(tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_IMPLICT_ALUA)) {
+ printk(KERN_ERR "Unable to process implict configfs ALUA"
+ " transition while TPGS_IMPLICT_ALUA is diabled\n");
+ return -EINVAL;
+ }
+
+ ret = core_alua_do_port_transition(tg_pt_gp, su_dev->se_dev_ptr,
+ NULL, NULL, new_state, 0);
+ return (!ret) ? count : -EINVAL;
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(alua_access_state, S_IRUGO | S_IWUSR);
+
+/*
+ * alua_access_status
+ */
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_status(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ char *page)
+{
+ return sprintf(page, "%s\n",
+ core_alua_dump_status(tg_pt_gp->tg_pt_gp_alua_access_status));
+}
+
+SE_DEV_ALUA_TG_PT_ATTR_RO(alua_access_status);
+
+/*
+ * alua_access_type
+ */
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_access_type(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ char *page)
+{
+ return core_alua_show_access_type(tg_pt_gp, page);
+}
+
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_type(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ const char *page,
+ size_t count)
+{
+ return core_alua_store_access_type(tg_pt_gp, page, count);
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
+
+/*
+ * nonop_delay_msecs
+ */
+static ssize_t target_core_alua_tg_pt_gp_show_attr_nonop_delay_msecs(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ char *page)
+{
+ return core_alua_show_nonop_delay_msecs(tg_pt_gp, page);
+
+}
+
+static ssize_t target_core_alua_tg_pt_gp_store_attr_nonop_delay_msecs(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ const char *page,
+ size_t count)
+{
+ return core_alua_store_nonop_delay_msecs(tg_pt_gp, page, count);
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(nonop_delay_msecs, S_IRUGO | S_IWUSR);
+
+/*
+ * preferred
+ */
+
+static ssize_t target_core_alua_tg_pt_gp_show_attr_preferred(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ char *page)
+{
+ return core_alua_show_preferred_bit(tg_pt_gp, page);
+}
+
+static ssize_t target_core_alua_tg_pt_gp_store_attr_preferred(
+ struct t10_alua_tg_pt_gp_s *tg_pt_gp,
+ const char *page,
+ size_t count)
+{
+ return core_alua_store_preferred_bit(tg_pt_gp, page, count);
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(preferred, S_IRUGO | S_IWUSR);

/*
* tg_pt_gp_id
@@ -2287,6 +2383,10 @@ CONFIGFS_EATTR_OPS(target_core_alua_tg_pt_gp, t10_alua_tg_pt_gp_s,

static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
&target_core_alua_tg_pt_gp_alua_access_state.attr,
+ &target_core_alua_tg_pt_gp_alua_access_status.attr,
+ &target_core_alua_tg_pt_gp_alua_access_type.attr,
+ &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
+ &target_core_alua_tg_pt_gp_preferred.attr,
&target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
&target_core_alua_tg_pt_gp_members.attr,
NULL,
@@ -2311,11 +2411,14 @@ static struct config_group *target_core_alua_create_tg_pt_gp(
struct config_group *group,
const char *name)
{
+ t10_alua_t *alua = container_of(group, t10_alua_t,
+ alua_tg_pt_gps_group);
t10_alua_tg_pt_gp_t *tg_pt_gp;
+ se_subsystem_dev_t *su_dev = alua->t10_sub_dev;
struct config_group *alua_tg_pt_gp_cg = NULL;
struct config_item *alua_tg_pt_gp_ci = NULL;

- tg_pt_gp = core_alua_allocate_tg_pt_gp(name, 0);
+ tg_pt_gp = core_alua_allocate_tg_pt_gp(su_dev, name, 0);
if (!(tg_pt_gp))
return NULL;

@@ -2326,7 +2429,7 @@ static struct config_group *target_core_alua_create_tg_pt_gp(
&target_core_alua_tg_pt_gp_cit);

printk(KERN_INFO "Target_Core_ConfigFS: Allocated ALUA Target Port"
- " Group: core/alua/tg_pt_gps/%s\n",
+ " Group: alua/tg_pt_gps/%s\n",
config_item_name(alua_tg_pt_gp_ci));

return alua_tg_pt_gp_cg;
@@ -2340,7 +2443,7 @@ static void target_core_alua_drop_tg_pt_gp(
t10_alua_tg_pt_gp_t, tg_pt_gp_group);

printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port"
- " Group: core/alua/tg_pt_gps/%s, ID: %hu\n",
+ " Group: alua/tg_pt_gps/%s, ID: %hu\n",
config_item_name(item), tg_pt_gp->tg_pt_gp_id);

config_item_put(item);
@@ -2381,11 +2484,12 @@ static struct config_group *target_core_call_createdev(
struct config_group *group,
const char *name)
{
+ t10_alua_tg_pt_gp_t *tg_pt_gp;
se_subsystem_dev_t *se_dev;
se_hba_t *hba;
se_subsystem_api_t *t;
struct config_item *hba_ci;
- struct config_group *dev_cg = NULL;
+ struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
int ret = 0;

hba_ci = &group->cg_item;
@@ -2423,15 +2527,18 @@ static struct config_group *target_core_call_createdev(
INIT_LIST_HEAD(&se_dev->t10_reservation.aptpl_reg_list);
spin_lock_init(&se_dev->t10_reservation.registration_lock);
spin_lock_init(&se_dev->t10_reservation.aptpl_reg_lock);
+ INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list);
+ spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock);
spin_lock_init(&se_dev->se_dev_lock);
se_dev->t10_reservation.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
se_dev->t10_wwn.t10_sub_dev = se_dev;
+ se_dev->t10_alua.t10_sub_dev = se_dev;
se_dev->se_dev_attrib.da_sub_dev = se_dev;

se_dev->se_dev_hba = hba;
dev_cg = &se_dev->se_dev_group;

- dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 5,
+ dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 6,
GFP_KERNEL);
if (!(dev_cg->default_groups))
goto out;
@@ -2466,11 +2573,35 @@ static struct config_group *target_core_call_createdev(
&target_core_dev_snap_cit);
config_group_init_type_name(&se_dev->t10_wwn.t10_wwn_group, "wwn",
&target_core_dev_wwn_cit);
+ config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
+ "alua", &target_core_alua_tg_pt_gps_cit);
dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
dev_cg->default_groups[2] = &se_dev->se_dev_snap_group;
dev_cg->default_groups[3] = &se_dev->t10_wwn.t10_wwn_group;
- dev_cg->default_groups[4] = NULL;
+ dev_cg->default_groups[4] = &se_dev->t10_alua.alua_tg_pt_gps_group;
+ dev_cg->default_groups[5] = NULL;
+ /*
+ * Add core/$HBA/$DEV/alua/tg_pt_gps/default_tg_pt_gp
+ */
+ tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
+ if (!(tg_pt_gp))
+ goto out;
+
+ tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
+ tg_pt_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
+ GFP_KERNEL);
+ if (!(tg_pt_gp_cg->default_groups)) {
+ printk(KERN_ERR "Unable to allocate tg_pt_gp_cg->"
+ "default_groups\n");
+ goto out;
+ }
+
+ config_group_init_type_name(&tg_pt_gp->tg_pt_gp_group,
+ "default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit);
+ tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
+ tg_pt_gp_cg->default_groups[1] = NULL;
+ T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp;

printk(KERN_INFO "Target_Core_ConfigFS: Allocated se_subsystem_dev_t:"
" %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
@@ -2478,8 +2609,16 @@ static struct config_group *target_core_call_createdev(
core_put_hba(hba);
return &se_dev->se_dev_group;
out:
+ if (T10_ALUA(se_dev)->default_tg_pt_gp) {
+ core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
+ T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
+ }
+ if (tg_pt_gp_cg)
+ kfree(tg_pt_gp_cg->default_groups);
if (dev_cg)
kfree(dev_cg->default_groups);
+ if (se_dev->se_dev_su_ptr)
+ t->free_device(se_dev->se_dev_su_ptr);
kfree(se_dev);
core_put_hba(hba);
return NULL;
@@ -2493,7 +2632,9 @@ static void target_core_call_freedev(
se_subsystem_dev_t, se_dev_group);
se_hba_t *hba;
se_subsystem_api_t *t;
- int ret = 0;
+ struct config_item *df_item;
+ struct config_group *tg_pt_gp_cg;
+ int i, ret = 0;

hba = target_core_get_hba_from_item(
&se_dev->se_dev_hba->hba_group.cg_item);
@@ -2509,6 +2650,15 @@ static void target_core_call_freedev(
list_del(&se_dev->g_se_dev_list);
spin_unlock(&se_global->g_device_lock);

+ tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
+ for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
+ df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
+ tg_pt_gp_cg->default_groups[i] = NULL;
+ config_item_put(df_item);
+ }
+ core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
+ T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
+
config_item_put(item);
/*
* This pointer will set when the storage is enabled with:
@@ -2686,13 +2836,12 @@ static struct config_item_type target_core_cit = {
int target_core_init_configfs(void)
{
struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
- struct config_group *lu_gp_cg = NULL, *tg_pt_gp_cg = NULL;
+ struct config_group *lu_gp_cg = NULL;
struct configfs_subsystem *subsys;
#ifdef SNMP_SUPPORT
struct proc_dir_entry *scsi_target_proc;
#endif
t10_alua_lu_gp_t *lu_gp;
- t10_alua_tg_pt_gp_t *tg_pt_gp;
int ret;

printk(KERN_INFO "TARGET_CORE[0]: Loading Generic Kernel Storage"
@@ -2746,7 +2895,7 @@ int target_core_init_configfs(void)
* groups under /sys/kernel/config/target/core/alua/
*/
alua_cg = &se_global->alua_group;
- alua_cg->default_groups = kzalloc(sizeof(struct config_group) * 3,
+ alua_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
GFP_KERNEL);
if (!(alua_cg->default_groups)) {
printk(KERN_ERR "Unable to allocate alua_cg->default_groups\n");
@@ -2755,11 +2904,8 @@ int target_core_init_configfs(void)

config_group_init_type_name(&se_global->alua_lu_gps_group,
"lu_gps", &target_core_alua_lu_gps_cit);
- config_group_init_type_name(&se_global->alua_tg_pt_gps_group,
- "tg_pt_gps", &target_core_alua_tg_pt_gps_cit);
alua_cg->default_groups[0] = &se_global->alua_lu_gps_group;
- alua_cg->default_groups[1] = &se_global->alua_tg_pt_gps_group;
- alua_cg->default_groups[2] = NULL;
+ alua_cg->default_groups[1] = NULL;
/*
* Add core/alua/lu_gps/default_lu_gp
*/
@@ -2781,27 +2927,6 @@ int target_core_init_configfs(void)
lu_gp_cg->default_groups[1] = NULL;
se_global->default_lu_gp = lu_gp;
/*
- * Add core/alua/tg_pt_gps/default_tg_pt_gp
- */
- tg_pt_gp = core_alua_allocate_tg_pt_gp("default_tg_pt_gp", 1);
- if (!(tg_pt_gp))
- goto out_global;
-
- tg_pt_gp_cg = &se_global->alua_tg_pt_gps_group;
- tg_pt_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
- GFP_KERNEL);
- if (!(tg_pt_gp_cg->default_groups)) {
- printk(KERN_ERR "Unable to allocate tg_pt_gp_cg->"
- "default_groups\n");
- goto out_global;
- }
-
- config_group_init_type_name(&tg_pt_gp->tg_pt_gp_group,
- "default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit);
- tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
- tg_pt_gp_cg->default_groups[1] = NULL;
- se_global->default_tg_pt_gp = tg_pt_gp;
- /*
* Register the target_core_mod subsystem with configfs.
*/
ret = configfs_register_subsystem(subsys);
@@ -2838,14 +2963,8 @@ out_global:
core_alua_free_lu_gp(se_global->default_lu_gp);
se_global->default_lu_gp = NULL;
}
- if (se_global->default_tg_pt_gp) {
- core_alua_free_tg_pt_gp(se_global->default_tg_pt_gp);
- se_global->default_tg_pt_gp = NULL;
- }
if (lu_gp_cg)
kfree(lu_gp_cg->default_groups);
- if (tg_pt_gp_cg)
- kfree(tg_pt_gp_cg->default_groups);
if (alua_cg)
kfree(alua_cg->default_groups);
if (hba_cg)
@@ -2858,22 +2977,13 @@ out_global:
void target_core_exit_configfs(void)
{
struct configfs_subsystem *subsys;
- struct config_group *hba_cg, *alua_cg, *lu_gp_cg, *tg_pt_gp_cg;
+ struct config_group *hba_cg, *alua_cg, *lu_gp_cg;
struct config_item *item;
int i;

se_global->in_shutdown = 1;
subsys = target_core_subsystem[0];

- tg_pt_gp_cg = &se_global->alua_tg_pt_gps_group;
- for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
- item = &tg_pt_gp_cg->default_groups[i]->cg_item;
- tg_pt_gp_cg->default_groups[i] = NULL;
- config_item_put(item);
- }
- core_alua_free_tg_pt_gp(se_global->default_tg_pt_gp);
- se_global->default_tg_pt_gp = NULL;
-
lu_gp_cg = &se_global->alua_lu_gps_group;
for (i = 0; lu_gp_cg->default_groups[i]; i++) {
item = &lu_gp_cg->default_groups[i]->cg_item;
--
1.5.4.1




--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/