]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/target/target_core_transport.c
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[karo-tx-linux.git] / drivers / target / target_core_transport.c
index cd3bfc16d25f6eeaf79f757ebf7031e7cbee8ca2..ce8574b7220ced193e969e46141c411156e7e9a7 100644 (file)
@@ -43,7 +43,6 @@
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
 #include <target/target_core_fabric.h>
-#include <target/target_core_configfs.h>
 
 #include "target_core_internal.h"
 #include "target_core_alua.h"
@@ -60,7 +59,6 @@ struct kmem_cache *t10_pr_reg_cache;
 struct kmem_cache *t10_alua_lu_gp_cache;
 struct kmem_cache *t10_alua_lu_gp_mem_cache;
 struct kmem_cache *t10_alua_tg_pt_gp_cache;
-struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
 struct kmem_cache *t10_alua_lba_map_cache;
 struct kmem_cache *t10_alua_lba_map_mem_cache;
 
@@ -119,16 +117,6 @@ int init_se_kmem_caches(void)
                                "cache failed\n");
                goto out_free_lu_gp_mem_cache;
        }
-       t10_alua_tg_pt_gp_mem_cache = kmem_cache_create(
-                       "t10_alua_tg_pt_gp_mem_cache",
-                       sizeof(struct t10_alua_tg_pt_gp_member),
-                       __alignof__(struct t10_alua_tg_pt_gp_member),
-                       0, NULL);
-       if (!t10_alua_tg_pt_gp_mem_cache) {
-               pr_err("kmem_cache_create() for t10_alua_tg_pt_gp_"
-                               "mem_t failed\n");
-               goto out_free_tg_pt_gp_cache;
-       }
        t10_alua_lba_map_cache = kmem_cache_create(
                        "t10_alua_lba_map_cache",
                        sizeof(struct t10_alua_lba_map),
@@ -136,7 +124,7 @@ int init_se_kmem_caches(void)
        if (!t10_alua_lba_map_cache) {
                pr_err("kmem_cache_create() for t10_alua_lba_map_"
                                "cache failed\n");
-               goto out_free_tg_pt_gp_mem_cache;
+               goto out_free_tg_pt_gp_cache;
        }
        t10_alua_lba_map_mem_cache = kmem_cache_create(
                        "t10_alua_lba_map_mem_cache",
@@ -159,8 +147,6 @@ out_free_lba_map_mem_cache:
        kmem_cache_destroy(t10_alua_lba_map_mem_cache);
 out_free_lba_map_cache:
        kmem_cache_destroy(t10_alua_lba_map_cache);
-out_free_tg_pt_gp_mem_cache:
-       kmem_cache_destroy(t10_alua_tg_pt_gp_mem_cache);
 out_free_tg_pt_gp_cache:
        kmem_cache_destroy(t10_alua_tg_pt_gp_cache);
 out_free_lu_gp_mem_cache:
@@ -186,7 +172,6 @@ void release_se_kmem_caches(void)
        kmem_cache_destroy(t10_alua_lu_gp_cache);
        kmem_cache_destroy(t10_alua_lu_gp_mem_cache);
        kmem_cache_destroy(t10_alua_tg_pt_gp_cache);
-       kmem_cache_destroy(t10_alua_tg_pt_gp_mem_cache);
        kmem_cache_destroy(t10_alua_lba_map_cache);
        kmem_cache_destroy(t10_alua_lba_map_mem_cache);
 }
@@ -406,12 +391,6 @@ EXPORT_SYMBOL(target_get_session);
 
 void target_put_session(struct se_session *se_sess)
 {
-       struct se_portal_group *tpg = se_sess->se_tpg;
-
-       if (tpg->se_tpg_tfo->put_session != NULL) {
-               tpg->se_tpg_tfo->put_session(se_sess);
-               return;
-       }
        kref_put(&se_sess->sess_kref, target_release_session);
 }
 EXPORT_SYMBOL(target_put_session);
@@ -498,7 +477,7 @@ void transport_deregister_session(struct se_session *se_sess)
        const struct target_core_fabric_ops *se_tfo;
        struct se_node_acl *se_nacl;
        unsigned long flags;
-       bool comp_nacl = true;
+       bool comp_nacl = true, drop_nacl = false;
 
        if (!se_tpg) {
                transport_free_session(se_sess);
@@ -518,22 +497,22 @@ void transport_deregister_session(struct se_session *se_sess)
         */
        se_nacl = se_sess->se_node_acl;
 
-       spin_lock_irqsave(&se_tpg->acl_node_lock, flags);
+       mutex_lock(&se_tpg->acl_node_mutex);
        if (se_nacl && se_nacl->dynamic_node_acl) {
                if (!se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
                        list_del(&se_nacl->acl_list);
                        se_tpg->num_node_acls--;
-                       spin_unlock_irqrestore(&se_tpg->acl_node_lock, flags);
-                       core_tpg_wait_for_nacl_pr_ref(se_nacl);
-                       core_free_device_list_for_node(se_nacl, se_tpg);
-                       se_tfo->tpg_release_fabric_acl(se_tpg, se_nacl);
-
-                       comp_nacl = false;
-                       spin_lock_irqsave(&se_tpg->acl_node_lock, flags);
+                       drop_nacl = true;
                }
        }
-       spin_unlock_irqrestore(&se_tpg->acl_node_lock, flags);
+       mutex_unlock(&se_tpg->acl_node_mutex);
 
+       if (drop_nacl) {
+               core_tpg_wait_for_nacl_pr_ref(se_nacl);
+               core_free_device_list_for_node(se_nacl, se_tpg);
+               kfree(se_nacl);
+               comp_nacl = false;
+       }
        pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
                se_tpg->se_tpg_tfo->get_fabric_name());
        /*
@@ -593,9 +572,8 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists,
         * this command for frontend exceptions.
         */
        if (cmd->transport_state & CMD_T_STOP) {
-               pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n",
-                       __func__, __LINE__,
-                       cmd->se_tfo->get_task_tag(cmd));
+               pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08llx\n",
+                       __func__, __LINE__, cmd->tag);
 
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
@@ -1148,6 +1126,8 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
 /*
  * Used by fabric modules containing a local struct se_cmd within their
  * fabric dependent per I/O descriptor.
+ *
+ * Preserves the value of @cmd->tag.
  */
 void transport_init_se_cmd(
        struct se_cmd *cmd,
@@ -1274,11 +1254,7 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
                return ret;
 
        cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE;
-
-       spin_lock(&cmd->se_lun->lun_sep_lock);
-       if (cmd->se_lun->lun_sep)
-               cmd->se_lun->lun_sep->sep_stats.cmd_pdus++;
-       spin_unlock(&cmd->se_lun->lun_sep_lock);
+       atomic_long_inc(&cmd->se_lun->lun_stats.cmd_pdus);
        return 0;
 }
 EXPORT_SYMBOL(target_setup_cmd_from_cdb);
