]> Pileus Git - ~andy/linux/commitdiff
target: merge transport_generic_write_pending into transport_generic_new_cmd
authorChristoph Hellwig <hch@infradead.org>
Sun, 8 Jul 2012 19:58:41 +0000 (15:58 -0400)
committerNicholas Bellinger <nab@linux-iscsi.org>
Tue, 17 Jul 2012 00:35:17 +0000 (17:35 -0700)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_transport.c

index dd9c87f62d7655b2bc7e8a8326b3dd5f353b1246..db139133f7082fcabad2a42667ff7f5de8e1c70f 100644 (file)
@@ -66,7 +66,6 @@ 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;
 
-static int transport_generic_write_pending(struct se_cmd *);
 static int transport_processing_thread(void *param);
 static void transport_complete_task_attr(struct se_cmd *cmd);
 static void transport_handle_queue_full(struct se_cmd *cmd,
@@ -2487,23 +2486,39 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
        atomic_inc(&cmd->t_fe_count);
 
        /*
-        * For WRITEs, let the fabric know its buffer is ready.
-        *
-        * The command will be added to the execution queue after its write
-        * data has arrived.
-        *
-        * Everything else but a WRITE, add the command to the execution queue.
+        * If this command is not a write we can execute it right here,
+        * for write buffers we need to notify the fabric driver first
+        * and let it call back once the write buffers are ready.
         */
        target_add_to_state_list(cmd);
-       if (cmd->data_direction == DMA_TO_DEVICE)
-               return transport_generic_write_pending(cmd);
-       target_execute_cmd(cmd);
-       return 0;
+       if (cmd->data_direction != DMA_TO_DEVICE) {
+               target_execute_cmd(cmd);
+               return 0;
+       }
+
+       spin_lock_irq(&cmd->t_state_lock);
+       cmd->t_state = TRANSPORT_WRITE_PENDING;
+       spin_unlock_irq(&cmd->t_state_lock);
+
+       transport_cmd_check_stop(cmd, false);
+
+       ret = cmd->se_tfo->write_pending(cmd);
+       if (ret == -EAGAIN || ret == -ENOMEM)
+               goto queue_full;
+
+       if (ret < 0)
+               return ret;
+       return 1;
 
 out_fail:
        cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
        cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
        return -EINVAL;
+queue_full:
+       pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
+       cmd->t_state = TRANSPORT_COMPLETE_QF_WP;
+       transport_handle_queue_full(cmd, cmd->se_dev);
+       return 0;
 }
 EXPORT_SYMBOL(transport_generic_new_cmd);
 
@@ -2519,43 +2534,6 @@ static void transport_write_pending_qf(struct se_cmd *cmd)
        }
 }
 
-static int transport_generic_write_pending(struct se_cmd *cmd)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       cmd->t_state = TRANSPORT_WRITE_PENDING;
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-
-       /*
-        * Clear the se_cmd for WRITE_PENDING status in order to set
-        * CMD_T_ACTIVE so that transport_generic_handle_data can be called
-        * from HW target mode interrupt code.  This is safe to be called
-        * with remove_from_lists false before the cmd->se_tfo->write_pending
-        * because the se_cmd->se_lun pointer is not being cleared.
-        */
-       transport_cmd_check_stop(cmd, false);
-
-       /*
-        * Call the fabric write_pending function here to let the
-        * frontend know that WRITE buffers are ready.
-        */
-       ret = cmd->se_tfo->write_pending(cmd);
-       if (ret == -EAGAIN || ret == -ENOMEM)
-               goto queue_full;
-       else if (ret < 0)
-               return ret;
-
-       return 1;
-
-queue_full:
-       pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
-       cmd->t_state = TRANSPORT_COMPLETE_QF_WP;
-       transport_handle_queue_full(cmd, cmd->se_dev);
-       return 0;
-}
-
 void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 {
        if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {