[PATCH 4/6] [Target_Core_Mod/ALUA]: Add ALUA struct kmem_cachesand update EVPD 0x83 information
From: Nicholas A. Bellinger
Date: Fri Feb 06 2009 - 03:01:58 EST
>From 26cab633d02f548bba95b2b6c4677ce493165854 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Thu, 5 Feb 2009 23:18:29 -0800
Subject: [PATCH 4/6] [Target_Core_Mod/ALUA]: Add ALUA struct kmem_caches and update EVPD 0x83 information
This patch adds t10_alua_lu_gp_cache and t10_alua_tg_pt_gp_cache for use with
ALUA Logical Unit Group and Target Port Group emulation.
This patch also updates transport_generic_emulate_inquiry() to set the values
from different ALUA Logical Unit Group and Target Port Group assocations in
EVPD 0x83 response data.
Also, this patch also adds the logic EVPD 0x83 Target port group identifier and
Logical Unit Group identifier are not returned in response data unless said
T10_ALUA(se_subsystem_dev_t)->alue_type == SPC3_ALUA_EMULATED.
Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/lio-core/target_core_transport.c | 56 ++++++++++++++++++++++++++----
1 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/drivers/lio-core/target_core_transport.c b/drivers/lio-core/target_core_transport.c
index 28f3126..82ccd3c 100644
--- a/drivers/lio-core/target_core_transport.c
+++ b/drivers/lio-core/target_core_transport.c
@@ -209,6 +209,8 @@ struct kmem_cache *se_cmd_cache = NULL;
struct kmem_cache *se_task_cache = NULL;
struct kmem_cache *se_sess_cache = NULL;
struct kmem_cache *t10_pr_reg_cache = NULL;
+struct kmem_cache *t10_alua_lu_gp_cache = NULL;
+struct kmem_cache *t10_alua_tg_pt_gp_cache = NULL;
EXPORT_SYMBOL(se_global);
static int transport_generic_write_pending (se_cmd_t *);
@@ -254,8 +256,12 @@ extern int init_se_global (void)
return(-1);
};
+ INIT_LIST_HEAD(&global->g_lu_gps_list);
+ INIT_LIST_HEAD(&global->g_tg_pt_gps_list);
INIT_LIST_HEAD(&global->g_se_tpg_list);
spin_lock_init(&global->hba_lock);
+ spin_lock_init(&global->lu_gps_lock);
+ spin_lock_init(&global->tg_pt_gps_lock);
spin_lock_init(&global->plugin_class_lock);
if (!(se_cmd_cache = kmem_cache_create("se_cmd_cache",
@@ -280,6 +286,19 @@ extern int init_se_global (void)
printk(KERN_ERR "kmem_cache_create() for t10_pr_registration_t failed\n");
goto out;
}
+ if (!(t10_alua_lu_gp_cache = kmem_cache_create("t10_alua_lu_gp_cache",
+ sizeof(t10_alua_lu_gp_t), __alignof__(t10_alua_lu_gp_t),
+ 0, NULL))) {
+ printk(KERN_ERR "kmem_cache_create() for t10_alua_lu_gp_cache failed\n");
+ goto out;
+ }
+ if (!(t10_alua_tg_pt_gp_cache = kmem_cache_create("t10_alua_tg_pt_gp_cache",
+ sizeof(t10_alua_tg_pt_gp_t), __alignof__(t10_alua_tg_pt_gp_t),
+ 0, NULL))) {
+ printk(KERN_ERR "kmem_cache_create() for t10_alua_tg_pt_gp_cache failed\n");
+ goto out;
+ }
+
if (!(global->hba_list = kzalloc((sizeof(se_hba_t) *
TRANSPORT_MAX_GLOBAL_HBAS), GFP_KERNEL))) {
TRACE_ERROR("Unable to allocate global->hba_list\n");
@@ -319,6 +338,10 @@ out:
kmem_cache_destroy(se_sess_cache);
if (t10_pr_reg_cache)
kmem_cache_destroy(t10_pr_reg_cache);
+ if (t10_alua_lu_gp_cache)
+ kmem_cache_destroy(t10_alua_lu_gp_cache);
+ if (t10_alua_tg_pt_gp_cache)
+ kmem_cache_destroy(t10_alua_tg_pt_gp_cache);
kfree(global);
return(-1);
}
@@ -336,6 +359,8 @@ extern void release_se_global (void)
kmem_cache_destroy(se_task_cache);
kmem_cache_destroy(se_sess_cache);
kmem_cache_destroy(t10_pr_reg_cache);
+ kmem_cache_destroy(t10_alua_lu_gp_cache);
+ kmem_cache_destroy(t10_alua_tg_pt_gp_cache);
kfree(global);
se_global = NULL;
@@ -2059,11 +2084,13 @@ extern se_device_t *transport_add_device_to_core_hba (
dev->transport = transport;
atomic_set(&dev->active_cmds, 0);
INIT_LIST_HEAD(&dev->dev_sep_list);
+ INIT_LIST_HEAD(&dev->dev_lu_gp_list);
init_MUTEX_LOCKED(&dev->dev_queue_obj->thread_create_sem);
init_MUTEX_LOCKED(&dev->dev_queue_obj->thread_done_sem);
init_MUTEX_LOCKED(&dev->dev_queue_obj->thread_sem);
spin_lock_init(&dev->execute_task_lock);
spin_lock_init(&dev->state_task_lock);
+ spin_lock_init(&dev->dev_alua_lock);
spin_lock_init(&dev->dev_reservation_lock);
spin_lock_init(&dev->dev_status_lock);
spin_lock_init(&dev->dev_status_thr_lock);
@@ -4036,7 +4063,7 @@ extern int transport_generic_emulate_inquiry (
unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
unsigned char *cdb = T_TASK(cmd)->t_task_cdb;
unsigned char *iqn_sn;
- u32 vend_len, prod_len, iqn_sn_len, se_location_len;
+ u32 prod_len, iqn_sn_len, se_location_len;
u32 unit_serial_len, off = 0;
u16 len = 0;
@@ -4165,9 +4192,11 @@ extern int transport_generic_emulate_inquiry (
*/
check_port:
if ((port = lun->lun_sep)) {
+ t10_alua_lu_gp_t *lu_gp_p;
+ t10_alua_tg_pt_gp_t *tg_pt_gp_p;
u32 padding, scsi_name_len;
- u16 lun_gp = 0; // Set to zero for implict ALUA
- u16 tg_pg_i = 0; // Set to zero for implict ALUA
+ u16 lu_gp_id = 0;
+ u16 tg_pt_gp_id = 0;
u16 tpgt;
tpg = port->sep_tpg;
@@ -4199,10 +4228,18 @@ check_port:
* section 7.5.1 Table 362
*/
check_tpgi:
+ if (T10_ALUA(dev->se_sub_dev)->alua_type != SPC3_ALUA_EMULATED)
+ goto check_scsi_name;
+
if (((len + 4) + 8) > cmd->data_length) {
len += 8;
goto check_lu_gp;
}
+ spin_lock(&port->sep_alua_lock);
+ if ((tg_pt_gp_p = port->sep_alua_tg_pt_gp))
+ tg_pt_gp_id = tg_pt_gp_p->tg_pt_gp_id;
+ spin_unlock(&port->sep_alua_lock);
+
buf[off] = (TPG_TFO(tpg)->get_fabric_proto_ident() << 4);
buf[off++] |= 0x1; // CODE SET == Binary
buf[off] = 0x80; // Set PIV=1
@@ -4211,8 +4248,8 @@ check_tpgi:
off++; // Skip over Reserved
buf[off++] = 4; /* DESIGNATOR LENGTH */
off += 2; // Skip over Reserved Field
- buf[off++] = ((tg_pg_i >> 8) & 0xff);
- buf[off++] = (tg_pg_i & 0xff);
+ buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
+ buf[off++] = (tg_pt_gp_id & 0xff);
len += 8; // Header size + Designation descriptor
/*
* Logical Unit Group identifier, see spc4r17 section 7.7.3.8
@@ -4222,13 +4259,18 @@ check_lu_gp:
len += 8;
goto check_scsi_name;
}
+ spin_lock(&dev->dev_alua_lock);
+ if ((lu_gp_p = dev->dev_alua_lu_gp))
+ lu_gp_id = lu_gp_p->lu_gp_id;
+ spin_unlock(&dev->dev_alua_lock);
+
buf[off++] |= 0x1; // CODE SET == Binary
buf[off++] |= 0x6; // DESIGNATOR TYPE == Logical Unit Group identifier
off++; // Skip over Reserved
buf[off++] = 4; /* DESIGNATOR LENGTH */
off += 2; // Skip over Reserved Field
- buf[off++] = ((lun_gp >> 8) & 0xff);
- buf[off++] = (lun_gp & 0xff);
+ buf[off++] = ((lu_gp_id >> 8) & 0xff);
+ buf[off++] = (lu_gp_id & 0xff);
len += 8; // Header size + Designation descriptor
/*
* SCSI name string designator, see spc4r17 section 7.7.3.11
--
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/