@@ -1346,11 +1322,9 @@ transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
 
        cmd->t_data_sg = sgl;
        cmd->t_data_nents = sgl_count;
+       cmd->t_bidi_data_sg = sgl_bidi;
+       cmd->t_bidi_data_nents = sgl_bidi_count;
 
-       if (sgl_bidi && sgl_bidi_count) {
-               cmd->t_bidi_data_sg = sgl_bidi;
-               cmd->t_bidi_data_nents = sgl_bidi_count;
-       }
        cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC;
        return 0;
 }
@@ -1375,6 +1349,8 @@ transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
  * @sgl_prot: struct scatterlist memory protection information
  * @sgl_prot_count: scatterlist count for protection information
  *
+ * Task tags are supported if the caller has set @se_cmd->tag.
+ *
  * Returns non zero to signal active I/O shutdown failure.  All other
  * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
  * but still return zero here.
@@ -1383,7 +1359,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,
@@ -1412,7 +1388,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
         * for fabrics using TARGET_SCF_ACK_KREF that expect a second
         * kref_put() to happen during fabric packet acknowledgement.
         */
-       ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
+       ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
        if (ret)
                return ret;
        /*
@@ -1426,7 +1402,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
        rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun);
        if (rc) {
                transport_send_check_condition_and_sense(se_cmd, rc, 0);
-               target_put_sess_cmd(se_sess, se_cmd);
+               target_put_sess_cmd(se_cmd);
                return 0;
        }
 
@@ -1443,6 +1419,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
        if (sgl_prot_count) {
                se_cmd->t_prot_sg = sgl_prot;
                se_cmd->t_prot_nents = sgl_prot_count;
+               se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC;
        }
 
        /*
@@ -1506,6 +1483,8 @@ EXPORT_SYMBOL(target_submit_cmd_map_sgls);
  * @data_dir: DMA data direction
  * @flags: flags for command submission from target_sc_flags_tables
  *
+ * Task tags are supported if the caller has set @se_cmd->tag.
+ *
  * Returns non zero to signal active I/O shutdown failure.  All other
  * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
  * but still return zero here.
@@ -1516,7 +1495,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,
@@ -1553,7 +1532,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)
 {
@@ -1577,7 +1556,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
                se_cmd->se_tmr_req->ref_task_tag = tag;
 
        /* See target_submit_cmd for commentary */
