tcm_fc: Offload WRITE I/O backend submission to tpg workqueue
authorChristoph Hellwig <hch@infradead.org>
Sun, 8 Jul 2012 19:58:45 +0000 (15:58 -0400)
committerNicholas Bellinger <nab@linux-iscsi.org>
Tue, 17 Jul 2012 00:35:19 +0000 (17:35 -0700)
Defer the write processing to the internal to be able to use
target_execute_cmd.  I'm not even entirely sure the calling code requires
this due to the convoluted structure in libfc, but let's be safe for now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Mark Rustad <mark.d.rustad@intel.com>
Cc: Kiran Patil <Kiran.patil@intel.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/tcm_fc/tfc_io.c

index 071a505f98fc13256fa536f4a39cae111ccd1050..ad36ede1a1eab12b907964ca8c446262d2918528 100644 (file)
@@ -183,6 +183,13 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
        return ft_queue_status(se_cmd);
 }
 
+static void ft_execute_work(struct work_struct *work)
+{
+       struct ft_cmd *cmd = container_of(work, struct ft_cmd, work);
+
+       target_execute_cmd(&cmd->se_cmd);
+}
+
 /*
  * Receive write data frame.
  */
@@ -307,8 +314,10 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
                cmd->write_data_len += tlen;
        }
 last_frame:
-       if (cmd->write_data_len == se_cmd->data_length)
-               transport_generic_handle_data(se_cmd);
+       if (cmd->write_data_len == se_cmd->data_length) {
+               INIT_WORK(&cmd->work, ft_execute_work);
+               queue_work(cmd->sess->tport->tpg->workqueue, &cmd->work);
+       }
 drop:
        fc_frame_free(fp);
 }