These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / target / target_core_ua.c
index 1738b16..be25eb8 100644 (file)
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_proto.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_configfs.h>
 
 #include "target_core_internal.h"
 #include "target_core_alua.h"
@@ -51,9 +49,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:
         *
@@ -80,18 +86,11 @@ target_scsi3_ua_check(struct se_cmd *cmd)
 }
 
 int core_scsi3_ua_allocate(
-       struct se_node_acl *nacl,
-       u32 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) {
@@ -100,13 +99,9 @@ int core_scsi3_ua_allocate(
        }
        INIT_LIST_HEAD(&ua->ua_nacl_list);
 
-       ua->ua_nacl = nacl;
        ua->ua_asc = asc;
        ua->ua_ascq = ascq;
 
-       spin_lock_irq(&nacl->device_list_lock);
-       deve = nacl->device_list[unpacked_lun];
-
        spin_lock(&deve->ua_lock);
        list_for_each_entry_safe(ua_p, ua_tmp, &deve->ua_list, ua_nacl_list) {
                /*
@@ -114,7 +109,6 @@ 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);
                        kmem_cache_free(se_ua_cache, ua);
                        return 0;
                }
@@ -159,24 +153,40 @@ 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);
                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",
-               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);
        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)
 {
@@ -211,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;
        }
        /*
@@ -250,10 +264,10 @@ 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"
+               " 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" :
@@ -279,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;
        }
        /*
@@ -308,10 +326,10 @@ 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,"
+               " 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);