-       ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
+       ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
        if (ret) {
                core_tmr_release_req(se_cmd->se_tmr_req);
                return ret;
@@ -1633,9 +1612,8 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 {
        int ret = 0;
 
-       pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x"
-               " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd),
-               cmd->t_task_cdb[0]);
+       pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08llx"
+               " CDB: 0x%02x\n", cmd, cmd->tag, cmd->t_task_cdb[0]);
        pr_debug("-----[ i_state: %d t_state: %d sense_reason: %d\n",
                cmd->se_tfo->get_cmd_state(cmd),
                cmd->t_state, sense_reason);
@@ -1692,13 +1670,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;
@@ -1759,8 +1737,8 @@ static int target_write_prot_action(struct se_cmd *cmd)
                        break;
 
                sectors = cmd->data_length >> ilog2(cmd->se_dev->dev_attrib.block_size);
-               cmd->pi_err = sbc_dif_verify_write(cmd, cmd->t_task_lba,
-                                                  sectors, 0, NULL, 0);
+               cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba,
+                                            sectors, 0, cmd->t_prot_sg, 0);
                if (unlikely(cmd->pi_err)) {
                        spin_lock_irq(&cmd->t_state_lock);
                        cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
@@ -1843,9 +1821,8 @@ void target_execute_cmd(struct se_cmd *cmd)
         */
        spin_lock_irq(&cmd->t_state_lock);
        if (cmd->transport_state & CMD_T_STOP) {
-               pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n",
-                       __func__, __LINE__,
-                       cmd->se_tfo->get_task_tag(cmd));
+               pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08llx\n",
+                       __func__, __LINE__, cmd->tag);
 
                spin_unlock_irq(&cmd->t_state_lock);
                complete_all(&cmd->t_transport_stop_comp);
