From 7ad34a93675e9c5a65711f83c518871317adc2ee Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 3 May 2015 08:50:56 +0200 Subject: target: target_core_configfs.h is not needed in fabric drivers Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_ua.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/target/target_core_ua.c') diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index 1738b1646988..a0bf0d1a3df7 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -30,7 +30,6 @@ #include #include -#include #include "target_core_internal.h" #include "target_core_alua.h" -- cgit v1.2.3 From 29a05deebf6c2e3010934fb78ee65cab3d329470 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sun, 22 Mar 2015 20:42:19 -0700 Subject: target: Convert se_node_acl->device_list[] to RCU hlist This patch converts se_node_acl->device_list[] table for mappedluns to modern RCU hlist_head usage in order to support an arbitrary number of node_acl lun mappings. It converts transport_lookup_*_lun() fast-path code to use RCU read path primitives when looking up se_dev_entry. It adds a new hlist_head at se_node_acl->lun_entry_hlist for this purpose. For transport_lookup_cmd_lun() code, it works with existing per-cpu se_lun->lun_ref when associating se_cmd with se_lun + se_device. Also, go ahead and update core_create_device_list_for_node() + core_free_device_list_for_node() to use ->lun_entry_hlist. It also converts se_dev_entry->pr_ref_count access to use modern struct kref counting, and updates core_disable_device_list_for_node() to kref_put() and block on se_deve->pr_comp waiting for outstanding PR special-case PR references to drop, then invoke kfree_rcu() to wait for the RCU grace period to complete before releasing memory. So now that se_node_acl->lun_entry_hlist fast path access uses RCU protected pointers, go ahead and convert remaining non-fast path RCU updater code using ->lun_entry_lock to struct mutex to allow callers to block while walking se_node_acl->lun_entry_hlist. Finally drop the left-over core_clear_initiator_node_from_tpg() that originally cleared lun_access during se_node_acl shutdown, as post RCU conversion it now becomes duplicated logic. Reviewed-by: Hannes Reinecke Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Paul E. McKenney Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_alua.c | 3 +- drivers/target/target_core_device.c | 356 ++++++++++++++------------- drivers/target/target_core_fabric_configfs.c | 43 ++-- drivers/target/target_core_internal.h | 8 +- drivers/target/target_core_pr.c | 72 +++--- drivers/target/target_core_pscsi.c | 7 +- drivers/target/target_core_spc.c | 18 +- drivers/target/target_core_stat.c | 197 +++++++-------- drivers/target/target_core_tpg.c | 75 +----- drivers/target/target_core_ua.c | 51 ++-- include/target/target_core_backend.h | 2 +- include/target/target_core_base.h | 27 +- 12 files changed, 415 insertions(+), 444 deletions(-) (limited to 'drivers/target/target_core_ua.c') diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index b590f153a7b6..53cdfabac861 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1001,7 +1001,8 @@ static void core_alua_do_transition_tg_pt_work(struct work_struct *work) spin_lock_bh(&port->sep_alua_lock); list_for_each_entry(se_deve, &port->sep_alua_list, alua_port_list) { - lacl = se_deve->se_lun_acl; + lacl = rcu_dereference_check(se_deve->se_lun_acl, + lockdep_is_held(&port->sep_alua_lock)); /* * se_deve->se_lun_acl pointer may be NULL for a * entry created without explicit Node+MappedLUN ACLs diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 371a9770f563..e44e6bd66659 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -60,18 +60,17 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) { struct se_lun *se_lun = NULL; struct se_session *se_sess = se_cmd->se_sess; + struct se_node_acl *nacl = se_sess->se_node_acl; struct se_device *dev; - unsigned long flags; + struct se_dev_entry *deve; if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) return TCM_NON_EXISTENT_LUN; - spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); - se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; - if (se_cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { - struct se_dev_entry *deve = se_cmd->se_deve; - - deve->total_cmds++; + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, unpacked_lun); + if (deve) { + atomic_long_inc(&deve->total_cmds); if ((se_cmd->data_direction == DMA_TO_DEVICE) && (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { @@ -79,17 +78,19 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) " Access for 0x%08x\n", se_cmd->se_tfo->get_fabric_name(), unpacked_lun); - spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); + rcu_read_unlock(); return TCM_WRITE_PROTECTED; } if (se_cmd->data_direction == DMA_TO_DEVICE) - deve->write_bytes += se_cmd->data_length; + atomic_long_add(se_cmd->data_length, + &deve->write_bytes); else if (se_cmd->data_direction == DMA_FROM_DEVICE) - deve->read_bytes += se_cmd->data_length; + atomic_long_add(se_cmd->data_length, + &deve->read_bytes); - se_lun = deve->se_lun; - se_cmd->se_lun = deve->se_lun; + se_lun = rcu_dereference(deve->se_lun); + se_cmd->se_lun = rcu_dereference(deve->se_lun); se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; @@ -97,7 +98,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) percpu_ref_get(&se_lun->lun_ref); se_cmd->lun_ref_active = true; } - spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); + rcu_read_unlock(); if (!se_lun) { /* @@ -147,24 +148,23 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) struct se_dev_entry *deve; struct se_lun *se_lun = NULL; struct se_session *se_sess = se_cmd->se_sess; + struct se_node_acl *nacl = se_sess->se_node_acl; struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; unsigned long flags; if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) return -ENODEV; - spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); - se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; - deve = se_cmd->se_deve; - - if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { - se_tmr->tmr_lun = deve->se_lun; - se_cmd->se_lun = deve->se_lun; - se_lun = deve->se_lun; + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, unpacked_lun); + if (deve) { + se_tmr->tmr_lun = rcu_dereference(deve->se_lun); + se_cmd->se_lun = rcu_dereference(deve->se_lun); + se_lun = rcu_dereference(deve->se_lun); se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; } - spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); + rcu_read_unlock(); if (!se_lun) { pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" @@ -186,9 +186,27 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) } EXPORT_SYMBOL(transport_lookup_tmr_lun); +bool target_lun_is_rdonly(struct se_cmd *cmd) +{ + struct se_session *se_sess = cmd->se_sess; + struct se_dev_entry *deve; + bool ret; + + if (cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) + return true; + + rcu_read_lock(); + deve = target_nacl_find_deve(se_sess->se_node_acl, cmd->orig_fe_lun); + ret = (deve && deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY); + rcu_read_unlock(); + + return ret; +} +EXPORT_SYMBOL(target_lun_is_rdonly); + /* * This function is called from core_scsi3_emulate_pro_register_and_move() - * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_ref_count + * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_kref * when a matching rtpi is found. */ struct se_dev_entry *core_get_se_deve_from_rtpi( @@ -197,81 +215,43 @@ struct se_dev_entry *core_get_se_deve_from_rtpi( { struct se_dev_entry *deve; struct se_lun *lun; - struct se_port *port; struct se_portal_group *tpg = nacl->se_tpg; - u32 i; - - spin_lock_irq(&nacl->device_list_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = nacl->device_list[i]; - - if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) - continue; - lun = deve->se_lun; + rcu_read_lock(); + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { + lun = rcu_dereference(deve->se_lun); if (!lun) { pr_err("%s device entries device pointer is" " NULL, but Initiator has access.\n", tpg->se_tpg_tfo->get_fabric_name()); continue; } - port = lun->lun_sep; - if (!port) { - pr_err("%s device entries device pointer is" - " NULL, but Initiator has access.\n", - tpg->se_tpg_tfo->get_fabric_name()); - continue; - } - if (port->sep_rtpi != rtpi) + if (lun->lun_rtpi != rtpi) continue; - atomic_inc_mb(&deve->pr_ref_count); - spin_unlock_irq(&nacl->device_list_lock); + kref_get(&deve->pr_kref); + rcu_read_unlock(); return deve; } - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return NULL; } -int core_free_device_list_for_node( +void core_free_device_list_for_node( struct se_node_acl *nacl, struct se_portal_group *tpg) { struct se_dev_entry *deve; - struct se_lun *lun; - u32 i; - - if (!nacl->device_list) - return 0; - spin_lock_irq(&nacl->device_list_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = nacl->device_list[i]; - - if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) - continue; - - if (!deve->se_lun) { - pr_err("%s device entries device pointer is" - " NULL, but Initiator has access.\n", - tpg->se_tpg_tfo->get_fabric_name()); - continue; - } - lun = deve->se_lun; - - spin_unlock_irq(&nacl->device_list_lock); - core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); - spin_lock_irq(&nacl->device_list_lock); + mutex_lock(&nacl->lun_entry_mutex); + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { + struct se_lun *lun = rcu_dereference_check(deve->se_lun, + lockdep_is_held(&nacl->lun_entry_mutex)); + core_disable_device_list_for_node(lun, deve, nacl, tpg); } - spin_unlock_irq(&nacl->device_list_lock); - - array_free(nacl->device_list, TRANSPORT_MAX_LUNS_PER_TPG); - nacl->device_list = NULL; - - return 0; + mutex_unlock(&nacl->lun_entry_mutex); } void core_update_device_list_access( @@ -281,16 +261,40 @@ void core_update_device_list_access( { struct se_dev_entry *deve; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[mapped_lun]; - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - } else { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; + mutex_lock(&nacl->lun_entry_mutex); + deve = target_nacl_find_deve(nacl, mapped_lun); + if (deve) { + if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { + deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; + deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; + } else { + deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; + deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; + } } - spin_unlock_irq(&nacl->device_list_lock); + mutex_unlock(&nacl->lun_entry_mutex); +} + +/* + * Called with rcu_read_lock or nacl->device_list_lock held. + */ +struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *nacl, u32 mapped_lun) +{ + struct se_dev_entry *deve; + + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) + if (deve->mapped_lun == mapped_lun) + return deve; + + return NULL; +} +EXPORT_SYMBOL(target_nacl_find_deve); + +void target_pr_kref_release(struct kref *kref) +{ + struct se_dev_entry *deve = container_of(kref, struct se_dev_entry, + pr_kref); + complete(&deve->pr_comp); } /* core_enable_device_list_for_node(): @@ -306,85 +310,87 @@ int core_enable_device_list_for_node( struct se_portal_group *tpg) { struct se_port *port = lun->lun_sep; - struct se_dev_entry *deve; - - spin_lock_irq(&nacl->device_list_lock); - - deve = nacl->device_list[mapped_lun]; - - /* - * Check if the call is handling demo mode -> explicit LUN ACL - * transition. This transition must be for the same struct se_lun - * + mapped_lun that was setup in demo mode.. - */ - if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { - if (deve->se_lun_acl != NULL) { - pr_err("struct se_dev_entry->se_lun_acl" - " already set for demo mode -> explicit" - " LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); + struct se_dev_entry *orig, *new; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) { + pr_err("Unable to allocate se_dev_entry memory\n"); + return -ENOMEM; + } + + atomic_set(&new->ua_count, 0); + spin_lock_init(&new->ua_lock); + INIT_LIST_HEAD(&new->alua_port_list); + INIT_LIST_HEAD(&new->ua_list); + + new->mapped_lun = mapped_lun; + kref_init(&new->pr_kref); + init_completion(&new->pr_comp); + + if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) + new->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; + else + new->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; + + new->creation_time = get_jiffies_64(); + new->attach_count++; + + mutex_lock(&nacl->lun_entry_mutex); + orig = target_nacl_find_deve(nacl, mapped_lun); + if (orig && orig->se_lun) { + struct se_lun *orig_lun = rcu_dereference_check(orig->se_lun, + lockdep_is_held(&nacl->lun_entry_mutex)); + + if (orig_lun != lun) { + pr_err("Existing orig->se_lun doesn't match new lun" + " for dynamic -> explicit NodeACL conversion:" + " %s\n", nacl->initiatorname); + mutex_unlock(&nacl->lun_entry_mutex); + kfree(new); return -EINVAL; } - if (deve->se_lun != lun) { - pr_err("struct se_dev_entry->se_lun does" - " match passed struct se_lun for demo mode" - " -> explicit LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); - return -EINVAL; - } - deve->se_lun_acl = lun_acl; + BUG_ON(orig->se_lun_acl != NULL); - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - } else { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; - } + rcu_assign_pointer(new->se_lun, lun); + rcu_assign_pointer(new->se_lun_acl, lun_acl); + hlist_del_rcu(&orig->link); + hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist); + mutex_unlock(&nacl->lun_entry_mutex); - spin_unlock_irq(&nacl->device_list_lock); - return 0; - } + spin_lock_bh(&port->sep_alua_lock); + list_del(&orig->alua_port_list); + list_add_tail(&new->alua_port_list, &port->sep_alua_list); + spin_unlock_bh(&port->sep_alua_lock); - deve->se_lun = lun; - deve->se_lun_acl = lun_acl; - deve->mapped_lun = mapped_lun; - deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; + kref_put(&orig->pr_kref, target_pr_kref_release); + wait_for_completion(&orig->pr_comp); - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - } else { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; + kfree_rcu(orig, rcu_head); + return 0; } - deve->creation_time = get_jiffies_64(); - deve->attach_count++; - spin_unlock_irq(&nacl->device_list_lock); + rcu_assign_pointer(new->se_lun, lun); + rcu_assign_pointer(new->se_lun_acl, lun_acl); + hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist); + mutex_unlock(&nacl->lun_entry_mutex); spin_lock_bh(&port->sep_alua_lock); - list_add_tail(&deve->alua_port_list, &port->sep_alua_list); + list_add_tail(&new->alua_port_list, &port->sep_alua_list); spin_unlock_bh(&port->sep_alua_lock); return 0; } -/* core_disable_device_list_for_node(): - * - * +/* + * Called with se_node_acl->lun_entry_mutex held. */ -int core_disable_device_list_for_node( +void core_disable_device_list_for_node( struct se_lun *lun, - struct se_lun_acl *lun_acl, - u32 mapped_lun, - u32 lun_access, + struct se_dev_entry *orig, struct se_node_acl *nacl, struct se_portal_group *tpg) { struct se_port *port = lun->lun_sep; - struct se_dev_entry *deve = nacl->device_list[mapped_lun]; - /* * If the MappedLUN entry is being disabled, the entry in * port->sep_alua_list must be removed now before clearing the @@ -399,29 +405,29 @@ int core_disable_device_list_for_node( * MappedLUN *deve will be released below.. */ spin_lock_bh(&port->sep_alua_lock); - list_del(&deve->alua_port_list); + list_del(&orig->alua_port_list); spin_unlock_bh(&port->sep_alua_lock); /* - * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE - * PR operation to complete. + * Disable struct se_dev_entry LUN ACL mapping */ - while (atomic_read(&deve->pr_ref_count) != 0) - cpu_relax(); - - spin_lock_irq(&nacl->device_list_lock); + core_scsi3_ua_release_all(orig); + + hlist_del_rcu(&orig->link); + rcu_assign_pointer(orig->se_lun, NULL); + rcu_assign_pointer(orig->se_lun_acl, NULL); + orig->lun_flags = 0; + orig->creation_time = 0; + orig->attach_count--; /* - * Disable struct se_dev_entry LUN ACL mapping + * Before firing off RCU callback, wait for any in process SPEC_I_PT=1 + * or REGISTER_AND_MOVE PR operation to complete. */ - core_scsi3_ua_release_all(deve); - deve->se_lun = NULL; - deve->se_lun_acl = NULL; - deve->lun_flags = 0; - deve->creation_time = 0; - deve->attach_count--; - spin_unlock_irq(&nacl->device_list_lock); + kref_put(&orig->pr_kref, target_pr_kref_release); + wait_for_completion(&orig->pr_comp); + + kfree_rcu(orig, rcu_head); core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl); - return 0; } /* core_clear_lun_from_tpg(): @@ -432,26 +438,22 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) { struct se_node_acl *nacl; struct se_dev_entry *deve; - u32 i; spin_lock_irq(&tpg->acl_node_lock); list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { spin_unlock_irq(&tpg->acl_node_lock); - spin_lock_irq(&nacl->device_list_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = nacl->device_list[i]; - if (lun != deve->se_lun) - continue; - spin_unlock_irq(&nacl->device_list_lock); + mutex_lock(&nacl->lun_entry_mutex); + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { + struct se_lun *tmp_lun = rcu_dereference_check(deve->se_lun, + lockdep_is_held(&nacl->lun_entry_mutex)); - core_disable_device_list_for_node(lun, NULL, - deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, - nacl, tpg); + if (lun != tmp_lun) + continue; - spin_lock_irq(&nacl->device_list_lock); + core_disable_device_list_for_node(lun, deve, nacl, tpg); } - spin_unlock_irq(&nacl->device_list_lock); + mutex_unlock(&nacl->lun_entry_mutex); spin_lock_irq(&tpg->acl_node_lock); } @@ -583,7 +585,9 @@ int core_dev_export( if (IS_ERR(port)) return PTR_ERR(port); + lun->lun_index = dev->dev_index; lun->lun_se_dev = dev; + lun->lun_rtpi = port->sep_rtpi; spin_lock(&hba->device_lock); dev->export_count++; @@ -1369,16 +1373,13 @@ int core_dev_add_initiator_node_lun_acl( return 0; } -/* core_dev_del_initiator_node_lun_acl(): - * - * - */ int core_dev_del_initiator_node_lun_acl( struct se_portal_group *tpg, struct se_lun *lun, struct se_lun_acl *lacl) { struct se_node_acl *nacl; + struct se_dev_entry *deve; nacl = lacl->se_lun_nacl; if (!nacl) @@ -1389,8 +1390,11 @@ int core_dev_del_initiator_node_lun_acl( atomic_dec_mb(&lun->lun_acl_count); spin_unlock(&lun->lun_acl_lock); - core_disable_device_list_for_node(lun, NULL, lacl->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); + mutex_lock(&nacl->lun_entry_mutex); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (deve) + core_disable_device_list_for_node(lun, deve, nacl, tpg); + mutex_unlock(&nacl->lun_entry_mutex); lacl->se_lun = NULL; diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 6cb4828308e9..0939a5492c16 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -123,16 +123,16 @@ static int target_fabric_mappedlun_link( * which be will write protected (READ-ONLY) when * tpg_1/attrib/demo_mode_write_protect=1 */ - spin_lock_irq(&lacl->se_lun_nacl->device_list_lock); - deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun]; - if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) + rcu_read_lock(); + deve = target_nacl_find_deve(lacl->se_lun_nacl, lacl->mapped_lun); + if (deve) lun_access = deve->lun_flags; else lun_access = (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect( se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY : TRANSPORT_LUNFLAGS_READ_WRITE; - spin_unlock_irq(&lacl->se_lun_nacl->device_list_lock); + rcu_read_unlock(); /* * Determine the actual mapped LUN value user wants.. * @@ -149,23 +149,13 @@ static int target_fabric_mappedlun_unlink( struct config_item *lun_acl_ci, struct config_item *lun_ci) { - struct se_lun *lun; struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci), struct se_lun_acl, se_lun_group); - struct se_node_acl *nacl = lacl->se_lun_nacl; - struct se_dev_entry *deve = nacl->device_list[lacl->mapped_lun]; - struct se_portal_group *se_tpg; - /* - * Determine if the underlying MappedLUN has already been released.. - */ - if (!deve->se_lun) - return 0; - - lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group); - se_tpg = lun->lun_sep->sep_tpg; + struct se_lun *lun = container_of(to_config_group(lun_ci), + struct se_lun, lun_group); + struct se_portal_group *se_tpg = lun->lun_sep->sep_tpg; - core_dev_del_initiator_node_lun_acl(se_tpg, lun, lacl); - return 0; + return core_dev_del_initiator_node_lun_acl(se_tpg, lun, lacl); } CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl); @@ -181,14 +171,15 @@ static ssize_t target_fabric_mappedlun_show_write_protect( { struct se_node_acl *se_nacl = lacl->se_lun_nacl; struct se_dev_entry *deve; - ssize_t len; - - spin_lock_irq(&se_nacl->device_list_lock); - deve = se_nacl->device_list[lacl->mapped_lun]; - len = sprintf(page, "%d\n", - (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) ? - 1 : 0); - spin_unlock_irq(&se_nacl->device_list_lock); + ssize_t len = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(se_nacl, lacl->mapped_lun); + if (deve) { + len = sprintf(page, "%d\n", + (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) ? 1 : 0); + } + rcu_read_unlock(); return len; } diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index d0344ad9b0d8..a04a6e396ae3 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -9,13 +9,15 @@ extern struct mutex g_device_mutex; extern struct list_head g_device_list; struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); -int core_free_device_list_for_node(struct se_node_acl *, +void target_pr_kref_release(struct kref *); +void core_free_device_list_for_node(struct se_node_acl *, struct se_portal_group *); void core_update_device_list_access(u32, u32, struct se_node_acl *); +struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *, u32); int core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, u32, u32, struct se_node_acl *, struct se_portal_group *); -int core_disable_device_list_for_node(struct se_lun *, struct se_lun_acl *, - u32, u32, struct se_node_acl *, struct se_portal_group *); +void core_disable_device_list_for_node(struct se_lun *, struct se_dev_entry *, + struct se_node_acl *, struct se_portal_group *); void core_clear_lun_from_tpg(struct se_lun *, struct se_portal_group *); int core_dev_export(struct se_device *, struct se_portal_group *, struct se_lun *); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index a4b9a0dd50cd..909573a682d5 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -48,7 +48,7 @@ struct pr_transport_id_holder { struct t10_pr_registration *dest_pr_reg; struct se_portal_group *dest_tpg; struct se_node_acl *dest_node_acl; - struct se_dev_entry *dest_se_deve; + struct se_dev_entry __rcu *dest_se_deve; struct list_head dest_list; }; @@ -232,7 +232,7 @@ target_scsi2_reservation_release(struct se_cmd *cmd) tpg = sess->se_tpg; pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), - cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, + cmd->se_lun->unpacked_lun, cmd->orig_fe_lun, sess->se_node_acl->initiatorname); out_unlock: @@ -281,7 +281,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) dev->dev_reserved_node_acl->initiatorname); pr_err("Current attempt - LUN: %u -> MAPPED LUN: %u" " from %s \n", cmd->se_lun->unpacked_lun, - cmd->se_deve->mapped_lun, + cmd->orig_fe_lun, sess->se_node_acl->initiatorname); ret = TCM_RESERVATION_CONFLICT; goto out_unlock; @@ -295,7 +295,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) } pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u" " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), - cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, + cmd->se_lun->unpacked_lun, cmd->orig_fe_lun, sess->se_node_acl->initiatorname); out_unlock: @@ -320,6 +320,7 @@ static int core_scsi3_pr_seq_non_holder( unsigned char *cdb = cmd->t_task_cdb; struct se_dev_entry *se_deve; struct se_session *se_sess = cmd->se_sess; + struct se_node_acl *nacl = se_sess->se_node_acl; int other_cdb = 0, ignore_reg; int registered_nexus = 0, ret = 1; /* Conflict by default */ int all_reg = 0, reg_only = 0; /* ALL_REG, REG_ONLY */ @@ -327,7 +328,8 @@ static int core_scsi3_pr_seq_non_holder( int legacy = 0; /* Act like a legacy device and return * RESERVATION CONFLICT on some CDBs */ - se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; + rcu_read_lock(); + se_deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); /* * Determine if the registration should be ignored due to * non-matching ISIDs in target_scsi3_pr_reservation_check(). @@ -368,8 +370,10 @@ static int core_scsi3_pr_seq_non_holder( registered_nexus = 1; break; default: + rcu_read_unlock(); return -EINVAL; } + rcu_read_unlock(); /* * Referenced from spc4r17 table 45 for *NON* PR holder access */ @@ -735,7 +739,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( if (strcmp(nacl->initiatorname, nacl_tmp->initiatorname)) continue; - atomic_inc_mb(&deve_tmp->pr_ref_count); + kref_get(&deve_tmp->pr_kref); spin_unlock_bh(&port->sep_alua_lock); /* * Grab a configfs group dependency that is released @@ -748,7 +752,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( pr_err("core_scsi3_lunacl_depend" "_item() failed\n"); atomic_dec_mb(&port->sep_tg_pt_ref_cnt); - atomic_dec_mb(&deve_tmp->pr_ref_count); + kref_put(&deve_tmp->pr_kref, target_pr_kref_release); goto out; } /* @@ -763,7 +767,6 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( sa_res_key, all_tg_pt, aptpl); if (!pr_reg_atp) { atomic_dec_mb(&port->sep_tg_pt_ref_cnt); - atomic_dec_mb(&deve_tmp->pr_ref_count); core_scsi3_lunacl_undepend_item(deve_tmp); goto out; } @@ -896,7 +899,7 @@ static int __core_scsi3_check_aptpl_registration( struct se_lun *lun, u32 target_lun, struct se_node_acl *nacl, - struct se_dev_entry *deve) + u32 mapped_lun) { struct t10_pr_registration *pr_reg, *pr_reg_tmp; struct t10_reservation *pr_tmpl = &dev->t10_pr; @@ -924,13 +927,12 @@ static int __core_scsi3_check_aptpl_registration( pr_reg_aptpl_list) { if (!strcmp(pr_reg->pr_iport, i_port) && - (pr_reg->pr_res_mapped_lun == deve->mapped_lun) && + (pr_reg->pr_res_mapped_lun == mapped_lun) && !(strcmp(pr_reg->pr_tport, t_port)) && (pr_reg->pr_reg_tpgt == tpgt) && (pr_reg->pr_aptpl_target_lun == target_lun)) { pr_reg->pr_reg_nacl = nacl; - pr_reg->pr_reg_deve = deve; pr_reg->pr_reg_tg_pt_lun = lun; list_del(&pr_reg->pr_reg_aptpl_list); @@ -968,13 +970,12 @@ int core_scsi3_check_aptpl_registration( struct se_node_acl *nacl, u32 mapped_lun) { - struct se_dev_entry *deve = nacl->device_list[mapped_lun]; - if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) return 0; return __core_scsi3_check_aptpl_registration(dev, tpg, lun, - lun->unpacked_lun, nacl, deve); + lun->unpacked_lun, nacl, + mapped_lun); } static void __core_scsi3_dump_registration( @@ -1408,27 +1409,29 @@ static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve) static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) { - struct se_lun_acl *lun_acl = se_deve->se_lun_acl; + struct se_lun_acl *lun_acl; struct se_node_acl *nacl; struct se_portal_group *tpg; /* * For nacl->dynamic_node_acl=1 */ + lun_acl = se_deve->se_lun_acl; if (!lun_acl) { - atomic_dec_mb(&se_deve->pr_ref_count); + kref_put(&se_deve->pr_kref, target_pr_kref_release); return; } nacl = lun_acl->se_lun_nacl; tpg = nacl->se_tpg; target_undepend_item(&lun_acl->se_lun_group.cg_item); - atomic_dec_mb(&se_deve->pr_ref_count); + kref_put(&se_deve->pr_kref, target_pr_kref_release); } static sense_reason_t core_scsi3_decode_spec_i_port( struct se_cmd *cmd, struct se_portal_group *tpg, + struct se_dev_entry *local_se_deve, unsigned char *l_isid, u64 sa_res_key, int all_tg_pt, @@ -1439,7 +1442,7 @@ core_scsi3_decode_spec_i_port( struct se_portal_group *dest_tpg = NULL, *tmp_tpg; struct se_session *se_sess = cmd->se_sess; struct se_node_acl *dest_node_acl = NULL; - struct se_dev_entry *dest_se_deve = NULL, *local_se_deve; + struct se_dev_entry __rcu *dest_se_deve = NULL; struct t10_pr_registration *dest_pr_reg, *local_pr_reg, *pr_reg_e; struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; LIST_HEAD(tid_dest_list); @@ -1452,7 +1455,6 @@ core_scsi3_decode_spec_i_port( int dest_local_nexus; u32 dest_rtpi = 0; - local_se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; /* * Allocate a struct pr_transport_id_holder and setup the * local_node_acl and local_se_deve pointers and add to @@ -1467,7 +1469,6 @@ core_scsi3_decode_spec_i_port( INIT_LIST_HEAD(&tidh_new->dest_list); tidh_new->dest_tpg = tpg; tidh_new->dest_node_acl = se_sess->se_node_acl; - tidh_new->dest_se_deve = local_se_deve; local_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev, se_sess->se_node_acl, local_se_deve, l_isid, @@ -1476,6 +1477,7 @@ core_scsi3_decode_spec_i_port( kfree(tidh_new); return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } + rcu_assign_pointer(tidh_new->dest_se_deve, local_se_deve); tidh_new->dest_pr_reg = local_pr_reg; /* * The local I_T nexus does not hold any configfs dependances, @@ -1635,7 +1637,7 @@ core_scsi3_decode_spec_i_port( if (core_scsi3_lunacl_depend_item(dest_se_deve)) { pr_err("core_scsi3_lunacl_depend_item()" " failed\n"); - atomic_dec_mb(&dest_se_deve->pr_ref_count); + kref_put(&dest_se_deve->pr_kref, target_pr_kref_release); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; @@ -1990,6 +1992,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, bool aptpl, bool all_tg_pt, bool spec_i_pt, enum register_type register_type) { struct se_session *se_sess = cmd->se_sess; + struct se_node_acl *nacl = se_sess->se_node_acl; struct se_device *dev = cmd->se_dev; struct se_dev_entry *se_deve; struct se_lun *se_lun = cmd->se_lun; @@ -2005,7 +2008,14 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } se_tpg = se_sess->se_tpg; - se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; + + rcu_read_lock(); + se_deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); + if (!se_deve) { + pr_err("Unable to locate se_deve for PRO-REGISTER\n"); + rcu_read_unlock(); + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) { memset(&isid_buf[0], 0, PR_REG_ISID_LEN); @@ -2021,14 +2031,16 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, if (res_key) { pr_warn("SPC-3 PR: Reservation Key non-zero" " for SA REGISTER, returning CONFLICT\n"); + rcu_read_unlock(); return TCM_RESERVATION_CONFLICT; } /* * Do nothing but return GOOD status. */ - if (!sa_res_key) + if (!sa_res_key) { + rcu_read_unlock(); return 0; - + } if (!spec_i_pt) { /* * Perform the Service Action REGISTER on the Initiator @@ -2041,6 +2053,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, register_type, 0)) { pr_err("Unable to allocate" " struct t10_pr_registration\n"); + rcu_read_unlock(); return TCM_INVALID_PARAMETER_LIST; } } else { @@ -2052,14 +2065,17 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, * logic from of core_scsi3_alloc_registration() for * each TransportID provided SCSI Initiator Port/Device */ - ret = core_scsi3_decode_spec_i_port(cmd, se_tpg, + ret = core_scsi3_decode_spec_i_port(cmd, se_tpg, se_deve, isid_ptr, sa_res_key, all_tg_pt, aptpl); - if (ret != 0) + if (ret != 0) { + rcu_read_unlock(); return ret; + } } - + rcu_read_unlock(); return core_scsi3_update_and_write_aptpl(dev, aptpl); } + rcu_read_unlock(); /* ok, existing registration */ @@ -3321,7 +3337,7 @@ after_iport_check: if (core_scsi3_lunacl_depend_item(dest_se_deve)) { pr_err("core_scsi3_lunacl_depend_item() failed\n"); - atomic_dec_mb(&dest_se_deve->pr_ref_count); + kref_put(&dest_se_deve->pr_kref, target_pr_kref_release); dest_se_deve = NULL; ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; goto out; diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index ecc5eaef13d6..21db991b4465 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -47,6 +47,7 @@ #include #include "target_core_alua.h" +#include "target_core_internal.h" #include "target_core_pscsi.h" #define ISPRINT(a) ((a >= ' ') && (a <= '~')) @@ -637,12 +638,14 @@ static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, * Hack to make sure that Write-Protect modepage is set if R/O mode is * forced. */ - if (!cmd->se_deve || !cmd->data_length) + if (!cmd->data_length) goto after_mode_sense; if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && (status_byte(result) << 1) == SAM_STAT_GOOD) { - if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { + bool read_only = target_lun_is_rdonly(cmd); + + if (read_only) { unsigned char *buf; buf = transport_kmap_data_sg(cmd); diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 78c0b40fa5c0..9f995b87b8d1 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -981,6 +981,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) int length = 0; int ret; int i; + bool read_only = target_lun_is_rdonly(cmd);; memset(buf, 0, SE_MODE_PAGE_BUF); @@ -991,9 +992,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) length = ten ? 3 : 2; /* DEVICE-SPECIFIC PARAMETER */ - if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || - (cmd->se_deve && - (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) + if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || read_only) spc_modesense_write_protect(&buf[length], type); /* @@ -1211,8 +1210,9 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) { struct se_dev_entry *deve; struct se_session *sess = cmd->se_sess; + struct se_node_acl *nacl; unsigned char *buf; - u32 lun_count = 0, offset = 8, i; + u32 lun_count = 0, offset = 8; if (cmd->data_length < 16) { pr_warn("REPORT LUNS allocation length %u too small\n", @@ -1234,12 +1234,10 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) lun_count = 1; goto done; } + nacl = sess->se_node_acl; - spin_lock_irq(&sess->se_node_acl->device_list_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = sess->se_node_acl->device_list[i]; - if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) - continue; + rcu_read_lock(); + hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { /* * We determine the correct LUN LIST LENGTH even once we * have reached the initial allocation length. @@ -1252,7 +1250,7 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); offset += 8; } - spin_unlock_irq(&sess->se_node_acl->device_list_lock); + rcu_read_unlock(); /* * See SPC3 r07, page 159. diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index 64efee2fba52..ea1287940a7c 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c @@ -1084,17 +1084,17 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_inst( struct se_portal_group *tpg; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } tpg = nacl->se_tpg; /* scsiInstIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_inst_index(tpg)); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(inst); @@ -1109,16 +1109,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_dev( struct se_lun *lun; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } - lun = deve->se_lun; + lun = rcu_dereference(deve->se_lun); /* scsiDeviceIndex */ - ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index); - spin_unlock_irq(&nacl->device_list_lock); + ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_index); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev); @@ -1133,16 +1133,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_port( struct se_portal_group *tpg; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } tpg = nacl->se_tpg; /* scsiAuthIntrTgtPortIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_tag(tpg)); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(port); @@ -1156,15 +1156,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_indx( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(indx); @@ -1178,15 +1178,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_dev_or_port( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrDevOrPort */ ret = snprintf(page, PAGE_SIZE, "%u\n", 1); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev_or_port); @@ -1200,15 +1200,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_intr_name( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrName */ ret = snprintf(page, PAGE_SIZE, "%s\n", nacl->initiatorname); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(intr_name); @@ -1222,15 +1222,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_map_indx( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* FIXME: scsiAuthIntrLunMapIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", 0); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(map_indx); @@ -1244,15 +1244,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_att_count( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrAttachedTimes */ ret = snprintf(page, PAGE_SIZE, "%u\n", deve->attach_count); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(att_count); @@ -1266,15 +1266,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_num_cmds( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrOutCommands */ - ret = snprintf(page, PAGE_SIZE, "%u\n", deve->total_cmds); - spin_unlock_irq(&nacl->device_list_lock); + ret = snprintf(page, PAGE_SIZE, "%lu\n", + atomic_long_read(&deve->total_cmds)); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(num_cmds); @@ -1288,15 +1289,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_read_mbytes( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrReadMegaBytes */ - ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->read_bytes >> 20)); - spin_unlock_irq(&nacl->device_list_lock); + ret = snprintf(page, PAGE_SIZE, "%u\n", + (u32)(atomic_long_read(&deve->read_bytes) >> 20)); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(read_mbytes); @@ -1310,15 +1312,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_write_mbytes( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrWrittenMegaBytes */ - ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->write_bytes >> 20)); - spin_unlock_irq(&nacl->device_list_lock); + ret = snprintf(page, PAGE_SIZE, "%u\n", + (u32)(atomic_long_read(&deve->write_bytes) >> 20)); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(write_mbytes); @@ -1332,15 +1335,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_hs_num_cmds( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* FIXME: scsiAuthIntrHSOutCommands */ ret = snprintf(page, PAGE_SIZE, "%u\n", 0); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(hs_num_cmds); @@ -1354,16 +1357,16 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_creation_time( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAuthIntrLastCreation */ ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)deve->creation_time - INITIAL_JIFFIES) * 100 / HZ)); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(creation_time); @@ -1377,15 +1380,15 @@ static ssize_t target_stat_scsi_auth_intr_show_attr_row_status( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* FIXME: scsiAuthIntrRowStatus */ ret = snprintf(page, PAGE_SIZE, "Ready\n"); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(row_status); @@ -1450,17 +1453,17 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_inst( struct se_portal_group *tpg; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } tpg = nacl->se_tpg; /* scsiInstIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_inst_index(tpg)); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(inst); @@ -1475,16 +1478,16 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_dev( struct se_lun *lun; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } - lun = deve->se_lun; + lun = rcu_dereference(deve->se_lun); /* scsiDeviceIndex */ - ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index); - spin_unlock_irq(&nacl->device_list_lock); + ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_index); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(dev); @@ -1499,16 +1502,16 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_port( struct se_portal_group *tpg; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } tpg = nacl->se_tpg; /* scsiPortIndex */ ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_tag(tpg)); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port); @@ -1548,15 +1551,15 @@ static ssize_t target_stat_scsi_att_intr_port_show_attr_port_auth_indx( struct se_dev_entry *deve; ssize_t ret; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[lacl->mapped_lun]; - if (!deve->se_lun || !deve->se_lun_acl) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); + if (!deve) { + rcu_read_unlock(); return -ENODEV; } /* scsiAttIntrPortAuthIntrIdx */ ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return ret; } DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_auth_indx); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index c0c1f67facb5..0519923ef930 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -47,42 +47,6 @@ extern struct se_device *g_lun0_dev; static DEFINE_SPINLOCK(tpg_lock); static LIST_HEAD(tpg_list); -/* core_clear_initiator_node_from_tpg(): - * - * - */ -static void core_clear_initiator_node_from_tpg( - struct se_node_acl *nacl, - struct se_portal_group *tpg) -{ - int i; - struct se_dev_entry *deve; - struct se_lun *lun; - - spin_lock_irq(&nacl->device_list_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = nacl->device_list[i]; - - if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) - continue; - - if (!deve->se_lun) { - pr_err("%s device entries device pointer is" - " NULL, but Initiator has access.\n", - tpg->se_tpg_tfo->get_fabric_name()); - continue; - } - - lun = deve->se_lun; - spin_unlock_irq(&nacl->device_list_lock); - core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, - TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); - - spin_lock_irq(&nacl->device_list_lock); - } - spin_unlock_irq(&nacl->device_list_lock); -} - /* __core_tpg_get_initiator_node_acl(): * * spin_lock_bh(&tpg->acl_node_lock); must be held when calling @@ -225,35 +189,6 @@ static void *array_zalloc(int n, size_t size, gfp_t flags) return a; } -/* core_create_device_list_for_node(): - * - * - */ -static int core_create_device_list_for_node(struct se_node_acl *nacl) -{ - struct se_dev_entry *deve; - int i; - - nacl->device_list = array_zalloc(TRANSPORT_MAX_LUNS_PER_TPG, - sizeof(struct se_dev_entry), GFP_KERNEL); - if (!nacl->device_list) { - pr_err("Unable to allocate memory for" - " struct se_node_acl->device_list\n"); - return -ENOMEM; - } - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - deve = nacl->device_list[i]; - - atomic_set(&deve->ua_count, 0); - atomic_set(&deve->pr_ref_count, 0); - spin_lock_init(&deve->ua_lock); - INIT_LIST_HEAD(&deve->alua_port_list); - INIT_LIST_HEAD(&deve->ua_list); - } - - return 0; -} - static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg, const unsigned char *initiatorname) { @@ -266,10 +201,11 @@ static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg, INIT_LIST_HEAD(&acl->acl_list); INIT_LIST_HEAD(&acl->acl_sess_list); + INIT_HLIST_HEAD(&acl->lun_entry_hlist); kref_init(&acl->acl_kref); init_completion(&acl->acl_free_comp); - spin_lock_init(&acl->device_list_lock); spin_lock_init(&acl->nacl_sess_lock); + mutex_init(&acl->lun_entry_mutex); atomic_set(&acl->acl_pr_ref_count, 0); if (tpg->se_tpg_tfo->tpg_get_default_depth) acl->queue_depth = tpg->se_tpg_tfo->tpg_get_default_depth(tpg); @@ -281,15 +217,11 @@ static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg, tpg->se_tpg_tfo->set_default_node_attributes(acl); - if (core_create_device_list_for_node(acl) < 0) - goto out_free_acl; if (core_set_queue_depth_for_node(tpg, acl) < 0) - goto out_free_device_list; + goto out_free_acl; return acl; -out_free_device_list: - core_free_device_list_for_node(acl, tpg); out_free_acl: kfree(acl); return NULL; @@ -454,7 +386,6 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl) wait_for_completion(&acl->acl_free_comp); core_tpg_wait_for_nacl_pr_ref(acl); - core_clear_initiator_node_from_tpg(acl, tpg); core_free_device_list_for_node(acl, tpg); pr_debug("%s_TPG[%hu] - Deleted ACL with TCQ Depth: %d for %s" diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index a0bf0d1a3df7..6c9616d212b1 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -50,9 +50,17 @@ target_scsi3_ua_check(struct se_cmd *cmd) if (!nacl) return 0; - deve = nacl->device_list[cmd->orig_fe_lun]; - if (!atomic_read(&deve->ua_count)) + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); + if (!deve) { + rcu_read_unlock(); return 0; + } + if (!atomic_read(&deve->ua_count)) { + rcu_read_unlock(); + return 0; + } + rcu_read_unlock(); /* * From sam4r14, section 5.14 Unit attention condition: * @@ -103,9 +111,12 @@ int core_scsi3_ua_allocate( ua->ua_asc = asc; ua->ua_ascq = ascq; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[unpacked_lun]; - + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, unpacked_lun); + if (!deve) { + rcu_read_unlock(); + return -EINVAL; + } spin_lock(&deve->ua_lock); list_for_each_entry_safe(ua_p, ua_tmp, &deve->ua_list, ua_nacl_list) { /* @@ -113,7 +124,7 @@ int core_scsi3_ua_allocate( */ if ((ua_p->ua_asc == asc) && (ua_p->ua_ascq == ascq)) { spin_unlock(&deve->ua_lock); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); kmem_cache_free(se_ua_cache, ua); return 0; } @@ -158,14 +169,13 @@ int core_scsi3_ua_allocate( list_add_tail(&ua->ua_nacl_list, &deve->ua_list); spin_unlock(&deve->ua_lock); - spin_unlock_irq(&nacl->device_list_lock); atomic_inc_mb(&deve->ua_count); + rcu_read_unlock(); return 0; } list_add_tail(&ua->ua_nacl_list, &deve->ua_list); spin_unlock(&deve->ua_lock); - spin_unlock_irq(&nacl->device_list_lock); pr_debug("[%s]: Allocated UNIT ATTENTION, mapped LUN: %u, ASC:" " 0x%02x, ASCQ: 0x%02x\n", @@ -173,6 +183,7 @@ int core_scsi3_ua_allocate( asc, ascq); atomic_inc_mb(&deve->ua_count); + rcu_read_unlock(); return 0; } @@ -210,10 +221,14 @@ void core_scsi3_ua_for_check_condition( if (!nacl) return; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[cmd->orig_fe_lun]; + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); + if (!deve) { + rcu_read_unlock(); + return; + } if (!atomic_read(&deve->ua_count)) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return; } /* @@ -249,7 +264,7 @@ void core_scsi3_ua_for_check_condition( atomic_dec_mb(&deve->ua_count); } spin_unlock(&deve->ua_lock); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); pr_debug("[%s]: %s UNIT ATTENTION condition with" " INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x" @@ -278,10 +293,14 @@ int core_scsi3_ua_clear_for_request_sense( if (!nacl) return -EINVAL; - spin_lock_irq(&nacl->device_list_lock); - deve = nacl->device_list[cmd->orig_fe_lun]; + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); + if (!deve) { + rcu_read_unlock(); + return -EINVAL; + } if (!atomic_read(&deve->ua_count)) { - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); return -EPERM; } /* @@ -307,7 +326,7 @@ int core_scsi3_ua_clear_for_request_sense( atomic_dec_mb(&deve->ua_count); } spin_unlock(&deve->ua_lock); - spin_unlock_irq(&nacl->device_list_lock); + rcu_read_unlock(); pr_debug("[%s]: Released UNIT ATTENTION condition, mapped" " LUN: %u, got REQUEST_SENSE reported ASC: 0x%02x," diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 47fafec556f8..80d9e486e33e 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -101,7 +101,7 @@ int target_alloc_sgl(struct scatterlist **, unsigned int *, u32, bool); sense_reason_t transport_generic_map_mem_to_cmd(struct se_cmd *, struct scatterlist *, u32, struct scatterlist *, u32); -void array_free(void *array, int n); +bool target_lun_is_rdonly(struct se_cmd *); /* From target_core_configfs.c to setup default backend config_item_types */ void target_core_setup_sub_cits(struct se_subsystem_api *); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 042a73464966..b518523cba7b 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -160,10 +160,8 @@ enum se_cmd_flags_table { /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ enum transport_lunflags_table { - TRANSPORT_LUNFLAGS_NO_ACCESS = 0x00, - TRANSPORT_LUNFLAGS_INITIATOR_ACCESS = 0x01, - TRANSPORT_LUNFLAGS_READ_ONLY = 0x02, - TRANSPORT_LUNFLAGS_READ_WRITE = 0x04, + TRANSPORT_LUNFLAGS_READ_ONLY = 0x01, + TRANSPORT_LUNFLAGS_READ_WRITE = 0x02, }; /* @@ -584,10 +582,10 @@ struct se_node_acl { char acl_tag[MAX_ACL_TAG_SIZE]; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t acl_pr_ref_count; - struct se_dev_entry **device_list; + struct hlist_head lun_entry_hlist; struct se_session *nacl_sess; struct se_portal_group *se_tpg; - spinlock_t device_list_lock; + struct mutex lun_entry_mutex; spinlock_t nacl_sess_lock; struct config_group acl_group; struct config_group acl_attrib_group; @@ -644,20 +642,23 @@ struct se_dev_entry { /* See transport_lunflags_table */ u32 lun_flags; u32 mapped_lun; - u32 total_cmds; u64 pr_res_key; u64 creation_time; u32 attach_count; - u64 read_bytes; - u64 write_bytes; + atomic_long_t total_cmds; + atomic_long_t read_bytes; + atomic_long_t write_bytes; atomic_t ua_count; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ - atomic_t pr_ref_count; - struct se_lun_acl *se_lun_acl; + struct kref pr_kref; + struct completion pr_comp; + struct se_lun_acl __rcu *se_lun_acl; spinlock_t ua_lock; - struct se_lun *se_lun; + struct se_lun __rcu *se_lun; struct list_head alua_port_list; struct list_head ua_list; + struct hlist_node link; + struct rcu_head rcu_head; }; struct se_dev_attrib { @@ -703,6 +704,7 @@ struct se_port_stat_grps { }; struct se_lun { + u16 lun_rtpi; #define SE_LUN_LINK_MAGIC 0xffff7771 u32 lun_link_magic; /* See transport_lun_status_table */ @@ -710,6 +712,7 @@ struct se_lun { u32 lun_access; u32 lun_flags; u32 unpacked_lun; + u32 lun_index; atomic_t lun_acl_count; spinlock_t lun_acl_lock; spinlock_t lun_sep_lock; -- cgit v1.2.3 From f2d30680204f20b815e6796437923fb870b6c193 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 10 Jun 2015 08:41:22 +0200 Subject: target: use 64-bit LUNs As we're now using a list to hold the LUNs the target core can now converted to use 64-bit LUNs internally. Signed-off-by: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_tmr.c | 4 +-- drivers/target/loopback/tcm_loop.c | 4 +-- drivers/target/target_core_alua.c | 2 +- drivers/target/target_core_configfs.c | 12 ++++---- drivers/target/target_core_device.c | 30 +++++++++---------- drivers/target/target_core_fabric_configfs.c | 18 ++++-------- drivers/target/target_core_internal.h | 10 +++---- drivers/target/target_core_pr.c | 43 ++++++++++++++-------------- drivers/target/target_core_pr.h | 6 ++-- drivers/target/target_core_tpg.c | 6 ++-- drivers/target/target_core_transport.c | 6 ++-- drivers/target/target_core_ua.c | 8 +++--- drivers/target/target_core_ua.h | 2 +- include/target/target_core_base.h | 19 ++++++------ include/target/target_core_fabric.h | 10 +++---- 15 files changed, 88 insertions(+), 92 deletions(-) (limited to 'drivers/target/target_core_ua.c') diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index b0224a77e26d..515988258e9e 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -120,7 +120,7 @@ u8 iscsit_tmr_task_reassign( struct iscsi_tmr_req *tmr_req = cmd->tmr_req; struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; struct iscsi_tm *hdr = (struct iscsi_tm *) buf; - int ret, ref_lun; + u64 ret, ref_lun; pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x," " RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n", @@ -164,7 +164,7 @@ u8 iscsit_tmr_task_reassign( ref_lun = scsilun_to_int(&hdr->lun); if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) { pr_err("Unable to perform connection recovery for" - " differing ref_lun: %d ref_cmd orig_fe_lun: %u\n", + " differing ref_lun: %llu ref_cmd orig_fe_lun: %llu\n", ref_lun, ref_cmd->se_cmd.orig_fe_lun); return ISCSI_TMF_RSP_REJECTED; } diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index bd9d11a6f823..a556bdebd775 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -215,7 +215,7 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) * to struct scsi_device */ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, - int lun, int task, enum tcm_tmreq_table tmr) + u64 lun, int task, enum tcm_tmreq_table tmr) { struct se_cmd *se_cmd = NULL; struct se_session *se_sess; @@ -747,7 +747,7 @@ static void tcm_loop_port_unlink( se_lun->unpacked_lun); if (!sd) { pr_err("Unable to locate struct scsi_device for %d:%d:" - "%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun); + "%llu\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun); return; } /* diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 02d8e1a8a6a5..2318e6e5ce52 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1257,7 +1257,7 @@ static int core_alua_update_tpg_secondary_metadata(struct se_lun *lun) atomic_read(&lun->lun_tg_pt_secondary_offline), lun->lun_tg_pt_secondary_stat); - snprintf(path, ALUA_METADATA_PATH_LEN, "/var/target/alua/%s/%s/lun_%u", + snprintf(path, ALUA_METADATA_PATH_LEN, "/var/target/alua/%s/%s/lun_%llu", se_tpg->se_tpg_tfo->get_fabric_name(), wwn, lun->unpacked_lun); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index f97b969e6714..68addbc7eb7b 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1438,7 +1438,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( tfo->tpg_get_wwn(se_tpg)); len += sprintf(page+len, "SPC-3 Reservation: Relative Port" " Identifier Tag: %hu %s Portal Group Tag: %hu" - " %s Logical Unit: %u\n", pr_reg->tg_pt_sep_rtpi, + " %s Logical Unit: %llu\n", pr_reg->tg_pt_sep_rtpi, tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), tfo->get_fabric_name(), pr_reg->pr_aptpl_target_lun); @@ -1565,12 +1565,12 @@ static match_table_t tokens = { {Opt_res_type, "res_type=%d"}, {Opt_res_scope, "res_scope=%d"}, {Opt_res_all_tg_pt, "res_all_tg_pt=%d"}, - {Opt_mapped_lun, "mapped_lun=%d"}, + {Opt_mapped_lun, "mapped_lun=%lld"}, {Opt_target_fabric, "target_fabric=%s"}, {Opt_target_node, "target_node=%s"}, {Opt_tpgt, "tpgt=%d"}, {Opt_port_rtpi, "port_rtpi=%d"}, - {Opt_target_lun, "target_lun=%d"}, + {Opt_target_lun, "target_lun=%lld"}, {Opt_err, NULL} }; @@ -1585,7 +1585,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( substring_t args[MAX_OPT_ARGS]; unsigned long long tmp_ll; u64 sa_res_key = 0; - u32 mapped_lun = 0, target_lun = 0; + u64 mapped_lun = 0, target_lun = 0; int ret = -1, res_holder = 0, all_tg_pt = 0, arg, token; u16 tpgt = 0; u8 type = 0; @@ -1675,7 +1675,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( break; case Opt_mapped_lun: match_int(args, &arg); - mapped_lun = (u32)arg; + mapped_lun = (u64)arg; break; /* * PR APTPL Metadata for Target Port @@ -1710,7 +1710,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( break; case Opt_target_lun: match_int(args, &arg); - target_lun = (u32)arg; + target_lun = (u64)arg; break; default: break; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index db531fb5e787..2ea7322c4dd4 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -56,7 +56,7 @@ static struct se_hba *lun0_hba; struct se_device *g_lun0_dev; sense_reason_t -transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) +transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) { struct se_lun *se_lun = NULL; struct se_session *se_sess = se_cmd->se_sess; @@ -74,7 +74,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) if ((se_cmd->data_direction == DMA_TO_DEVICE) && (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" - " Access for 0x%08x\n", + " Access for 0x%08llx\n", se_cmd->se_tfo->get_fabric_name(), unpacked_lun); rcu_read_unlock(); @@ -107,7 +107,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) */ if (unpacked_lun != 0) { pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" - " Access for 0x%08x\n", + " Access for 0x%08llx\n", se_cmd->se_tfo->get_fabric_name(), unpacked_lun); return TCM_NON_EXISTENT_LUN; @@ -147,7 +147,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) } EXPORT_SYMBOL(transport_lookup_cmd_lun); -int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) +int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun) { struct se_dev_entry *deve; struct se_lun *se_lun = NULL; @@ -172,7 +172,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) if (!se_lun) { pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" - " Access for 0x%08x\n", + " Access for 0x%08llx\n", se_cmd->se_tfo->get_fabric_name(), unpacked_lun); return -ENODEV; @@ -260,7 +260,7 @@ void core_free_device_list_for_node( } void core_update_device_list_access( - u32 mapped_lun, + u64 mapped_lun, u32 lun_access, struct se_node_acl *nacl) { @@ -283,7 +283,7 @@ void core_update_device_list_access( /* * Called with rcu_read_lock or nacl->device_list_lock held. */ -struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *nacl, u32 mapped_lun) +struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *nacl, u64 mapped_lun) { struct se_dev_entry *deve; @@ -309,7 +309,7 @@ void target_pr_kref_release(struct kref *kref) int core_enable_device_list_for_node( struct se_lun *lun, struct se_lun_acl *lun_acl, - u32 mapped_lun, + u64 mapped_lun, u32 lun_access, struct se_node_acl *nacl, struct se_portal_group *tpg) @@ -550,7 +550,7 @@ int core_dev_add_lun( if (rc < 0) return rc; - pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" + pr_debug("%s_TPG[%u]_LUN[%llu] - Activated %s Logical Unit from" " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); @@ -583,7 +583,7 @@ void core_dev_del_lun( struct se_portal_group *tpg, struct se_lun *lun) { - pr_debug("%s_TPG[%u]_LUN[%u] - Deactivating %s Logical Unit from" + pr_debug("%s_TPG[%u]_LUN[%llu] - Deactivating %s Logical Unit from" " device object\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, tpg->se_tpg_tfo->get_fabric_name()); @@ -594,7 +594,7 @@ void core_dev_del_lun( struct se_lun_acl *core_dev_init_initiator_node_lun_acl( struct se_portal_group *tpg, struct se_node_acl *nacl, - u32 mapped_lun, + u64 mapped_lun, int *ret) { struct se_lun_acl *lacl; @@ -646,7 +646,7 @@ int core_dev_add_initiator_node_lun_acl( lun_access, nacl, tpg) < 0) return -EINVAL; - pr_debug("%s_TPG[%hu]_LUN[%u->%u] - Added %s ACL for " + pr_debug("%s_TPG[%hu]_LUN[%llu->%llu] - Added %s ACL for " " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", @@ -678,8 +678,8 @@ int core_dev_del_initiator_node_lun_acl( core_disable_device_list_for_node(lun, deve, nacl, tpg); mutex_unlock(&nacl->lun_entry_mutex); - pr_debug("%s_TPG[%hu]_LUN[%u] - Removed ACL for" - " InitiatorNode: %s Mapped LUN: %u\n", + pr_debug("%s_TPG[%hu]_LUN[%llu] - Removed ACL for" + " InitiatorNode: %s Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->initiatorname, lacl->mapped_lun); @@ -692,7 +692,7 @@ void core_dev_free_initiator_node_lun_acl( struct se_lun_acl *lacl) { pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" - " Mapped LUN: %u\n", tpg->se_tpg_tfo->get_fabric_name(), + " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), tpg->se_tpg_tfo->get_fabric_name(), lacl->initiatorname, lacl->mapped_lun); diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 0ee182fce1a6..2fd493e416b0 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -202,7 +202,7 @@ static ssize_t target_fabric_mappedlun_store_write_protect( lacl->se_lun_nacl); pr_debug("%s_ConfigFS: Changed Initiator ACL: %s" - " Mapped LUN: %u Write Protect bit to %s\n", + " Mapped LUN: %llu Write Protect bit to %s\n", se_tpg->se_tpg_tfo->get_fabric_name(), lacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF"); @@ -322,7 +322,7 @@ static struct config_group *target_fabric_make_mappedlun( struct config_item *acl_ci; struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL; char *buf; - unsigned long mapped_lun; + unsigned long long mapped_lun; int ret = 0; acl_ci = &group->cg_item; @@ -350,15 +350,11 @@ static struct config_group *target_fabric_make_mappedlun( * Determine the Mapped LUN value. This is what the SCSI Initiator * Port will actually see. */ - ret = kstrtoul(buf + 4, 0, &mapped_lun); + ret = kstrtoull(buf + 4, 0, &mapped_lun); if (ret) goto out; - if (mapped_lun > UINT_MAX) { - ret = -EINVAL; - goto out; - } if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { - pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG" + pr_err("Mapped LUN: %llu exceeds TRANSPORT_MAX_LUNS_PER_TPG" "-1: %u for Target Portal Group: %u\n", mapped_lun, TRANSPORT_MAX_LUNS_PER_TPG-1, se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); @@ -881,7 +877,7 @@ static struct config_group *target_fabric_make_lun( struct se_portal_group, tpg_lun_group); struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; struct config_group *lun_cg = NULL, *port_stat_grp = NULL; - unsigned long unpacked_lun; + unsigned long long unpacked_lun; int errno; if (strstr(name, "lun_") != name) { @@ -889,11 +885,9 @@ static struct config_group *target_fabric_make_lun( " \"lun_$LUN_NUMBER\"\n"); return ERR_PTR(-EINVAL); } - errno = kstrtoul(name + 4, 0, &unpacked_lun); + errno = kstrtoull(name + 4, 0, &unpacked_lun); if (errno) return ERR_PTR(errno); - if (unpacked_lun > UINT_MAX) - return ERR_PTR(-EINVAL); lun = core_tpg_alloc_lun(se_tpg, unpacked_lun); if (IS_ERR(lun)) diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 8d8737a13e6f..511178969df3 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -26,10 +26,10 @@ struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); void target_pr_kref_release(struct kref *); void core_free_device_list_for_node(struct se_node_acl *, struct se_portal_group *); -void core_update_device_list_access(u32, u32, struct se_node_acl *); -struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *, u32); +void core_update_device_list_access(u64, u32, struct se_node_acl *); +struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *, u64); int core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, - u32, u32, struct se_node_acl *, struct se_portal_group *); + u64, u32, struct se_node_acl *, struct se_portal_group *); void core_disable_device_list_for_node(struct se_lun *, struct se_dev_entry *, struct se_node_acl *, struct se_portal_group *); void core_clear_lun_from_tpg(struct se_lun *, struct se_portal_group *); @@ -37,7 +37,7 @@ int core_dev_add_lun(struct se_portal_group *, struct se_device *, struct se_lun *lun); void core_dev_del_lun(struct se_portal_group *, struct se_lun *); struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, - struct se_node_acl *, u32, int *); + struct se_node_acl *, u64, int *); int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, struct se_lun_acl *, struct se_lun *lun, u32); int core_dev_del_initiator_node_lun_acl(struct se_lun *, @@ -80,7 +80,7 @@ struct se_node_acl *__core_tpg_get_initiator_node_acl(struct se_portal_group *tp void core_tpg_add_node_to_devs(struct se_node_acl *, struct se_portal_group *, struct se_lun *); void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *); -struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, u32); +struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, u64); int core_tpg_add_lun(struct se_portal_group *, struct se_lun *, u32, struct se_device *); void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 94935eaa7fa7..436e30b14a11 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -229,8 +229,9 @@ target_scsi2_reservation_release(struct se_cmd *cmd) dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID; } tpg = sess->se_tpg; - pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" - " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), + pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->" + " MAPPED LUN: %llu for %s\n", + tpg->se_tpg_tfo->get_fabric_name(), cmd->se_lun->unpacked_lun, cmd->orig_fe_lun, sess->se_node_acl->initiatorname); @@ -275,10 +276,10 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) (dev->dev_reserved_node_acl != sess->se_node_acl)) { pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n", tpg->se_tpg_tfo->get_fabric_name()); - pr_err("Original reserver LUN: %u %s\n", + pr_err("Original reserver LUN: %llu %s\n", cmd->se_lun->unpacked_lun, dev->dev_reserved_node_acl->initiatorname); - pr_err("Current attempt - LUN: %u -> MAPPED LUN: %u" + pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu" " from %s \n", cmd->se_lun->unpacked_lun, cmd->orig_fe_lun, sess->se_node_acl->initiatorname); @@ -292,7 +293,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) dev->dev_res_bin_isid = sess->sess_bin_isid; dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID; } - pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u" + pr_debug("SCSI-2 Reserved %s LUN: %llu -> MAPPED LUN: %llu" " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), cmd->se_lun->unpacked_lun, cmd->orig_fe_lun, sess->se_node_acl->initiatorname); @@ -618,7 +619,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( struct se_node_acl *nacl, struct se_lun *lun, struct se_dev_entry *deve, - u32 mapped_lun, + u64 mapped_lun, unsigned char *isid, u64 sa_res_key, int all_tg_pt, @@ -671,7 +672,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( struct se_node_acl *nacl, struct se_lun *lun, struct se_dev_entry *deve, - u32 mapped_lun, + u64 mapped_lun, unsigned char *isid, u64 sa_res_key, int all_tg_pt, @@ -804,10 +805,10 @@ int core_scsi3_alloc_aptpl_registration( u64 sa_res_key, unsigned char *i_port, unsigned char *isid, - u32 mapped_lun, + u64 mapped_lun, unsigned char *t_port, u16 tpgt, - u32 target_lun, + u64 target_lun, int res_holder, int all_tg_pt, u8 type) @@ -901,9 +902,9 @@ static int __core_scsi3_check_aptpl_registration( struct se_device *dev, struct se_portal_group *tpg, struct se_lun *lun, - u32 target_lun, + u64 target_lun, struct se_node_acl *nacl, - u32 mapped_lun) + u64 mapped_lun) { struct t10_pr_registration *pr_reg, *pr_reg_tmp; struct t10_reservation *pr_tmpl = &dev->t10_pr; @@ -972,7 +973,7 @@ int core_scsi3_check_aptpl_registration( struct se_portal_group *tpg, struct se_lun *lun, struct se_node_acl *nacl, - u32 mapped_lun) + u64 mapped_lun) { if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) return 0; @@ -1094,7 +1095,7 @@ static int core_scsi3_alloc_registration( struct se_node_acl *nacl, struct se_lun *lun, struct se_dev_entry *deve, - u32 mapped_lun, + u64 mapped_lun, unsigned char *isid, u64 sa_res_key, int all_tg_pt, @@ -1668,7 +1669,7 @@ core_scsi3_decode_spec_i_port( } pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" - " dest_se_deve mapped_lun: %u\n", + " dest_se_deve mapped_lun: %llu\n", dest_tpg->se_tpg_tfo->get_fabric_name(), dest_node_acl->initiatorname, dest_se_deve->mapped_lun); @@ -1780,7 +1781,7 @@ core_scsi3_decode_spec_i_port( pr_debug("SPC-3 PR [%s] SPEC_I_PT: Successfully" " registered Transport ID for Node: %s%s Mapped LUN:" - " %u\n", dest_tpg->se_tpg_tfo->get_fabric_name(), + " %llu\n", dest_tpg->se_tpg_tfo->get_fabric_name(), dest_node_acl->initiatorname, i_buf, (dest_se_deve) ? dest_se_deve->mapped_lun : 0); @@ -1873,7 +1874,7 @@ static int core_scsi3_update_aptpl_buf( "sa_res_key=%llu\n" "res_holder=1\nres_type=%02x\n" "res_scope=%02x\nres_all_tg_pt=%d\n" - "mapped_lun=%u\n", reg_count, + "mapped_lun=%llu\n", reg_count, tpg->se_tpg_tfo->get_fabric_name(), pr_reg->pr_reg_nacl->initiatorname, isid_buf, pr_reg->pr_res_key, pr_reg->pr_res_type, @@ -1883,7 +1884,7 @@ static int core_scsi3_update_aptpl_buf( snprintf(tmp, 512, "PR_REG_START: %d\n" "initiator_fabric=%s\ninitiator_node=%s\n%s" "sa_res_key=%llu\nres_holder=0\n" - "res_all_tg_pt=%d\nmapped_lun=%u\n", + "res_all_tg_pt=%d\nmapped_lun=%llu\n", reg_count, tpg->se_tpg_tfo->get_fabric_name(), pr_reg->pr_reg_nacl->initiatorname, isid_buf, pr_reg->pr_res_key, pr_reg->pr_reg_all_tg_pt, @@ -1902,7 +1903,7 @@ static int core_scsi3_update_aptpl_buf( * Include information about the associated SCSI target port. */ snprintf(tmp, 512, "target_fabric=%s\ntarget_node=%s\n" - "tpgt=%hu\nport_rtpi=%hu\ntarget_lun=%u\nPR_REG_END:" + "tpgt=%hu\nport_rtpi=%hu\ntarget_lun=%llu\nPR_REG_END:" " %d\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_wwn(tpg), tpg->se_tpg_tfo->tpg_get_tag(tpg), @@ -2646,7 +2647,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) struct se_session *se_sess = cmd->se_sess; struct t10_reservation *pr_tmpl = &dev->t10_pr; struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; - u32 pr_res_mapped_lun = 0; + u64 pr_res_mapped_lun = 0; int calling_it_nexus = 0; /* * Locate the existing *pr_reg via struct se_node_acl pointers @@ -2802,7 +2803,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, LIST_HEAD(preempt_and_abort_list); struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder; struct t10_reservation *pr_tmpl = &dev->t10_pr; - u32 pr_res_mapped_lun = 0; + u64 pr_res_mapped_lun = 0; int all_reg = 0, calling_it_nexus = 0; bool sa_res_key_unmatched = sa_res_key != 0; int prh_type = 0, prh_scope = 0; @@ -3350,7 +3351,7 @@ after_iport_check: } pr_debug("SPC-3 PR REGISTER_AND_MOVE: Located %s node %s LUN" - " ACL for dest_se_deve->mapped_lun: %u\n", + " ACL for dest_se_deve->mapped_lun: %llu\n", dest_tf_ops->get_fabric_name(), dest_node_acl->initiatorname, dest_se_deve->mapped_lun); diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index 749fd7bb7510..e3d26e9126a0 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h @@ -56,11 +56,11 @@ extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); extern int core_scsi3_alloc_aptpl_registration( struct t10_reservation *, u64, - unsigned char *, unsigned char *, u32, - unsigned char *, u16, u32, int, int, u8); + unsigned char *, unsigned char *, u64, + unsigned char *, u16, u64, int, int, u8); extern int core_scsi3_check_aptpl_registration(struct se_device *, struct se_portal_group *, struct se_lun *, - struct se_node_acl *, u32); + struct se_node_acl *, u64); extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *, struct se_node_acl *); extern void core_scsi3_free_all_registrations(struct se_device *); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 2e77eebe1671..82ed8a0f3f0e 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -122,7 +122,7 @@ void core_tpg_add_node_to_devs( lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; } - pr_debug("TARGET_CORE[%s]->TPG[%u]_LUN[%u] - Adding %s" + pr_debug("TARGET_CORE[%s]->TPG[%u]_LUN[%llu] - Adding %s" " access for LUN in Demo Mode\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, @@ -598,12 +598,12 @@ EXPORT_SYMBOL(core_tpg_deregister); struct se_lun *core_tpg_alloc_lun( struct se_portal_group *tpg, - u32 unpacked_lun) + u64 unpacked_lun) { struct se_lun *lun; if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { - pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER_TPG" + pr_err("%s LUN: %llu exceeds TRANSPORT_MAX_LUNS_PER_TPG" "-1: %u for Target Portal Group: %u\n", tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, TRANSPORT_MAX_LUNS_PER_TPG-1, diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d8a59122fe3b..eed9580b7f6c 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1366,7 +1366,7 @@ transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl, * assumes internal allocation of fabric payload buffer by target-core. */ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess, - unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, + unsigned char *cdb, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags, struct scatterlist *sgl, u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count, @@ -1502,7 +1502,7 @@ EXPORT_SYMBOL(target_submit_cmd_map_sgls); * It also assumes interal target core SGL memory allocation. */ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, - unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, + unsigned char *cdb, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags) { return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense, @@ -1539,7 +1539,7 @@ static void target_complete_tmr_failure(struct work_struct *work) **/ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, - unsigned char *sense, u32 unpacked_lun, + unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t gfp, unsigned int tag, int flags) { diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index 6c9616d212b1..e53d4eec2ebc 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -88,7 +88,7 @@ target_scsi3_ua_check(struct se_cmd *cmd) int core_scsi3_ua_allocate( struct se_node_acl *nacl, - u32 unpacked_lun, + u64 unpacked_lun, u8 asc, u8 ascq) { @@ -177,7 +177,7 @@ int core_scsi3_ua_allocate( list_add_tail(&ua->ua_nacl_list, &deve->ua_list); spin_unlock(&deve->ua_lock); - pr_debug("[%s]: Allocated UNIT ATTENTION, mapped LUN: %u, ASC:" + pr_debug("[%s]: Allocated UNIT ATTENTION, mapped LUN: %llu, ASC:" " 0x%02x, ASCQ: 0x%02x\n", nacl->se_tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, asc, ascq); @@ -267,7 +267,7 @@ void core_scsi3_ua_for_check_condition( rcu_read_unlock(); pr_debug("[%s]: %s UNIT ATTENTION condition with" - " INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x" + " INTLCK_CTRL: %d, mapped LUN: %llu, got CDB: 0x%02x" " reported ASC: 0x%02x, ASCQ: 0x%02x\n", nacl->se_tpg->se_tpg_tfo->get_fabric_name(), (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" : @@ -329,7 +329,7 @@ int core_scsi3_ua_clear_for_request_sense( rcu_read_unlock(); pr_debug("[%s]: Released UNIT ATTENTION condition, mapped" - " LUN: %u, got REQUEST_SENSE reported ASC: 0x%02x," + " LUN: %llu, got REQUEST_SENSE reported ASC: 0x%02x," " ASCQ: 0x%02x\n", nacl->se_tpg->se_tpg_tfo->get_fabric_name(), cmd->orig_fe_lun, *asc, *ascq); diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index a6b56b364e7a..6e592b10a8c0 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h @@ -28,7 +28,7 @@ extern struct kmem_cache *se_ua_cache; extern sense_reason_t target_scsi3_ua_check(struct se_cmd *); -extern int core_scsi3_ua_allocate(struct se_node_acl *, u32, u8, u8); +extern int core_scsi3_ua_allocate(struct se_node_acl *, u64, u8, u8); extern void core_scsi3_ua_release_all(struct se_dev_entry *); extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); extern int core_scsi3_ua_clear_for_request_sense(struct se_cmd *, diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index eefc2b0cfaa3..836ff8abdf18 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -355,8 +355,8 @@ struct t10_pr_registration { int pr_res_scope; /* Used for fabric initiator WWPNs using a ISID */ bool isid_present_at_reg; - u32 pr_res_mapped_lun; - u32 pr_aptpl_target_lun; + u64 pr_res_mapped_lun; + u64 pr_aptpl_target_lun; u16 tg_pt_sep_rtpi; u32 pr_res_generation; u64 pr_reg_bin_isid; @@ -476,7 +476,7 @@ struct se_cmd { /* Total size in bytes associated with command */ u32 data_length; u32 residual_count; - u32 orig_fe_lun; + u64 orig_fe_lun; /* Persistent Reservation key */ u64 pr_res_key; /* Used for sense data */ @@ -614,7 +614,7 @@ struct se_ml_stat_grps { struct se_lun_acl { char initiatorname[TRANSPORT_IQN_LEN]; - u32 mapped_lun; + u64 mapped_lun; struct se_node_acl *se_lun_nacl; struct se_lun *se_lun; struct config_group se_lun_group; @@ -623,10 +623,10 @@ struct se_lun_acl { struct se_dev_entry { /* See transport_lunflags_table */ - u32 lun_flags; - u32 mapped_lun; + u64 mapped_lun; u64 pr_res_key; u64 creation_time; + u32 lun_flags; u32 attach_count; atomic_long_t total_cmds; atomic_long_t read_bytes; @@ -696,14 +696,15 @@ struct scsi_port_stats { }; struct se_lun { - /* RELATIVE TARGET PORT IDENTIFER */ - u16 lun_rtpi; + u64 unpacked_lun; #define SE_LUN_LINK_MAGIC 0xffff7771 u32 lun_link_magic; u32 lun_access; u32 lun_flags; - u32 unpacked_lun; u32 lun_index; + + /* RELATIVE TARGET PORT IDENTIFER */ + u16 lun_rtpi; atomic_t lun_acl_count; struct se_device __rcu *lun_se_dev; diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index d6216b761333..18afef91b447 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -116,16 +116,16 @@ void transport_deregister_session(struct se_session *); void transport_init_se_cmd(struct se_cmd *, const struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *); -sense_reason_t transport_lookup_cmd_lun(struct se_cmd *, u32); +sense_reason_t transport_lookup_cmd_lun(struct se_cmd *, u64); sense_reason_t target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, - unsigned char *, unsigned char *, u32, u32, int, int, int, + unsigned char *, unsigned char *, u64, u32, int, int, int, struct scatterlist *, u32, struct scatterlist *, u32, struct scatterlist *, u32); int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, - unsigned char *, u32, u32, int, int, int); + unsigned char *, u64, u32, int, int, int); int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, - unsigned char *sense, u32 unpacked_lun, + unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t, unsigned int, int); int transport_handle_cdb_direct(struct se_cmd *); @@ -151,7 +151,7 @@ void core_tmr_release_req(struct se_tmr_req *); int transport_generic_handle_tmr(struct se_cmd *); void transport_generic_request_failure(struct se_cmd *, sense_reason_t); void __target_execute_cmd(struct se_cmd *); -int transport_lookup_tmr_lun(struct se_cmd *, u32); +int transport_lookup_tmr_lun(struct se_cmd *, u64); struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg, unsigned char *); -- cgit v1.2.3 From 316058134ffa0017199b460318e109aa79432cc6 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 11 Jun 2015 10:01:25 +0200 Subject: target: Remove 'ua_nacl' pointer from se_ua structure Unused. Signed-off-by: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_ua.c | 1 - include/target/target_core_base.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/target/target_core_ua.c') diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index e53d4eec2ebc..e5062245171e 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -107,7 +107,6 @@ int core_scsi3_ua_allocate( } INIT_LIST_HEAD(&ua->ua_nacl_list); - ua->ua_nacl = nacl; ua->ua_asc = asc; ua->ua_ascq = ascq; diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 8cb612613c10..8a4f861f12b7 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -548,7 +548,6 @@ struct se_cmd { struct se_ua { u8 ua_asc; u8 ua_ascq; - struct se_node_acl *ua_nacl; struct list_head ua_nacl_list; }; -- cgit v1.2.3 From c51c8e7bcac966f209da83630fc8ca7e6cad279b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 11 Jun 2015 10:01:26 +0200 Subject: target: use 'se_dev_entry' when allocating UAs We need to use 'se_dev_entry' as argument when allocating UAs, otherwise we'll never see any UAs for an implicit ALUA state transition triggered from userspace. (Add target_ua_allocate_lun() common caller - nab) Signed-off-by: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_alua.c | 27 ++++++++++++++-------- drivers/target/target_core_pr.c | 12 +++++----- drivers/target/target_core_transport.c | 12 +++++----- drivers/target/target_core_ua.c | 42 ++++++++++++++++++---------------- drivers/target/target_core_ua.h | 3 ++- 5 files changed, 54 insertions(+), 42 deletions(-) (limited to 'drivers/target/target_core_ua.c') diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 228a3c7925e5..aa2e4b103d43 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -972,23 +972,32 @@ static void core_alua_queue_state_change_ua(struct t10_alua_tg_pt_gp *tg_pt_gp) list_for_each_entry(se_deve, &lun->lun_deve_list, lun_link) { lacl = rcu_dereference_check(se_deve->se_lun_acl, lockdep_is_held(&lun->lun_deve_lock)); + /* - * se_deve->se_lun_acl pointer may be NULL for a - * entry created without explicit Node+MappedLUN ACLs + * spc4r37 p.242: + * After an explicit target port asymmetric access + * state change, a device server shall establish a + * unit attention condition with the additional sense + * code set to ASYMMETRIC ACCESS STATE CHANGED for + * the initiator port associated with every I_T nexus + * other than the I_T nexus on which the SET TARGET + * PORT GROUPS command was received. */ - if (!lacl) - continue; - if ((tg_pt_gp->tg_pt_gp_alua_access_status == ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG) && - (tg_pt_gp->tg_pt_gp_alua_nacl != NULL) && - (tg_pt_gp->tg_pt_gp_alua_nacl == lacl->se_lun_nacl) && (tg_pt_gp->tg_pt_gp_alua_lun != NULL) && (tg_pt_gp->tg_pt_gp_alua_lun == lun)) continue; - core_scsi3_ua_allocate(lacl->se_lun_nacl, - se_deve->mapped_lun, 0x2A, + /* + * se_deve->se_lun_acl pointer may be NULL for a + * entry created without explicit Node+MappedLUN ACLs + */ + if (lacl && (tg_pt_gp->tg_pt_gp_alua_nacl != NULL) && + (tg_pt_gp->tg_pt_gp_alua_nacl == lacl->se_lun_nacl)) + continue; + + core_scsi3_ua_allocate(se_deve, 0x2A, ASCQ_2AH_ASYMMETRIC_ACCESS_STATE_CHANGED); } spin_unlock_bh(&lun->lun_deve_lock); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 436e30b14a11..0bb329243dba 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -2197,7 +2197,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, &pr_tmpl->registration_list, pr_reg_list) { - core_scsi3_ua_allocate( + target_ua_allocate_lun( pr_reg_p->pr_reg_nacl, pr_reg_p->pr_res_mapped_lun, 0x2A, @@ -2624,7 +2624,7 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, if (pr_reg_p == pr_reg) continue; - core_scsi3_ua_allocate(pr_reg_p->pr_reg_nacl, + target_ua_allocate_lun(pr_reg_p->pr_reg_nacl, pr_reg_p->pr_res_mapped_lun, 0x2A, ASCQ_2AH_RESERVATIONS_RELEASED); } @@ -2709,7 +2709,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) * additional sense code set to RESERVATIONS PREEMPTED. */ if (!calling_it_nexus) - core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, + target_ua_allocate_lun(pr_reg_nacl, pr_res_mapped_lun, 0x2A, ASCQ_2AH_RESERVATIONS_PREEMPTED); } spin_unlock(&pr_tmpl->registration_lock); @@ -2918,7 +2918,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, NULL, 0); } if (!calling_it_nexus) - core_scsi3_ua_allocate(pr_reg_nacl, + target_ua_allocate_lun(pr_reg_nacl, pr_res_mapped_lun, 0x2A, ASCQ_2AH_REGISTRATIONS_PREEMPTED); } @@ -3024,7 +3024,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, * persistent reservation and/or registration, with the * additional sense code set to REGISTRATIONS PREEMPTED; */ - core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A, + target_ua_allocate_lun(pr_reg_nacl, pr_res_mapped_lun, 0x2A, ASCQ_2AH_REGISTRATIONS_PREEMPTED); } spin_unlock(&pr_tmpl->registration_lock); @@ -3057,7 +3057,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, if (calling_it_nexus) continue; - core_scsi3_ua_allocate(pr_reg->pr_reg_nacl, + target_ua_allocate_lun(pr_reg->pr_reg_nacl, pr_reg->pr_res_mapped_lun, 0x2A, ASCQ_2AH_RESERVATIONS_RELEASED); } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index eed9580b7f6c..0364534f8d46 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1677,13 +1677,13 @@ void transport_generic_request_failure(struct se_cmd *cmd, * See spc4r17, section 7.4.6 Control Mode Page, Table 349 */ if (cmd->se_sess && - cmd->se_dev->dev_attrib.emulate_ua_intlck_ctrl == 2) - core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, - cmd->orig_fe_lun, 0x2C, - ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); - + cmd->se_dev->dev_attrib.emulate_ua_intlck_ctrl == 2) { + target_ua_allocate_lun(cmd->se_sess->se_node_acl, + cmd->orig_fe_lun, 0x2C, + ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); + } trace_target_cmd_complete(cmd); - ret = cmd->se_tfo-> queue_status(cmd); + ret = cmd->se_tfo->queue_status(cmd); if (ret == -EAGAIN || ret == -ENOMEM) goto queue_full; goto check_stop; diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index e5062245171e..fc095aed5a88 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -87,18 +87,11 @@ target_scsi3_ua_check(struct se_cmd *cmd) } int core_scsi3_ua_allocate( - struct se_node_acl *nacl, - u64 unpacked_lun, + struct se_dev_entry *deve, u8 asc, u8 ascq) { - struct se_dev_entry *deve; struct se_ua *ua, *ua_p, *ua_tmp; - /* - * PASSTHROUGH OPS - */ - if (!nacl) - return -EINVAL; ua = kmem_cache_zalloc(se_ua_cache, GFP_ATOMIC); if (!ua) { @@ -110,12 +103,6 @@ int core_scsi3_ua_allocate( ua->ua_asc = asc; ua->ua_ascq = ascq; - rcu_read_lock(); - deve = target_nacl_find_deve(nacl, unpacked_lun); - if (!deve) { - rcu_read_unlock(); - return -EINVAL; - } spin_lock(&deve->ua_lock); list_for_each_entry_safe(ua_p, ua_tmp, &deve->ua_list, ua_nacl_list) { /* @@ -123,7 +110,6 @@ int core_scsi3_ua_allocate( */ if ((ua_p->ua_asc == asc) && (ua_p->ua_ascq == ascq)) { spin_unlock(&deve->ua_lock); - rcu_read_unlock(); kmem_cache_free(se_ua_cache, ua); return 0; } @@ -170,22 +156,38 @@ int core_scsi3_ua_allocate( spin_unlock(&deve->ua_lock); atomic_inc_mb(&deve->ua_count); - rcu_read_unlock(); return 0; } list_add_tail(&ua->ua_nacl_list, &deve->ua_list); spin_unlock(&deve->ua_lock); - pr_debug("[%s]: Allocated UNIT ATTENTION, mapped LUN: %llu, ASC:" - " 0x%02x, ASCQ: 0x%02x\n", - nacl->se_tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, + pr_debug("Allocated UNIT ATTENTION, mapped LUN: %llu, ASC:" + " 0x%02x, ASCQ: 0x%02x\n", deve->mapped_lun, asc, ascq); atomic_inc_mb(&deve->ua_count); - rcu_read_unlock(); return 0; } +void target_ua_allocate_lun(struct se_node_acl *nacl, + u32 unpacked_lun, u8 asc, u8 ascq) +{ + struct se_dev_entry *deve; + + if (!nacl) + return; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, unpacked_lun); + if (!deve) { + rcu_read_unlock(); + return; + } + + core_scsi3_ua_allocate(deve, asc, ascq); + rcu_read_unlock(); +} + void core_scsi3_ua_release_all( struct se_dev_entry *deve) { diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index 6e592b10a8c0..96460bff490f 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h @@ -28,7 +28,8 @@ extern struct kmem_cache *se_ua_cache; extern sense_reason_t target_scsi3_ua_check(struct se_cmd *); -extern int core_scsi3_ua_allocate(struct se_node_acl *, u64, u8, u8); +extern int core_scsi3_ua_allocate(struct se_dev_entry *, u8, u8); +extern void target_ua_allocate_lun(struct se_node_acl *, u32, u8, u8); extern void core_scsi3_ua_release_all(struct se_dev_entry *); extern void core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *); extern int core_scsi3_ua_clear_for_request_sense(struct se_cmd *, -- cgit v1.2.3