@@ -1984,16 +1961,17 @@ static void transport_handle_queue_full(
 
 static bool target_read_prot_action(struct se_cmd *cmd)
 {
-       sense_reason_t rc;
-
        switch (cmd->prot_op) {
        case TARGET_PROT_DIN_STRIP:
                if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
-                       rc = sbc_dif_read_strip(cmd);
-                       if (rc) {
-                               cmd->pi_err = rc;
+                       u32 sectors = cmd->data_length >>
+                                 ilog2(cmd->se_dev->dev_attrib.block_size);
+
+                       cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba,
+                                                    sectors, 0, cmd->t_prot_sg,
+                                                    0);
+                       if (cmd->pi_err)
                                return true;
-                       }
                }
                break;
        case TARGET_PROT_DIN_INSERT:
@@ -2072,12 +2050,8 @@ static void target_complete_ok_work(struct work_struct *work)
 queue_rsp:
        switch (cmd->data_direction) {
        case DMA_FROM_DEVICE:
-               spin_lock(&cmd->se_lun->lun_sep_lock);
-               if (cmd->se_lun->lun_sep) {
-                       cmd->se_lun->lun_sep->sep_stats.tx_data_octets +=
-                                       cmd->data_length;
-               }
-               spin_unlock(&cmd->se_lun->lun_sep_lock);
+               atomic_long_add(cmd->data_length,
+                               &cmd->se_lun->lun_stats.tx_data_octets);
                /*
                 * Perform READ_STRIP of PI using software emulation when
                 * backend had PI enabled, if the transport will not be
@@ -2100,22 +2074,14 @@ queue_rsp:
                        goto queue_full;
                break;
        case DMA_TO_DEVICE:
-               spin_lock(&cmd->se_lun->lun_sep_lock);
-               if (cmd->se_lun->lun_sep) {
-                       cmd->se_lun->lun_sep->sep_stats.rx_data_octets +=
-                               cmd->data_length;
-               }
-               spin_unlock(&cmd->se_lun->lun_sep_lock);
+               atomic_long_add(cmd->data_length,
+                               &cmd->se_lun->lun_stats.rx_data_octets);
                /*
                 * Check if we need to send READ payload for BIDI-COMMAND
                 */
                if (cmd->se_cmd_flags & SCF_BIDI) {
-                       spin_lock(&cmd->se_lun->lun_sep_lock);
-                       if (cmd->se_lun->lun_sep) {
-                               cmd->se_lun->lun_sep->sep_stats.tx_data_octets +=
-                                       cmd->data_length;
-                       }
-                       spin_unlock(&cmd->se_lun->lun_sep_lock);
+                       atomic_long_add(cmd->data_length,
+                                       &cmd->se_lun->lun_stats.tx_data_octets);
                        ret = cmd->se_tfo->queue_data_in(cmd);
                        if (ret == -EAGAIN || ret == -ENOMEM)
                                goto queue_full;
@@ -2172,6 +2138,12 @@ static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
 
 static inline void transport_free_pages(struct se_cmd *cmd)
 {
+       if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) {
+               transport_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents);
+               cmd->t_prot_sg = NULL;
+               cmd->t_prot_nents = 0;
+       }
+
        if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
                /*
                 * Release special case READ buffer payload required for
@@ -2195,10 +2167,6 @@ static inline void transport_free_pages(struct se_cmd *cmd)
        transport_free_sgl(cmd->t_bidi_data_sg, cmd->t_bidi_data_nents);
        cmd->t_bidi_data_sg = NULL;
        cmd->t_bidi_data_nents = 0;
-
-       transport_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents);
-       cmd->t_prot_sg = NULL;
-       cmd->t_prot_nents = 0;
 }
 
 /**
@@ -2220,7 +2188,7 @@ static int transport_release_cmd(struct se_cmd *cmd)
         * If this cmd has been setup with target_get_sess_cmd(), drop
         * the kref and call ->release_cmd() in kref callback.
         */
-       return target_put_sess_cmd(cmd->se_sess, cmd);
+       return target_put_sess_cmd(cmd);
 }
 
 /**
@@ -2337,6 +2305,14 @@ transport_generic_new_cmd(struct se_cmd *cmd)
        int ret = 0;
        bool zero_flag = !(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB);
 
+       if (cmd->prot_op != TARGET_PROT_NORMAL &&
+           !(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) {
+               ret = target_alloc_sgl(&cmd->t_prot_sg, &cmd->t_prot_nents,
+                                      cmd->prot_length, true);
+               if (ret < 0)
+                       return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       }
+
        /*
         * Determine is the TCM fabric module has already allocated physical
         * memory, and is directly calling transport_generic_map_mem_to_cmd()
@@ -2362,14 +2338,6 @@ transport_generic_new_cmd(struct se_cmd *cmd)
                                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                }
 
-               if (cmd->prot_op != TARGET_PROT_NORMAL) {
-                       ret = target_alloc_sgl(&cmd->t_prot_sg,
-                                              &cmd->t_prot_nents,
-                                              cmd->prot_length, true);
-                       if (ret < 0)
-                               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               }
-
                ret = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents,
                                       cmd->data_length, zero_flag);
                if (ret < 0)
@@ -2464,13 +2432,12 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 EXPORT_SYMBOL(transport_generic_free_cmd);
 
 /* target_get_sess_cmd - Add command to active ->sess_cmd_list
- * @se_sess:   session to reference
  * @se_cmd:    command descriptor to add
  * @ack_kref:  Signal that fabric will perform an ack target_put_sess_cmd()
  */
-int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
-                              bool ack_kref)
+int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
 {
+       struct se_session *se_sess = se_cmd->se_sess;
        unsigned long flags;
        int ret = 0;
 
@@ -2492,7 +2459,7 @@ out:
        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
        if (ret && ack_kref)
-               target_put_sess_cmd(se_sess, se_cmd);
+               target_put_sess_cmd(se_cmd);
 
        return ret;
 }
@@ -2521,11 +2488,12 @@ static void target_release_cmd_kref(struct kref *kref)
 }
 
 /* target_put_sess_cmd - Check for active I/O shutdown via kref_put
- * @se_sess:   session to reference
  * @se_cmd:    command descriptor to drop
  */
-int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
+int target_put_sess_cmd(struct se_cmd *se_cmd)
 {
+       struct se_session *se_sess = se_cmd->se_sess;
+
        if (!se_sess) {
                se_cmd->se_tfo->release_cmd(se_cmd);
                return 1;
@@ -2591,31 +2559,10 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
 }
 EXPORT_SYMBOL(target_wait_for_sess_cmds);
 
-static int transport_clear_lun_ref_thread(void *p)
+void transport_clear_lun_ref(struct se_lun *lun)
 {
-       struct se_lun *lun = p;
-
        percpu_ref_kill(&lun->lun_ref);
-
        wait_for_completion(&lun->lun_ref_comp);
-       complete(&lun->lun_shutdown_comp);
-
-       return 0;
-}
-
-int transport_clear_lun_ref(struct se_lun *lun)
-{
-       struct task_struct *kt;
-
-       kt = kthread_run(transport_clear_lun_ref_thread, lun,
-                       "tcm_cl_%u", lun->unpacked_lun);
-       if (IS_ERR(kt)) {
-               pr_err("Unable to start clear_lun thread\n");
-               return PTR_ERR(kt);
-       }
-       wait_for_completion(&lun->lun_shutdown_comp);
-
-       return 0;
 }
 
 /**
@@ -2649,10 +2596,8 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 
        cmd->transport_state |= CMD_T_STOP;
 
-       pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08x"
-               " i_state: %d, t_state: %d, CMD_T_STOP\n",
-               cmd, cmd->se_tfo->get_task_tag(cmd),
-               cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
+       pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08llx i_state: %d, t_state: %d, CMD_T_STOP\n",
+               cmd, cmd->tag, cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
 
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
@@ -2661,9 +2606,8 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
 
-       pr_debug("wait_for_tasks: Stopped wait_for_completion("
-               "&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
-               cmd->se_tfo->get_task_tag(cmd));
+       pr_debug("wait_for_tasks: Stopped wait_for_completion(&cmd->t_transport_stop_comp) for ITT: 0x%08llx\n",
+               cmd->tag);
 
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
@@ -2965,8 +2909,8 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
        if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS))
                return 1;
 
-       pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08x\n",
-                cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd));
+       pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08llx\n",
+                cmd->t_task_cdb[0], cmd->tag);
 
        cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS;
        cmd->scsi_status = SAM_STAT_TASK_ABORTED;
@@ -3005,9 +2949,8 @@ void transport_send_task_abort(struct se_cmd *cmd)
 
        transport_lun_remove_cmd(cmd);
 
-       pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x,"
-               " ITT: 0x%08x\n", cmd->t_task_cdb[0],
-               cmd->se_tfo->get_task_tag(cmd));
+       pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x, ITT: 0x%08llx\n",
+                cmd->t_task_cdb[0], cmd->tag);
 
        trace_target_cmd_complete(cmd);
        cmd->se_tfo->queue_status(cmd);
@@ -3033,6 +2976,11 @@ static void target_tmr_work(struct work_struct *work)
                ret = core_tmr_lun_reset(dev, tmr, NULL, NULL);
                tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE :
                                         TMR_FUNCTION_REJECTED;
+               if (tmr->response == TMR_FUNCTION_COMPLETE) {
+                       target_ua_allocate_lun(cmd->se_sess->se_node_acl,
+                                              cmd->orig_fe_lun, 0x29,
+                                              ASCQ_29H_BUS_DEVICE_RESET_FUNCTION_OCCURRED);
+               }
                break;
        case TMR_TARGET_WARM_RESET:
                tmr->response = TMR_FUNCTION_REJECTED;
@@ -3067,3 +3015,22 @@ int transport_generic_handle_tmr(
        return 0;
 }
 EXPORT_SYMBOL(transport_generic_handle_tmr);
+
+bool
+target_check_wce(struct se_device *dev)
+{
+       bool wce = false;
+
+       if (dev->transport->get_write_cache)
+               wce = dev->transport->get_write_cache(dev);
+       else if (dev->dev_attrib.emulate_write_cache > 0)
+               wce = true;
+
+       return wce;
+}
+
+bool
+target_check_fua(struct se_device *dev)
+{
+       return target_check_wce(dev) && dev->dev_attrib.emulate_fua_write > 0;
+}