All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio()
@ 2011-07-21  7:11 Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 063/103] target: Rename get_cdb_count to allocate_tasks Nicholas A. Bellinger
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

pdv unused.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_pscsi.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 5df329c..3574c52 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -1051,7 +1051,7 @@ static void pscsi_bi_endio(struct bio *bio, int error)
 	bio_put(bio);
 }
 
-static inline struct bio *pscsi_get_bio(struct pscsi_dev_virt *pdv, int sg_num)
+static inline struct bio *pscsi_get_bio(int sg_num)
 {
 	struct bio *bio;
 	/*
@@ -1124,7 +1124,7 @@ static int __pscsi_map_task_SG(
 				/*
 				 * Calls bio_kmalloc() and sets bio->bi_end_io()
 				 */
-				bio = pscsi_get_bio(pdv, nr_vecs);
+				bio = pscsi_get_bio(nr_vecs);
 				if (!(bio))
 					goto fail;
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 063/103] target: Rename get_cdb_count to allocate_tasks
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 064/103] target: Make transport_generic_new_cmd() available for iscsi-target Nicholas A. Bellinger
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

To be more in-line with what it actually does.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index c5a541d..9bb3ac9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -206,7 +206,7 @@ static int __transport_execute_tasks(struct se_device *dev);
 static void transport_complete_task_attr(struct se_cmd *cmd);
 static void transport_direct_request_timeout(struct se_cmd *cmd);
 static void transport_free_dev_tasks(struct se_cmd *cmd);
-static u32 transport_generic_get_cdb_count(struct se_cmd *cmd,
+static u32 transport_allocate_tasks(struct se_cmd *cmd,
 		unsigned long long starting_lba, u32 sectors,
 		enum dma_data_direction data_direction,
 		struct list_head *mem_list, int set_counts);
@@ -4013,7 +4013,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd)
 		 */
 		if (!list_empty(&cmd->t_mem_bidi_list) &&
 		    (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV)) {
-			rc = transport_generic_get_cdb_count(cmd,
+			rc = transport_allocate_tasks(cmd,
 				cmd->t_task_lba,
 				transport_cmd_get_valid_sectors(cmd),
 				DMA_FROM_DEVICE, &cmd->t_mem_bidi_list,
@@ -4030,7 +4030,7 @@ static int transport_new_cmd_obj(struct se_cmd *cmd)
 		 * Setup the tasks and memory from cmd->t_mem_list
 		 * Note for BIDI transfers this will contain the WRITE payload
 		 */
-		task_cdbs = transport_generic_get_cdb_count(cmd,
+		task_cdbs = transport_allocate_tasks(cmd,
 				cmd->t_task_lba,
 				transport_cmd_get_valid_sectors(cmd),
 				cmd->data_direction, &cmd->t_mem_list,
@@ -4562,7 +4562,7 @@ static int transport_do_se_mem_map(
 /*
  * Break up cmd into chunks transport can handle
  */
-static u32 transport_generic_get_cdb_count(
+static u32 transport_allocate_tasks(
 	struct se_cmd *cmd,
 	unsigned long long lba,
 	u32 sectors,
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 064/103] target: Make transport_generic_new_cmd() available for iscsi-target
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 063/103] target: Rename get_cdb_count to allocate_tasks Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 065/103] target: Remove fabric callback to allocate iovecs Nicholas A. Bellinger
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch makes transport_generic_new_cmd() defined as EXPORT_SYMBOL()
for use with iscsi-target direct task allocation.  It then changes
iscsi-target to use this direct method instead of the legacy
transport_generic_handle_cdb() queue usage.

Signed-off-by: Andy Grover <agrover@redhat.com>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    4 ++--
 include/target/target_core_transport.h |    1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9bb3ac9..fbc5687 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1842,7 +1842,6 @@ int transport_generic_handle_cdb(
 		printk(KERN_ERR "cmd->se_lun is NULL\n");
 		return -EINVAL;
 	}
-
 	transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
 	return 0;
 }
@@ -4747,7 +4746,7 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd)
 	/*
 	 * Generate struct se_task(s) and/or their payloads for this CDB.
 	 */
-static int transport_generic_new_cmd(struct se_cmd *cmd)
+int transport_generic_new_cmd(struct se_cmd *cmd)
 {
 	struct se_portal_group *se_tpg;
 	struct se_task *task;
@@ -4817,6 +4816,7 @@ static int transport_generic_new_cmd(struct se_cmd *cmd)
 	transport_execute_tasks(cmd);
 	return 0;
 }
+EXPORT_SYMBOL(transport_generic_new_cmd);
 
 /*	transport_generic_process_write():
  *
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 4bbd88b..c9846d5 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -188,6 +188,7 @@ extern int transport_map_mem_to_sg(struct se_task *, struct list_head *,
 					struct se_mem **, u32 *, u32 *);
 extern void transport_do_task_sg_chain(struct se_cmd *);
 extern void transport_generic_process_write(struct se_cmd *);
+extern int transport_generic_new_cmd(struct se_cmd *);
 extern int transport_generic_do_tmr(struct se_cmd *);
 /* From target_core_alua.c */
 extern int core_alua_check_nonop_delay(struct se_cmd *);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 065/103] target: Remove fabric callback to allocate iovecs
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 063/103] target: Rename get_cdb_count to allocate_tasks Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 064/103] target: Make transport_generic_new_cmd() available for iscsi-target Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 066/103] target: Fix transport_generic_new_cmd WRITE comment Nicholas A. Bellinger
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

iscsi is the only one to use it, and by allocating it from
iscsit_alloc_buffs we are covered.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c      |    7 -------
 drivers/target/target_core_transport.c  |   13 -------------
 include/target/target_core_fabric_ops.h |    5 -----
 3 files changed, 0 insertions(+), 25 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index f6f78f1..1e0c7ca 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -1424,13 +1424,6 @@ static int tcm_loop_register_configfs(void)
 					&tcm_loop_tpg_release_fabric_acl;
 	fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
 	/*
-	 * Since tcm_loop is mapping physical memory from Linux/SCSI
-	 * struct scatterlist arrays for each struct scsi_cmnd I/O,
-	 * we do not need TCM to allocate a iovec array for
-	 * virtual memory address mappings
-	 */
-	fabric->tf_ops.alloc_cmd_iovecs = NULL;
-	/*
 	 * Used for setting up remaining TCM resources in process context
 	 */
 	fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index fbc5687..9fc017e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4748,7 +4748,6 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd)
 	 */
 int transport_generic_new_cmd(struct se_cmd *cmd)
 {
-	struct se_portal_group *se_tpg;
 	struct se_task *task;
 	struct se_device *dev = cmd->se_dev;
 	int ret = 0;
@@ -4769,18 +4768,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
 	if (ret < 0)
 		return ret;
 
-	/*
-	 * Determine if the calling TCM fabric module is talking to
-	 * Linux/NET via kernel sockets and needs to allocate a
-	 * struct iovec array to complete the struct se_cmd
-	 */
-	se_tpg = cmd->se_lun->lun_sep->sep_tpg;
-	if (se_tpg->se_tpg_tfo->alloc_cmd_iovecs != NULL) {
-		ret = se_tpg->se_tpg_tfo->alloc_cmd_iovecs(cmd);
-		if (ret < 0)
-			return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
-	}
-
 	if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
 		list_for_each_entry(task, &cmd->t_task_list, t_list) {
 			if (atomic_read(&task->task_sent))
diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h
index 747e140..1752ed3 100644
--- a/include/target/target_core_fabric_ops.h
+++ b/include/target/target_core_fabric_ops.h
@@ -39,11 +39,6 @@ struct target_core_fabric_ops {
 	 */
 	int (*new_cmd_map)(struct se_cmd *);
 	/*
-	 * Optional function pointer for TCM fabric modules that use
-	 * Linux/NET sockets to allocate struct iovec array to struct se_cmd
-	 */
-	int (*alloc_cmd_iovecs)(struct se_cmd *);
-	/*
 	 * Optional to release struct se_cmd and fabric dependent allocated
 	 * I/O descriptor in transport_cmd_check_stop()
 	 */
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 066/103] target: Fix transport_generic_new_cmd WRITE comment
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (2 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 065/103] target: Remove fabric callback to allocate iovecs Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 067/103] target: remove the always-noop ->new_cmd_failure method Nicholas A. Bellinger
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Remove fabric dependent language in transport_generic_new_cmd()

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9fc017e..6f2855d 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4786,7 +4786,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
 	}
 
 	/*
-	 * For WRITEs, let the iSCSI Target RX Thread know its buffer is ready..
+	 * For WRITEs, let the fabric know its buffer is ready..
 	 * This WRITE struct se_cmd (and all of its associated struct se_task's)
 	 * will be added to the struct se_device execution queue after its WRITE
 	 * data has arrived. (ie: It gets handled by the transport processing
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 067/103] target: remove the always-noop ->new_cmd_failure method
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (3 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 066/103] target: Fix transport_generic_new_cmd WRITE comment Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 068/103] target: remove the unused SCF_SE_DISABLE_ONLINE_CHECK flag Nicholas A. Bellinger
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c      |   11 -----------
 drivers/target/target_core_configfs.c   |    4 ----
 drivers/target/target_core_tmr.c        |    5 -----
 drivers/target/target_core_transport.c  |    2 --
 drivers/target/tcm_fc/tcm_fc.h          |    1 -
 drivers/target/tcm_fc/tfc_cmd.c         |    6 ------
 drivers/target/tcm_fc/tfc_conf.c        |    1 -
 include/target/target_core_fabric_ops.h |    1 -
 8 files changed, 0 insertions(+), 31 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 1e0c7ca..2c8a221 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -772,16 +772,6 @@ static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
 	return 1;
 }
 
-static void tcm_loop_new_cmd_failure(struct se_cmd *se_cmd)
-{
-	/*
-	 * Since TCM_loop is already passing struct scatterlist data from
-	 * struct scsi_cmnd, no more Linux/SCSI failure dependent state need
-	 * to be handled here.
-	 */
-	return;
-}
-
 static int tcm_loop_is_state_remove(struct se_cmd *se_cmd)
 {
 	/*
@@ -1446,7 +1436,6 @@ static int tcm_loop_register_configfs(void)
 					&tcm_loop_set_default_node_attributes;
 	fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
 	fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
-	fabric->tf_ops.new_cmd_failure = &tcm_loop_new_cmd_failure;
 	fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
 	fabric->tf_ops.queue_status = &tcm_loop_queue_status;
 	fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index ac7f765..aac0ee9 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -479,10 +479,6 @@ static int target_fabric_tf_ops_check(
 		printk(KERN_ERR "Missing tfo->get_cmd_state()\n");
 		return -EINVAL;
 	}
-	if (!(tfo->new_cmd_failure)) {
-		printk(KERN_ERR "Missing tfo->new_cmd_failure()\n");
-		return -EINVAL;
-	}
 	if (!(tfo->queue_data_in)) {
 		printk(KERN_ERR "Missing tfo->queue_data_in()\n");
 		return -EINVAL;
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 6667e39..5c20de3 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -356,11 +356,6 @@ int core_tmr_lun_reset(
 			atomic_read(&cmd->t_fe_count));
 		/*
 		 * Signal that the command has failed via cmd->se_cmd_flags,
-		 * and call TFO->new_cmd_failure() to wakeup any fabric
-		 * dependent code used to wait for unsolicited data out
-		 * allocation to complete.  The fabric module is expected
-		 * to dump any remaining unsolicited data out for the aborted
-		 * command at this point.
 		 */
 		transport_new_cmd_failure(cmd);
 
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 6f2855d..e3544c8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2586,8 +2586,6 @@ void transport_new_cmd_failure(struct se_cmd *se_cmd)
 	se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED;
 	se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
 	spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
-
-	se_cmd->se_tfo->new_cmd_failure(se_cmd);
 }
 
 static void transport_nop_wait_for_tasks(struct se_cmd *, int, int);
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 7b82f1b..8d26779 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -195,7 +195,6 @@ int ft_write_pending(struct se_cmd *);
 int ft_write_pending_status(struct se_cmd *);
 u32 ft_get_task_tag(struct se_cmd *);
 int ft_get_cmd_state(struct se_cmd *);
-void ft_new_cmd_failure(struct se_cmd *);
 int ft_queue_tm_resp(struct se_cmd *);
 int ft_is_state_remove(struct se_cmd *);
 
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 62b1226..4bf0a8f 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -294,12 +294,6 @@ int ft_is_state_remove(struct se_cmd *se_cmd)
 	return 0;	/* XXX TBD */
 }
 
-void ft_new_cmd_failure(struct se_cmd *se_cmd)
-{
-	/* XXX TBD */
-	printk(KERN_INFO "%s: se_cmd %p\n", __func__, se_cmd);
-}
-
 /*
  * FC sequence response handler for follow-on sequences (data) and aborts.
  */
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index e3176f5..2490e99 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -550,7 +550,6 @@ static struct target_core_fabric_ops ft_fabric_ops = {
 	.set_default_node_attributes =	ft_set_default_node_attr,
 	.get_task_tag =			ft_get_task_tag,
 	.get_cmd_state =		ft_get_cmd_state,
-	.new_cmd_failure =		ft_new_cmd_failure,
 	.queue_data_in =		ft_queue_data_in,
 	.queue_status =			ft_queue_status,
 	.queue_tm_rsp =			ft_queue_tm_resp,
diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h
index 1752ed3..eba7201 100644
--- a/include/target/target_core_fabric_ops.h
+++ b/include/target/target_core_fabric_ops.h
@@ -65,7 +65,6 @@ struct target_core_fabric_ops {
 	void (*set_default_node_attributes)(struct se_node_acl *);
 	u32 (*get_task_tag)(struct se_cmd *);
 	int (*get_cmd_state)(struct se_cmd *);
-	void (*new_cmd_failure)(struct se_cmd *);
 	int (*queue_data_in)(struct se_cmd *);
 	int (*queue_status)(struct se_cmd *);
 	int (*queue_tm_rsp)(struct se_cmd *);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 068/103] target: remove the unused SCF_SE_DISABLE_ONLINE_CHECK flag
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (4 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 067/103] target: remove the always-noop ->new_cmd_failure method Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 069/103] target: remove the unused SCF_CMD_PASSTHROUGH_NOALLOC flag Nicholas A. Bellinger
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   12 +++++-------
 include/target/target_core_base.h      |    1 -
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index e3544c8..bd97c6a 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2431,14 +2431,12 @@ static int transport_execute_tasks(struct se_cmd *cmd)
 {
 	int add_tasks;
 
-	if (!(cmd->se_cmd_flags & SCF_SE_DISABLE_ONLINE_CHECK)) {
-		if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) {
-			cmd->transport_error_status =
-				PYX_TRANSPORT_LU_COMM_FAILURE;
-			transport_generic_request_failure(cmd, NULL, 0, 1);
-			return 0;
-		}
+	if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) {
+		cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE;
+		transport_generic_request_failure(cmd, NULL, 0, 1);
+		return 0;
 	}
+
 	/*
 	 * Call transport_cmd_check_stop() to see if a fabric exception
 	 * has occurred that prevents execution.
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 71c96ce..bfcf4c2 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -116,7 +116,6 @@ enum se_cmd_flags_table {
 	SCF_SE_CMD_FAILED		= 0x00000400,
 	SCF_SE_LUN_CMD			= 0x00000800,
 	SCF_SE_ALLOW_EOO		= 0x00001000,
-	SCF_SE_DISABLE_ONLINE_CHECK	= 0x00002000,
 	SCF_SENT_CHECK_CONDITION	= 0x00004000,
 	SCF_OVERFLOW_BIT		= 0x00008000,
 	SCF_UNDERFLOW_BIT		= 0x00010000,
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 069/103] target: remove the unused SCF_CMD_PASSTHROUGH_NOALLOC flag
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (5 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 068/103] target: remove the unused SCF_SE_DISABLE_ONLINE_CHECK flag Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 070/103] target: remove the unused SCF_EMULATE_SYNC_UNMAP flag Nicholas A. Bellinger
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    6 ------
 include/target/target_core_base.h      |    1 -
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index bd97c6a..6ca367d 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -3758,12 +3758,6 @@ static inline void transport_free_pages(struct se_cmd *cmd)
 		return;
 	}
 
-	/*
-	 * Caller will handle releasing of struct se_mem.
-	 */
-	if (cmd->se_cmd_flags & SCF_CMD_PASSTHROUGH_NOALLOC)
-		return;
-
 	list_for_each_entry_safe(se_mem, se_mem_tmp,
 			&cmd->t_mem_list, se_list) {
 		/*
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index bfcf4c2..820ff2e 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -112,7 +112,6 @@ enum se_cmd_flags_table {
 	SCF_SCSI_NON_DATA_CDB		= 0x00000040,
 	SCF_SCSI_CDB_EXCEPTION		= 0x00000080,
 	SCF_SCSI_RESERVATION_CONFLICT	= 0x00000100,
-	SCF_CMD_PASSTHROUGH_NOALLOC	= 0x00000200,
 	SCF_SE_CMD_FAILED		= 0x00000400,
 	SCF_SE_LUN_CMD			= 0x00000800,
 	SCF_SE_ALLOW_EOO		= 0x00001000,
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 070/103] target: remove the unused SCF_EMULATE_SYNC_UNMAP flag
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (6 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 069/103] target: remove the unused SCF_CMD_PASSTHROUGH_NOALLOC flag Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 071/103] target: remove the unused SCF_EMULATE_SYNC_CACHE flag Nicholas A. Bellinger
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   12 ------------
 include/target/target_core_base.h      |    1 -
 2 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 6ca367d..43fd277 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -3396,18 +3396,6 @@ static int transport_generic_cmd_sequencer(
 		break;
 	case UNMAP:
 		size = get_unaligned_be16(&cdb[7]);
-		passthrough = (dev->transport->transport_type ==
-				TRANSPORT_PLUGIN_PHBA_PDEV);
-		/*
-		 * Determine if the received UNMAP used to for direct passthrough
-		 * into Linux/SCSI with struct request via TCM/pSCSI or we are
-		 * signaling the use of internal transport_generic_unmap() emulation
-		 * for UNMAP -> Linux/BLOCK disbard with TCM/IBLOCK and TCM/FILEIO
-		 * subsystem plugin backstores.
-		 */
-		if (!(passthrough))
-			cmd->se_cmd_flags |= SCF_EMULATE_SYNC_UNMAP;
-
 		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
 		break;
 	case WRITE_SAME_16:
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 820ff2e..72ef4b8 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -126,7 +126,6 @@ enum se_cmd_flags_table {
 	SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
 	SCF_EMULATE_SYNC_CACHE		= 0x00800000,
 	SCF_EMULATE_CDB_ASYNC		= 0x01000000,
-	SCF_EMULATE_SYNC_UNMAP		= 0x02000000
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 071/103] target: remove the unused SCF_EMULATE_SYNC_CACHE flag
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (7 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 070/103] target: remove the unused SCF_EMULATE_SYNC_UNMAP flag Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 072/103] target: merge release_cmd methods Nicholas A. Bellinger
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 include/target/target_core_base.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 72ef4b8..71abc4c 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -124,7 +124,6 @@ enum se_cmd_flags_table {
 	SCF_UNUSED			= 0x00100000,
 	SCF_PASSTHROUGH_CONTIG_TO_SG	= 0x00200000,
 	SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
-	SCF_EMULATE_SYNC_CACHE		= 0x00800000,
 	SCF_EMULATE_CDB_ASYNC		= 0x01000000,
 };
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 072/103] target: merge release_cmd methods
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (8 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 071/103] target: remove the unused SCF_EMULATE_SYNC_CACHE flag Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 073/103] target: Add transport_handle_cdb_direct optimization Nicholas A. Bellinger
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Christoph Hellwig

From: Christoph Hellwig <hch@infradead.org>

The release_cmd_to_pool and release_cmd_direct methods are always the same.
Merge them into a single release_cmd method, and clean up the fallout.

(nab: fix breakage in transport_generic_free_cmd() parameter build breakage
 in drivers/target/tcm_fc/tfc_cmd.c)

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c      |   12 ++-----
 drivers/target/target_core_configfs.c   |    8 +---
 drivers/target/target_core_transport.c  |   53 +++++++++++--------------------
 drivers/target/tcm_fc/tfc_cmd.c         |   12 +++---
 drivers/target/tcm_fc/tfc_conf.c        |    3 +-
 include/target/target_core_fabric_ops.h |    3 +-
 include/target/target_core_transport.h  |    4 +-
 7 files changed, 35 insertions(+), 60 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 2c8a221..083d6c5 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -204,13 +204,10 @@ static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
 	 * Release the struct se_cmd, which will make a callback to release
 	 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
 	 */
-	transport_generic_free_cmd(se_cmd, 0, 1, 0);
+	transport_generic_free_cmd(se_cmd, 0, 0);
 }
 
-/*
- * Called from struct target_core_fabric_ops->release_cmd_to_pool()
- */
-static void tcm_loop_deallocate_core_cmd(struct se_cmd *se_cmd)
+static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
 {
 	struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
 				struct tcm_loop_cmd, tl_se_cmd);
@@ -395,7 +392,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
 		SUCCESS : FAILED;
 release:
 	if (se_cmd)
-		transport_generic_free_cmd(se_cmd, 1, 1, 0);
+		transport_generic_free_cmd(se_cmd, 1, 0);
 	else
 		kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
 	kfree(tl_tmr);
@@ -1418,8 +1415,7 @@ static int tcm_loop_register_configfs(void)
 	 */
 	fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
 	fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
-	fabric->tf_ops.release_cmd_to_pool = &tcm_loop_deallocate_core_cmd;
-	fabric->tf_ops.release_cmd_direct = &tcm_loop_deallocate_core_cmd;
+	fabric->tf_ops.release_cmd = &tcm_loop_release_cmd;
 	fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
 	fabric->tf_ops.close_session = &tcm_loop_close_session;
 	fabric->tf_ops.stop_session = &tcm_loop_stop_session;
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index aac0ee9..63cba1e 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -427,12 +427,8 @@ static int target_fabric_tf_ops_check(
 		printk(KERN_ERR "Missing tfo->tpg_get_inst_index()\n");
 		return -EINVAL;
 	}
-	if (!(tfo->release_cmd_to_pool)) {
-		printk(KERN_ERR "Missing tfo->release_cmd_to_pool()\n");
-		return -EINVAL;
-	}
-	if (!(tfo->release_cmd_direct)) {
-		printk(KERN_ERR "Missing tfo->release_cmd_direct()\n");
+	if (!tfo->release_cmd) {
+		printk(KERN_ERR "Missing tfo->release_cmd()\n");
 		return -EINVAL;
 	}
 	if (!(tfo->shutdown_session)) {
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 43fd277..d42a98e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -212,7 +212,7 @@ static u32 transport_allocate_tasks(struct se_cmd *cmd,
 		struct list_head *mem_list, int set_counts);
 static int transport_generic_get_mem(struct se_cmd *cmd, u32 length);
 static int transport_generic_remove(struct se_cmd *cmd,
-		int release_to_pool, int session_reinstatement);
+		int session_reinstatement);
 static int transport_cmd_get_valid_sectors(struct se_cmd *cmd);
 static int transport_map_sg_to_mem(struct se_cmd *cmd,
 		struct list_head *se_mem_list, struct scatterlist *sgl);
@@ -737,7 +737,7 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 	if (transport_cmd_check_stop_to_fabric(cmd))
 		return;
 	if (remove)
-		transport_generic_remove(cmd, 0, 0);
+		transport_generic_remove(cmd, 0);
 }
 
 void transport_cmd_finish_abort_tmr(struct se_cmd *cmd)
@@ -747,7 +747,7 @@ void transport_cmd_finish_abort_tmr(struct se_cmd *cmd)
 	if (transport_cmd_check_stop_to_fabric(cmd))
 		return;
 
-	transport_generic_remove(cmd, 0, 0);
+	transport_generic_remove(cmd, 0);
 }
 
 static void transport_add_cmd_to_queue(
@@ -2146,7 +2146,7 @@ static void transport_generic_request_timeout(struct se_cmd *cmd)
 	}
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-	transport_generic_remove(cmd, 0, 0);
+	transport_generic_remove(cmd, 0);
 }
 
 static int
@@ -3825,13 +3825,11 @@ static void transport_release_fe_cmd(struct se_cmd *cmd)
 free_pages:
 	transport_free_pages(cmd);
 	transport_free_se_cmd(cmd);
-	cmd->se_tfo->release_cmd_direct(cmd);
+	cmd->se_tfo->release_cmd(cmd);
 }
 
-static int transport_generic_remove(
-	struct se_cmd *cmd,
-	int release_to_pool,
-	int session_reinstatement)
+static int
+transport_generic_remove(struct se_cmd *cmd, int session_reinstatement)
 {
 	unsigned long flags;
 
@@ -3858,14 +3856,7 @@ static int transport_generic_remove(
 
 free_pages:
 	transport_free_pages(cmd);
-
-	if (release_to_pool) {
-		transport_release_cmd_to_pool(cmd);
-	} else {
-		transport_free_se_cmd(cmd);
-		cmd->se_tfo->release_cmd_direct(cmd);
-	}
-
+	transport_release_cmd(cmd);
 	return 0;
 }
 
@@ -4894,18 +4885,14 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
 	return PYX_TRANSPORT_WRITE_PENDING;
 }
 
-/*	transport_release_cmd_to_pool():
- *
- *
- */
-void transport_release_cmd_to_pool(struct se_cmd *cmd)
+void transport_release_cmd(struct se_cmd *cmd)
 {
 	BUG_ON(!cmd->se_tfo);
 
 	transport_free_se_cmd(cmd);
-	cmd->se_tfo->release_cmd_to_pool(cmd);
+	cmd->se_tfo->release_cmd(cmd);
 }
-EXPORT_SYMBOL(transport_release_cmd_to_pool);
+EXPORT_SYMBOL(transport_release_cmd);
 
 /*	transport_generic_free_cmd():
  *
@@ -4914,11 +4901,10 @@ EXPORT_SYMBOL(transport_release_cmd_to_pool);
 void transport_generic_free_cmd(
 	struct se_cmd *cmd,
 	int wait_for_tasks,
-	int release_to_pool,
 	int session_reinstatement)
 {
 	if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD))
-		transport_release_cmd_to_pool(cmd);
+		transport_release_cmd(cmd);
 	else {
 		core_dec_lacl_count(cmd->se_sess->se_node_acl, cmd);
 
@@ -4936,8 +4922,7 @@ void transport_generic_free_cmd(
 
 		transport_free_dev_tasks(cmd);
 
-		transport_generic_remove(cmd, release_to_pool,
-				session_reinstatement);
+		transport_generic_remove(cmd, session_reinstatement);
 	}
 }
 EXPORT_SYMBOL(transport_generic_free_cmd);
@@ -5210,7 +5195,7 @@ remove:
 	if (!remove_cmd)
 		return;
 
-	transport_generic_free_cmd(cmd, 0, 0, session_reinstatement);
+	transport_generic_free_cmd(cmd, 0, session_reinstatement);
 }
 
 static int transport_get_sense_codes(
@@ -5616,7 +5601,7 @@ static void transport_processing_shutdown(struct se_device *dev)
 				transport_lun_remove_cmd(cmd);
 
 				if (transport_cmd_check_stop(cmd, 1, 0))
-					transport_generic_remove(cmd, 0, 0);
+					transport_generic_remove(cmd, 0);
 			}
 
 			spin_lock_irqsave(&dev->execute_task_lock, flags);
@@ -5644,7 +5629,7 @@ static void transport_processing_shutdown(struct se_device *dev)
 			transport_lun_remove_cmd(cmd);
 
 			if (transport_cmd_check_stop(cmd, 1, 0))
-				transport_generic_remove(cmd, 0, 0);
+				transport_generic_remove(cmd, 0);
 		}
 
 		spin_lock_irqsave(&dev->execute_task_lock, flags);
@@ -5667,7 +5652,7 @@ static void transport_processing_shutdown(struct se_device *dev)
 		} else {
 			transport_lun_remove_cmd(cmd);
 			if (transport_cmd_check_stop(cmd, 1, 0))
-				transport_generic_remove(cmd, 0, 0);
+				transport_generic_remove(cmd, 0);
 		}
 	}
 }
@@ -5739,10 +5724,10 @@ get_cmd:
 			transport_generic_complete_ok(cmd);
 			break;
 		case TRANSPORT_REMOVE:
-			transport_generic_remove(cmd, 1, 0);
+			transport_generic_remove(cmd, 0);
 			break;
 		case TRANSPORT_FREE_CMD_INTR:
-			transport_generic_free_cmd(cmd, 0, 1, 0);
+			transport_generic_free_cmd(cmd, 0, 0);
 			break;
 		case TRANSPORT_PROCESS_TMR:
 			transport_generic_do_tmr(cmd);
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 4bf0a8f..a00951c 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -149,7 +149,7 @@ void ft_release_cmd(struct se_cmd *se_cmd)
 
 void ft_check_stop_free(struct se_cmd *se_cmd)
 {
-	transport_generic_free_cmd(se_cmd, 0, 1, 0);
+	transport_generic_free_cmd(se_cmd, 0, 0);
 }
 
 /*
@@ -306,7 +306,7 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
 		/* XXX need to find cmd if queued */
 		cmd->se_cmd.t_state = TRANSPORT_REMOVE;
 		cmd->seq = NULL;
-		transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+		transport_generic_free_cmd(&cmd->se_cmd, 0, 0);
 		return;
 	}
 
@@ -323,7 +323,7 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
 		printk(KERN_INFO "%s: unhandled frame r_ctl %x\n",
 		       __func__, fh->fh_r_ctl);
 		fc_frame_free(fp);
-		transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+		transport_generic_free_cmd(&cmd->se_cmd, 0, 0);
 		break;
 	}
 }
@@ -445,7 +445,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
 			sess = cmd->sess;
 			transport_send_check_condition_and_sense(&cmd->se_cmd,
 				cmd->se_cmd.scsi_sense_reason, 0);
-			transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+			transport_generic_free_cmd(&cmd->se_cmd, 0, 0);
 			ft_sess_put(sess);
 			return;
 		}
@@ -647,7 +647,7 @@ static void ft_send_cmd(struct ft_cmd *cmd)
 	if (ret == -ENOMEM) {
 		transport_send_check_condition_and_sense(se_cmd,
 				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
-		transport_generic_free_cmd(se_cmd, 0, 1, 0);
+		transport_generic_free_cmd(se_cmd, 0, 0);
 		return;
 	}
 	if (ret == -EINVAL) {
@@ -656,7 +656,7 @@ static void ft_send_cmd(struct ft_cmd *cmd)
 		else
 			transport_send_check_condition_and_sense(se_cmd,
 					se_cmd->scsi_sense_reason, 0);
-		transport_generic_free_cmd(se_cmd, 0, 1, 0);
+		transport_generic_free_cmd(se_cmd, 0, 0);
 		return;
 	}
 	transport_generic_handle_cdb(se_cmd);
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 2490e99..ec9e40d 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -536,8 +536,7 @@ static struct target_core_fabric_ops ft_fabric_ops = {
 	.tpg_release_fabric_acl =	ft_tpg_release_fabric_acl,
 	.tpg_get_inst_index =		ft_tpg_get_inst_index,
 	.check_stop_free =		ft_check_stop_free,
-	.release_cmd_to_pool =		ft_release_cmd,
-	.release_cmd_direct =		ft_release_cmd,
+	.release_cmd =			ft_release_cmd,
 	.shutdown_session =		ft_sess_shutdown,
 	.close_session =		ft_sess_close,
 	.stop_session =			ft_sess_stop,
diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h
index eba7201..2de8fe9 100644
--- a/include/target/target_core_fabric_ops.h
+++ b/include/target/target_core_fabric_ops.h
@@ -43,8 +43,7 @@ struct target_core_fabric_ops {
 	 * I/O descriptor in transport_cmd_check_stop()
 	 */
 	void (*check_stop_free)(struct se_cmd *);
-	void (*release_cmd_to_pool)(struct se_cmd *);
-	void (*release_cmd_direct)(struct se_cmd *);
+	void (*release_cmd)(struct se_cmd *);
 	/*
 	 * Called with spin_lock_bh(struct se_portal_group->session_lock held.
 	 */
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index c9846d5..604e669 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -179,8 +179,8 @@ extern int transport_clear_lun_from_sessions(struct se_lun *);
 extern int transport_check_aborted_status(struct se_cmd *, int);
 extern int transport_send_check_condition_and_sense(struct se_cmd *, u8, int);
 extern void transport_send_task_abort(struct se_cmd *);
-extern void transport_release_cmd_to_pool(struct se_cmd *);
-extern void transport_generic_free_cmd(struct se_cmd *, int, int, int);
+extern void transport_release_cmd(struct se_cmd *);
+extern void transport_generic_free_cmd(struct se_cmd *, int, int);
 extern void transport_generic_wait_for_cmds(struct se_cmd *, int);
 extern int transport_init_task_sg(struct se_task *, struct se_mem *, u32);
 extern int transport_map_mem_to_sg(struct se_task *, struct list_head *,
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 073/103] target: Add transport_handle_cdb_direct optimization
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (9 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 072/103] target: merge release_cmd methods Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 074/103] target: Add SCF_EMULATE_QUEUE_FULL -> transport_handle_queue_full Nicholas A. Bellinger
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch adds a transport_handle_cdb_direct() optimization for mapping
and queueing tasks directly from within fabric processing context by calling
the newly exported transport_generic_new_cmd().  This currently expects to
be called from process context only, and will fail if called within interrupt
context.

This patch also leaves transport_generic_handle_cdb() unmodified for the
moment to function as expected with existing tcm_fc and ib_srpt fabrics,
and will be removed once these have been converted and tested with v4.1
code using transport_handle_cdb_direct().

Based on Andy's original patch here:

[PATCH 39/42] target: Call transport_new_cmd instead of adding to cmd queue

Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   24 ++++++++++++++++++++++++
 include/target/target_core_transport.h |    1 +
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index d42a98e..1ae6eb7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1842,12 +1842,36 @@ int transport_generic_handle_cdb(
 		printk(KERN_ERR "cmd->se_lun is NULL\n");
 		return -EINVAL;
 	}
+
 	transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
 	return 0;
 }
 EXPORT_SYMBOL(transport_generic_handle_cdb);
 
 /*
+ * Used by fabric module frontends to queue tasks directly.
+ * Many only be used from process context only
+ */
+int transport_handle_cdb_direct(
+	struct se_cmd *cmd)
+{
+	if (!cmd->se_lun) {
+		dump_stack();
+		printk(KERN_ERR "cmd->se_lun is NULL\n");
+		return -EINVAL;
+	}
+	if (in_interrupt()) {
+		dump_stack();
+		printk(KERN_ERR "transport_generic_handle_cdb cannot be called"
+				" from interrupt context\n");
+		return -EINVAL;
+	}
+
+	return transport_generic_new_cmd(cmd);
+}
+EXPORT_SYMBOL(transport_handle_cdb_direct);
+
+/*
  * Used by fabric module frontends defining a TFO->new_cmd_map() caller
  * to  queue up a newly setup se_cmd w/ TRANSPORT_NEW_CMD_MAP in order to
  * complete setup in TCM process context w/ TFO->new_cmd_map().
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 604e669..2aae764 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -166,6 +166,7 @@ extern void transport_init_se_cmd(struct se_cmd *,
 extern void transport_free_se_cmd(struct se_cmd *);
 extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
 extern int transport_generic_handle_cdb(struct se_cmd *);
+extern int transport_handle_cdb_direct(struct se_cmd *);
 extern int transport_generic_handle_cdb_map(struct se_cmd *);
 extern int transport_generic_handle_data(struct se_cmd *);
 extern void transport_new_cmd_failure(struct se_cmd *);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 074/103] target: Add SCF_EMULATE_QUEUE_FULL -> transport_handle_queue_full
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (10 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 073/103] target: Add transport_handle_cdb_direct optimization Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 075/103] target: Make transport_lookup_cmd_lun() locking IRQ-safe Nicholas A. Bellinger
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch adds SCF_EMULATE_QUEUE_FULL support using -EAGAIN failures
via transport_handle_queue_full() to signal queue full in completion
path TFO->queue_data_in() and TFO->queue_status() callbacks.

This is done using a new se_cmd->transport_qf_callback() to handle
the following queue full exception cases within target core:

*) TRANSPORT_COMPLETE_OK (for completion path queue full)

*) TRANSPORT_COMPLETE_QF_WP (for TRANSPORT_WRITE_PENDING queue full)

*) transport_send_check_condition_and_sense() failure paths in
   transport_generic_request_failure() and transport_generic_complete_ok()

All logic is driven using se_device->qf_work_queue -> target_qf_do_work()
to to requeue outstanding se_cmd at the head of se_dev->queue_obj->qobj_list
for transport_processing_thread() execution.

Tested using tcm_qla2xxx with MAX_OUTSTANDING_COMMANDS=128 for FCP READ
to trigger the TRANSPORT_COMPLETE_OK queue full cases, and a simulated
TFO->write_pending() -EAGAIN failure to trigger TRANSPORT_COMPLETE_QF_WP.

Reported-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |  194 +++++++++++++++++++++++++++++---
 include/target/target_core_base.h      |    9 ++
 2 files changed, 188 insertions(+), 15 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1ae6eb7..056c4cb 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -204,6 +204,9 @@ static int transport_generic_write_pending(struct se_cmd *);
 static int transport_processing_thread(void *param);
 static int __transport_execute_tasks(struct se_device *dev);
 static void transport_complete_task_attr(struct se_cmd *cmd);
+static int transport_complete_qf(struct se_cmd *cmd);
+static void transport_handle_queue_full(struct se_cmd *cmd,
+		struct se_device *dev, int (*qf_callback)(struct se_cmd *));
 static void transport_direct_request_timeout(struct se_cmd *cmd);
 static void transport_free_dev_tasks(struct se_cmd *cmd);
 static u32 transport_allocate_tasks(struct se_cmd *cmd,
@@ -768,7 +771,11 @@ static void transport_add_cmd_to_queue(
 	}
 
 	spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
-	list_add_tail(&cmd->se_queue_node, &qobj->qobj_list);
+	if (cmd->se_cmd_flags & SCF_EMULATE_QUEUE_FULL) {
+		cmd->se_cmd_flags &= ~SCF_EMULATE_QUEUE_FULL;
+		list_add(&cmd->se_queue_node, &qobj->qobj_list);
+	} else
+		list_add_tail(&cmd->se_queue_node, &qobj->qobj_list);
 	atomic_inc(&cmd->t_transport_queue_active);
 	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 
@@ -1102,6 +1109,40 @@ void transport_remove_task_from_execute_queue(
 	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
 
+/*
+ * Handle QUEUE_FULL / -EAGAIN status
+ */
+
+static void target_qf_do_work(struct work_struct *work)
+{
+	struct se_device *dev = container_of(work, struct se_device,
+					qf_work_queue);
+	struct se_cmd *cmd, *cmd_tmp;
+
+	spin_lock_irq(&dev->qf_cmd_lock);
+	list_for_each_entry_safe(cmd, cmd_tmp, &dev->qf_cmd_list, se_qf_node) {
+
+		list_del(&cmd->se_qf_node);
+		atomic_dec(&dev->dev_qf_count);
+		smp_mb__after_atomic_dec();
+		spin_unlock_irq(&dev->qf_cmd_lock);
+
+		printk(KERN_INFO "Processing %s cmd: %p QUEUE_FULL in work queue"
+			" context: %s\n", cmd->se_tfo->get_fabric_name(), cmd,
+			(cmd->t_state == TRANSPORT_COMPLETE_OK) ? "COMPLETE_OK" :
+			(cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING"
+			: "UNKNOWN");
+		/*
+		 * The SCF_EMULATE_QUEUE_FULL flag will be cleared once se_cmd
+		 * has been added to head of queue
+		 */
+		transport_add_cmd_to_queue(cmd, cmd->t_state);
+
+		spin_lock_irq(&dev->qf_cmd_lock);
+	}
+	spin_unlock_irq(&dev->qf_cmd_lock);
+}
+
 unsigned char *transport_dump_cmd_direction(struct se_cmd *cmd)
 {
 	switch (cmd->data_direction) {
@@ -1531,6 +1572,7 @@ struct se_device *transport_add_device_to_core_hba(
 	INIT_LIST_HEAD(&dev->delayed_cmd_list);
 	INIT_LIST_HEAD(&dev->ordered_cmd_list);
 	INIT_LIST_HEAD(&dev->state_task_list);
+	INIT_LIST_HEAD(&dev->qf_cmd_list);
 	spin_lock_init(&dev->execute_task_lock);
 	spin_lock_init(&dev->delayed_cmd_lock);
 	spin_lock_init(&dev->ordered_cmd_lock);
@@ -1541,6 +1583,7 @@ struct se_device *transport_add_device_to_core_hba(
 	spin_lock_init(&dev->dev_status_thr_lock);
 	spin_lock_init(&dev->se_port_lock);
 	spin_lock_init(&dev->se_tmr_lock);
+	spin_lock_init(&dev->qf_cmd_lock);
 
 	dev->queue_depth	= dev_limits->queue_depth;
 	atomic_set(&dev->depth_left, dev->queue_depth);
@@ -1584,7 +1627,10 @@ struct se_device *transport_add_device_to_core_hba(
 			dev->transport->name);
 		goto out;
 	}
-
+	/*
+	 * Setup work_queue for QUEUE_FULL
+	 */
+	INIT_WORK(&dev->qf_work_queue, target_qf_do_work);
 	/*
 	 * Preload the initial INQUIRY const values if we are doing
 	 * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
@@ -1697,6 +1743,7 @@ void transport_init_se_cmd(
 	INIT_LIST_HEAD(&cmd->se_lun_node);
 	INIT_LIST_HEAD(&cmd->se_delayed_node);
 	INIT_LIST_HEAD(&cmd->se_ordered_node);
+	INIT_LIST_HEAD(&cmd->se_qf_node);
 
 	INIT_LIST_HEAD(&cmd->t_mem_list);
 	INIT_LIST_HEAD(&cmd->t_mem_bidi_list);
@@ -2019,6 +2066,8 @@ static void transport_generic_request_failure(
 	int complete,
 	int sc)
 {
+	int ret = 0;
+
 	DEBUG_GRF("-----[ 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]);
@@ -2109,7 +2158,9 @@ static void transport_generic_request_failure(
 				cmd->orig_fe_lun, 0x2C,
 				ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
 
-		cmd->se_tfo->queue_status(cmd);
+		ret = cmd->se_tfo->queue_status(cmd);
+		if (ret == -EAGAIN)
+			goto queue_full;
 		goto check_stop;
 	case PYX_TRANSPORT_USE_SENSE_REASON:
 		/*
@@ -2126,13 +2177,22 @@ static void transport_generic_request_failure(
 
 	if (!sc)
 		transport_new_cmd_failure(cmd);
-	else
-		transport_send_check_condition_and_sense(cmd,
-			cmd->scsi_sense_reason, 0);
+	else {
+		ret = transport_send_check_condition_and_sense(cmd,
+				cmd->scsi_sense_reason, 0);
+		if (ret == -EAGAIN)
+			goto queue_full;
+	}
+
 check_stop:
 	transport_lun_remove_cmd(cmd);
 	if (!(transport_cmd_check_stop_to_fabric(cmd)))
 		;
+	return;
+
+queue_full:
+	cmd->t_state = TRANSPORT_COMPLETE_OK;
+	transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf);
 }
 
 static void transport_direct_request_timeout(struct se_cmd *cmd)
@@ -3637,9 +3697,53 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
 		wake_up_interruptible(&dev->dev_queue_obj.thread_wq);
 }
 
+static int transport_complete_qf(struct se_cmd *cmd)
+{
+	int ret = 0;
+
+	if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)
+		return cmd->se_tfo->queue_status(cmd);
+
+	switch (cmd->data_direction) {
+	case DMA_FROM_DEVICE:
+		ret = cmd->se_tfo->queue_data_in(cmd);
+		break;
+	case DMA_TO_DEVICE:
+		if (!list_empty(&cmd->t_mem_bidi_list)) {
+			ret = cmd->se_tfo->queue_data_in(cmd);
+			if (ret < 0)
+				return ret;
+		}
+		/* Fall through for DMA_TO_DEVICE */
+	case DMA_NONE:
+		ret = cmd->se_tfo->queue_status(cmd);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void transport_handle_queue_full(
+	struct se_cmd *cmd,
+	struct se_device *dev,
+	int (*qf_callback)(struct se_cmd *))
+{
+	spin_lock_irq(&dev->qf_cmd_lock);
+	cmd->se_cmd_flags |= SCF_EMULATE_QUEUE_FULL;
+	cmd->transport_qf_callback = qf_callback;
+	list_add_tail(&cmd->se_qf_node, &cmd->se_dev->qf_cmd_list);
+	atomic_inc(&dev->dev_qf_count);
+	smp_mb__after_atomic_inc();
+	spin_unlock_irq(&cmd->se_dev->qf_cmd_lock);
+
+	schedule_work(&cmd->se_dev->qf_work_queue);
+}
+
 static void transport_generic_complete_ok(struct se_cmd *cmd)
 {
-	int reason = 0;
+	int reason = 0, ret;
 	/*
 	 * Check if we need to move delayed/dormant tasks from cmds on the
 	 * delayed execution list after a HEAD_OF_QUEUE or ORDERED Task
@@ -3648,6 +3752,21 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
 	if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
 		transport_complete_task_attr(cmd);
 	/*
+	 * Check to schedule QUEUE_FULL work, or execute an existing
+	 * cmd->transport_qf_callback()
+	 */
+	if (atomic_read(&cmd->se_dev->dev_qf_count) != 0)
+		schedule_work(&cmd->se_dev->qf_work_queue);
+
+	if (cmd->transport_qf_callback) {
+		ret = cmd->transport_qf_callback(cmd);
+		if (ret < 0)
+			goto queue_full;
+
+		cmd->transport_qf_callback = NULL;
+		goto done;
+	}
+	/*
 	 * Check if we need to retrieve a sense buffer from
 	 * the struct se_cmd in question.
 	 */
@@ -3660,8 +3779,11 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
 		 * a non GOOD status.
 		 */
 		if (cmd->scsi_status) {
-			transport_send_check_condition_and_sense(
+			ret = transport_send_check_condition_and_sense(
 					cmd, reason, 1);
+			if (ret == -EAGAIN)
+				goto queue_full;
+
 			transport_lun_remove_cmd(cmd);
 			transport_cmd_check_stop_to_fabric(cmd);
 			return;
@@ -3693,7 +3815,9 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
 					    cmd->t_task_buf,
 					    cmd->data_length);
 
-		cmd->se_tfo->queue_data_in(cmd);
+		ret = cmd->se_tfo->queue_data_in(cmd);
+		if (ret == -EAGAIN)
+			goto queue_full;
 		break;
 	case DMA_TO_DEVICE:
 		spin_lock(&cmd->se_lun->lun_sep_lock);
@@ -3712,19 +3836,30 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
 					cmd->data_length;
 			}
 			spin_unlock(&cmd->se_lun->lun_sep_lock);
-			cmd->se_tfo->queue_data_in(cmd);
+			ret = cmd->se_tfo->queue_data_in(cmd);
+			if (ret == -EAGAIN)
+				goto queue_full;
 			break;
 		}
 		/* Fall through for DMA_TO_DEVICE */
 	case DMA_NONE:
-		cmd->se_tfo->queue_status(cmd);
+		ret = cmd->se_tfo->queue_status(cmd);
+		if (ret == -EAGAIN)
+			goto queue_full;
 		break;
 	default:
 		break;
 	}
 
+done:
 	transport_lun_remove_cmd(cmd);
 	transport_cmd_check_stop_to_fabric(cmd);
+	return;
+
+queue_full:
+	printk(KERN_INFO "Handling complete_ok QUEUE_FULL: se_cmd: %p,"
+		" data_direction: %d\n", cmd, cmd->data_direction);
+	transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf);
 }
 
 static void transport_free_dev_tasks(struct se_cmd *cmd)
@@ -4866,6 +5001,11 @@ void transport_generic_process_write(struct se_cmd *cmd)
 }
 EXPORT_SYMBOL(transport_generic_process_write);
 
+static int transport_write_pending_qf(struct se_cmd *cmd)
+{
+	return cmd->se_tfo->write_pending(cmd);
+}
+
 /*	transport_generic_write_pending():
  *
  *
@@ -4878,6 +5018,17 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
 	cmd->t_state = TRANSPORT_WRITE_PENDING;
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+	if (cmd->transport_qf_callback) {
+		ret = cmd->transport_qf_callback(cmd);
+		if (ret == -EAGAIN)
+			goto queue_full;
+		else if (ret < 0)
+			return ret;
+
+		cmd->transport_qf_callback = NULL;
+		return 0;
+	}
 	/*
 	 * For the TCM control CDBs using a contiguous buffer, do the memcpy
 	 * from the passed Linux/SCSI struct scatterlist located at
@@ -4903,10 +5054,19 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
 	 * frontend know that WRITE buffers are ready.
 	 */
 	ret = cmd->se_tfo->write_pending(cmd);
-	if (ret < 0)
+	if (ret == -EAGAIN)
+		goto queue_full;
+	else if (ret < 0)
 		return ret;
 
 	return PYX_TRANSPORT_WRITE_PENDING;
+
+queue_full:
+	printk(KERN_INFO "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,
+			transport_write_pending_qf);
+	return ret;
 }
 
 void transport_release_cmd(struct se_cmd *cmd)
@@ -5410,8 +5570,7 @@ int transport_send_check_condition_and_sense(
 	cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER + offset;
 
 after_reason:
-	cmd->se_tfo->queue_status(cmd);
-	return 0;
+	return cmd->se_tfo->queue_status(cmd);
 }
 EXPORT_SYMBOL(transport_send_check_condition_and_sense);
 
@@ -5733,7 +5892,9 @@ get_cmd:
 			/* Fall through */
 		case TRANSPORT_NEW_CMD:
 			ret = transport_generic_new_cmd(cmd);
-			if (ret < 0) {
+			if (ret == -EAGAIN)
+				break;
+			else if (ret < 0) {
 				cmd->transport_error_status = ret;
 				transport_generic_request_failure(cmd, NULL,
 					0, (cmd->data_direction !=
@@ -5763,6 +5924,9 @@ get_cmd:
 			transport_stop_all_task_timers(cmd);
 			transport_generic_request_timeout(cmd);
 			break;
+		case TRANSPORT_COMPLETE_QF_WP:
+			transport_generic_write_pending(cmd);
+			break;
 		default:
 			printk(KERN_ERR "Unknown t_state: %d deferred_t_state:"
 				" %d for ITT: 0x%08x i_state: %d on SE LUN:"
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 71abc4c..cd163dd 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -99,6 +99,7 @@ enum transport_state_table {
 	TRANSPORT_FREE		= 15,
 	TRANSPORT_NEW_CMD_MAP	= 16,
 	TRANSPORT_FREE_CMD_INTR = 17,
+	TRANSPORT_COMPLETE_QF_WP = 18,
 };
 
 /* Used for struct se_cmd->se_cmd_flags */
@@ -125,6 +126,7 @@ enum se_cmd_flags_table {
 	SCF_PASSTHROUGH_CONTIG_TO_SG	= 0x00200000,
 	SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
 	SCF_EMULATE_CDB_ASYNC		= 0x01000000,
+	SCF_EMULATE_QUEUE_FULL		= 0x02000000,
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -466,6 +468,7 @@ struct se_cmd {
 	struct list_head	se_delayed_node;
 	struct list_head	se_ordered_node;
 	struct list_head	se_lun_node;
+	struct list_head	se_qf_node;
 	struct se_device      *se_dev;
 	struct se_dev_entry   *se_deve;
 	struct se_device	*se_obj_ptr;
@@ -480,6 +483,8 @@ struct se_cmd {
 	void (*transport_split_cdb)(unsigned long long, u32 *, unsigned char *);
 	void (*transport_wait_for_tasks)(struct se_cmd *, int, int);
 	void (*transport_complete_callback)(struct se_cmd *);
+	int (*transport_qf_callback)(struct se_cmd *);
+
 	unsigned char		*t_task_cdb;
 	unsigned char		__t_task_cdb[TCM_MAX_COMMAND_SIZE];
 	unsigned long long	t_task_lba;
@@ -743,6 +748,7 @@ struct se_device {
 	atomic_t		dev_status_thr_count;
 	atomic_t		dev_hoq_count;
 	atomic_t		dev_ordered_sync;
+	atomic_t		dev_qf_count;
 	struct se_obj		dev_obj;
 	struct se_obj		dev_access_obj;
 	struct se_obj		dev_export_obj;
@@ -758,6 +764,7 @@ struct se_device {
 	spinlock_t		dev_status_thr_lock;
 	spinlock_t		se_port_lock;
 	spinlock_t		se_tmr_lock;
+	spinlock_t		qf_cmd_lock;
 	/* Used for legacy SPC-2 reservationsa */
 	struct se_node_acl	*dev_reserved_node_acl;
 	/* Used for ALUA Logical Unit Group membership */
@@ -771,10 +778,12 @@ struct se_device {
 	struct task_struct	*process_thread;
 	pid_t			process_thread_pid;
 	struct task_struct		*dev_mgmt_thread;
+	struct work_struct	qf_work_queue;
 	struct list_head	delayed_cmd_list;
 	struct list_head	ordered_cmd_list;
 	struct list_head	execute_task_list;
 	struct list_head	state_task_list;
+	struct list_head	qf_cmd_list;
 	/* Pointer to associated SE HBA */
 	struct se_hba		*se_hba;
 	struct se_subsystem_dev *se_sub_dev;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 075/103] target: Make transport_lookup_cmd_lun() locking IRQ-safe
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (11 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 074/103] target: Add SCF_EMULATE_QUEUE_FULL -> transport_handle_queue_full Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:11 ` [PATCH 076/103] target: Make se_dev_check_online() " Nicholas A. Bellinger
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

transport_lookup_cmd_lun() may be called from interrupt context (eg
tcm_loop_allocate_core_cmd() calls it, and it has a comment that says,
"Can be called from interrupt context"), so it needs to use
spin_lock_irqsave() instead of spin_lock_irq() to avoid enabling
interrupts at the wrong time.

(And indeed the last set of lock operations, on lun_cmd_lock, were
already using spin_lock_irqsave(), so we just need to fix the other
two locks we take)

Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_device.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index c674a5d..e25df3b 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -72,7 +72,7 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		return -ENODEV;
 	}
 
-	spin_lock_irq(&se_sess->se_node_acl->device_list_lock);
+	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;
@@ -88,7 +88,7 @@ int 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_irq(&se_sess->se_node_acl->device_list_lock);
+			spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags);
 			return -EACCES;
 		}
 
@@ -106,7 +106,7 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev;
 		se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
 	}
-	spin_unlock_irq(&se_sess->se_node_acl->device_list_lock);
+	spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags);
 
 	if (!se_lun) {
 		/*
@@ -154,13 +154,13 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 
 	/* TODO: get rid of this and use atomics for stats */
 	dev = se_lun->lun_se_dev;
-	spin_lock_irq(&dev->stats_lock);
+	spin_lock_irqsave(&dev->stats_lock, flags);
 	dev->num_cmds++;
 	if (se_cmd->data_direction == DMA_TO_DEVICE)
 		dev->write_bytes += se_cmd->data_length;
 	else if (se_cmd->data_direction == DMA_FROM_DEVICE)
 		dev->read_bytes += se_cmd->data_length;
-	spin_unlock_irq(&dev->stats_lock);
+	spin_unlock_irqrestore(&dev->stats_lock, flags);
 
 	/*
 	 * Add the iscsi_cmd_t to the struct se_lun's cmd list.  This list is used
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 076/103] target: Make se_dev_check_online() locking IRQ-safe
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (12 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 075/103] target: Make transport_lookup_cmd_lun() locking IRQ-safe Nicholas A. Bellinger
@ 2011-07-21  7:11 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 077/103] target/iblock: Use request_queue->nr_request for se_device defaults Nicholas A. Bellinger
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:11 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

se_dev_check_online() is called from transport_lookup_cmd_lun(), which
as discussed before may be called from interrupt context.  So it needs
to use spin_lock_irqsave() instead of spin_lock_irq() to avoid
enabling interrupts at the wrong time.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_device.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index e25df3b..6d93d96 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -813,12 +813,13 @@ static void se_dev_stop(struct se_device *dev)
 
 int se_dev_check_online(struct se_device *dev)
 {
+	unsigned long flags;
 	int ret;
 
-	spin_lock_irq(&dev->dev_status_lock);
+	spin_lock_irqsave(&dev->dev_status_lock, flags);
 	ret = ((dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) ||
 	       (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED)) ? 0 : 1;
-	spin_unlock_irq(&dev->dev_status_lock);
+	spin_unlock_irqrestore(&dev->dev_status_lock, flags);
 
 	return ret;
 }
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 077/103] target/iblock: Use request_queue->nr_request for se_device defaults
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (13 preceding siblings ...)
  2011-07-21  7:11 ` [PATCH 076/103] target: Make se_dev_check_online() " Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 078/103] loopback: Remove duplicate scsi/scsi_tcq.h include Nicholas A. Bellinger
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch converts iblock_create_virtdevice() to use request_queue->nr_request
for se_dev_limits usage of ->hw_queue_depth and ->queue_depth for individual
struct se_device export.

It also removes the now unused defines for IBLOCK_DEVICE_QUEUE_DEPTH and
IBLOCK_MAX_DEVICE_QUEUE_DEPTH

Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_iblock.c |    4 ++--
 drivers/target/target_core_iblock.h |    2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 814a85b..d43fc91 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -164,8 +164,8 @@ static struct se_device *iblock_create_virtdevice(
 	limits->logical_block_size = bdev_logical_block_size(bd);
 	limits->max_hw_sectors = queue_max_hw_sectors(q);
 	limits->max_sectors = queue_max_sectors(q);
-	dev_limits.hw_queue_depth = IBLOCK_MAX_DEVICE_QUEUE_DEPTH;
-	dev_limits.queue_depth = IBLOCK_DEVICE_QUEUE_DEPTH;
+	dev_limits.hw_queue_depth = q->nr_requests;
+	dev_limits.queue_depth = q->nr_requests;
 
 	ib_dev->ibd_major = MAJOR(bd->bd_dev);
 	ib_dev->ibd_minor = MINOR(bd->bd_dev);
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index 6b6d17b..a69b7c2 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -3,8 +3,6 @@
 
 #define IBLOCK_VERSION		"4.0"
 
-#define IBLOCK_DEVICE_QUEUE_DEPTH	32
-#define IBLOCK_MAX_DEVICE_QUEUE_DEPTH	128
 #define IBLOCK_MAX_CDBS		16
 #define IBLOCK_LBA_SHIFT	9
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 078/103] loopback: Remove duplicate scsi/scsi_tcq.h include
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (14 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 077/103] target/iblock: Use request_queue->nr_request for se_device defaults Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 079/103] target: Make se_tmr_lock IRQ-safe Nicholas A. Bellinger
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Jesper Juhl

From: Jesper Juhl <jj@chaosbits.net>

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 083d6c5..e53cec6 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -31,7 +31,6 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_tcq.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_transport.h>
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 079/103] target: Make se_tmr_lock IRQ-safe
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (15 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 078/103] loopback: Remove duplicate scsi/scsi_tcq.h include Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 080/103] loopback: Fix memory leak in tcm_loop_make_scsi_hba() Nicholas A. Bellinger
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

transport_lookup_tmr_lun() can be called from interrupt context and
therefore needs to use IRQ-safe spinlock functions.  Fix this up, and
to make the locking work, convert the other uses of se_tmr_lock to be
IRQ-disabling.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_device.c |    9 +++++----
 drivers/target/target_core_tmr.c    |   16 ++++++++--------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 6d93d96..f13e294 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -181,6 +181,7 @@ int transport_lookup_tmr_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_tmr_req *se_tmr = se_cmd->se_tmr_req;
+	unsigned long flags;
 
 	if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) {
 		se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN;
@@ -188,7 +189,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		return -ENODEV;
 	}
 
-	spin_lock_irq(&se_sess->se_node_acl->device_list_lock);
+	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;
 
@@ -200,7 +201,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		se_cmd->orig_fe_lun = unpacked_lun;
 		se_cmd->se_orig_obj_ptr = se_cmd->se_dev;
 	}
-	spin_unlock_irq(&se_sess->se_node_acl->device_list_lock);
+	spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags);
 
 	if (!se_lun) {
 		printk(KERN_INFO "TARGET_CORE[%s]: Detected NON_EXISTENT_LUN"
@@ -223,9 +224,9 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 	se_cmd->se_dev = se_lun->lun_se_dev;
 	se_tmr->tmr_dev = se_lun->lun_se_dev;
 
-	spin_lock(&se_tmr->tmr_dev->se_tmr_lock);
+	spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags);
 	list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list);
-	spin_unlock(&se_tmr->tmr_dev->se_tmr_lock);
+	spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags);
 
 	return 0;
 }
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 5c20de3..f1feea3 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -80,9 +80,9 @@ void core_tmr_release_req(
 		return;
 	}
 
-	spin_lock(&dev->se_tmr_lock);
+	spin_lock_irq(&dev->se_tmr_lock);
 	list_del(&tmr->tmr_list);
-	spin_unlock(&dev->se_tmr_lock);
+	spin_unlock_irq(&dev->se_tmr_lock);
 
 	kmem_cache_free(se_tmr_req_cache, tmr);
 }
@@ -154,7 +154,7 @@ int core_tmr_lun_reset(
 	 * Release all pending and outgoing TMRs aside from the received
 	 * LUN_RESET tmr..
 	 */
-	spin_lock(&dev->se_tmr_lock);
+	spin_lock_irq(&dev->se_tmr_lock);
 	list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) {
 		/*
 		 * Allow the received TMR to return with FUNCTION_COMPLETE.
@@ -176,17 +176,17 @@ int core_tmr_lun_reset(
 		    (core_scsi3_check_cdb_abort_and_preempt(
 					preempt_and_abort_list, cmd) != 0))
 			continue;
-		spin_unlock(&dev->se_tmr_lock);
+		spin_unlock_irq(&dev->se_tmr_lock);
 
 		spin_lock_irqsave(&cmd->t_state_lock, flags);
 		if (!(atomic_read(&cmd->t_transport_active))) {
 			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-			spin_lock(&dev->se_tmr_lock);
+			spin_lock_irq(&dev->se_tmr_lock);
 			continue;
 		}
 		if (cmd->t_state == TRANSPORT_ISTATE_PROCESSING) {
 			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-			spin_lock(&dev->se_tmr_lock);
+			spin_lock_irq(&dev->se_tmr_lock);
 			continue;
 		}
 		DEBUG_LR("LUN_RESET: %s releasing TMR %p Function: 0x%02x,"
@@ -196,9 +196,9 @@ int core_tmr_lun_reset(
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 		transport_cmd_finish_abort_tmr(cmd);
-		spin_lock(&dev->se_tmr_lock);
+		spin_lock_irq(&dev->se_tmr_lock);
 	}
-	spin_unlock(&dev->se_tmr_lock);
+	spin_unlock_irq(&dev->se_tmr_lock);
 	/*
 	 * Complete outstanding struct se_task CDBs with TASK_ABORTED SAM status.
 	 * This is following sam4r17, section 5.6 Aborting commands, Table 38
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 080/103] loopback: Fix memory leak in tcm_loop_make_scsi_hba()
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (16 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 079/103] target: Make se_tmr_lock IRQ-safe Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 081/103] target/iblock: Remove unused iblock_dev members Nicholas A. Bellinger
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Jesper Juhl

From: Jesper Juhl <jj@chaosbits.net>

There is a memory leak in tcm_loop_make_scsi_hba().

If all the strstr() calls return NULL and we end up at return ERR_PTR(-EINVAL);
then we'll be leaking the memory previously allocated to tl_hba as
that variable goes out of scope.

This patch should fix the leak.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index e53cec6..fe11a33 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -1288,22 +1288,21 @@ struct se_wwn *tcm_loop_make_scsi_hba(
 		goto check_len;
 	}
 	ptr = strstr(name, "iqn.");
-	if (ptr) {
-		tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
-		goto check_len;
+	if (!ptr) {
+		printk(KERN_ERR "Unable to locate prefix for emulated Target "
+				"Port: %s\n", name);
+		ret = -EINVAL;
+		goto out;
 	}
-
-	printk(KERN_ERR "Unable to locate prefix for emulated Target Port:"
-			" %s\n", name);
-	return ERR_PTR(-EINVAL);
+	tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
 
 check_len:
 	if (strlen(name) >= TL_WWN_ADDR_LEN) {
 		printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
 			" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
 			TL_WWN_ADDR_LEN);
-		kfree(tl_hba);
-		return ERR_PTR(-EINVAL);
+		ret = -EINVAL;
+		goto out;
 	}
 	snprintf(&tl_hba->tl_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 081/103] target/iblock: Remove unused iblock_dev members
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (17 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 080/103] loopback: Fix memory leak in tcm_loop_make_scsi_hba() Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 082/103] target: Allow for built-in target modules Nicholas A. Bellinger
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

ibd_depth and ibd_force are used write-only.  Remove them.
ibd_major/minor can be easily retrieved from ibd_bd, so get
rid of them too.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_iblock.c |   17 +++--------------
 drivers/target/target_core_iblock.h |    5 -----
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index d43fc91..160c484 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -167,8 +167,6 @@ static struct se_device *iblock_create_virtdevice(
 	dev_limits.hw_queue_depth = q->nr_requests;
 	dev_limits.queue_depth = q->nr_requests;
 
-	ib_dev->ibd_major = MAJOR(bd->bd_dev);
-	ib_dev->ibd_minor = MINOR(bd->bd_dev);
 	ib_dev->ibd_bd = bd;
 
 	dev = transport_add_device_to_core_hba(hba,
@@ -177,8 +175,6 @@ static struct se_device *iblock_create_virtdevice(
 	if (!(dev))
 		goto failed;
 
-	ib_dev->ibd_depth = dev->queue_depth;
-
 	/*
 	 * Check if the underlying struct block_device request_queue supports
 	 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
@@ -208,8 +204,6 @@ failed:
 		ib_dev->ibd_bio_set = NULL;
 	}
 	ib_dev->ibd_bd = NULL;
-	ib_dev->ibd_major = 0;
-	ib_dev->ibd_minor = 0;
 	return ERR_PTR(ret);
 }
 
@@ -467,7 +461,7 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
 	struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr;
 	char *orig, *ptr, *arg_p, *opts;
 	substring_t args[MAX_OPT_ARGS];
-	int ret = 0, arg, token;
+	int ret = 0, token;
 
 	opts = kstrdup(page, GFP_KERNEL);
 	if (!opts)
@@ -501,10 +495,6 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
 			ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
 			break;
 		case Opt_force:
-			match_int(args, &arg);
-			ib_dev->ibd_force = arg;
-			printk(KERN_INFO "IBLOCK: Set force=%d\n",
-				ib_dev->ibd_force);
 			break;
 		default:
 			break;
@@ -552,12 +542,11 @@ static ssize_t iblock_show_configfs_dev_params(
 	bl += sprintf(b + bl, "        ");
 	if (bd) {
 		bl += sprintf(b + bl, "Major: %d Minor: %d  %s\n",
-			ibd->ibd_major, ibd->ibd_minor, (!bd->bd_contains) ?
+			MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ?
 			"" : (bd->bd_holder == (struct iblock_dev *)ibd) ?
 			"CLAIMED: IBLOCK" : "CLAIMED: OS");
 	} else {
-		bl += sprintf(b + bl, "Major: %d Minor: %d\n",
-			ibd->ibd_major, ibd->ibd_minor);
+		bl += sprintf(b + bl, "Major: 0 Minor: 0\n");
 	}
 
 	return bl;
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index a69b7c2..2aa1d27 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -16,14 +16,9 @@ struct iblock_req {
 } ____cacheline_aligned;
 
 #define IBDF_HAS_UDEV_PATH		0x01
-#define IBDF_HAS_FORCE			0x02
 
 struct iblock_dev {
 	unsigned char ibd_udev_path[SE_UDEV_PATH_LEN];
-	int	ibd_force;
-	int	ibd_major;
-	int	ibd_minor;
-	u32	ibd_depth;
 	u32	ibd_flags;
 	struct bio_set	*ibd_bio_set;
 	struct block_device *ibd_bd;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 082/103] target: Allow for built-in target modules
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (18 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 081/103] target/iblock: Remove unused iblock_dev members Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 083/103] target: Fix reporting of supported VPD pages Nicholas A. Bellinger
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

In target_fabric_configfs_init(), we should allow fabric_mod to be NULL,
since THIS_MODULE is NULL for built-in modules.  The main method of
using the target code may be as modules, but having everything built-in
is useful eg to be able to do quick testing with "qemu -kernel".

In any case, we shouldn't bomb out fabric registration for a perfectly
valid configuration, so simply drop the check of fabric_mod.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_configfs.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 63cba1e..8d2aba5 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -306,10 +306,6 @@ struct target_fabric_configfs *target_fabric_configfs_init(
 {
 	struct target_fabric_configfs *tf;
 
-	if (!(fabric_mod)) {
-		printk(KERN_ERR "Missing struct module *fabric_mod pointer\n");
-		return ERR_PTR(-EINVAL);
-	}
 	if (!(name)) {
 		printk(KERN_ERR "Unable to locate passed fabric name\n");
 		return ERR_PTR(-EINVAL);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 083/103] target: Fix reporting of supported VPD pages
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (19 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 082/103] target: Allow for built-in target modules Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 084/103] target: Implement Block Device Characteristics VPD page Nicholas A. Bellinger
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

The current handling of VPD page 00h (Supported VPD Pages) for INQUIRY
commands has a couple of problems:

 - The page length field is incorrectly set to 3, so the entry for 86h
   (Extended INQUIRY Data) is ignored since it is in the fourth slot.
 - Even though the code handles pages B0h and B2h, those pages aren't
   mentioned in the Supported VPD Pages list, so eg the Linux SCSI stack
   won't actually try to use them.

Fix these problems and make things more robust to avoid future problems
by moving to a table of supported VPD pages, which means that any added
VPD page support will automatically get reported on page 0.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_cdb.c |   95 +++++++++++++++++++-------------------
 1 files changed, 47 insertions(+), 48 deletions(-)

diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 09ef3f8..1157e0c 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -114,31 +114,6 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 	return 0;
 }
 
-/* supported vital product data pages */
-static int
-target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
-{
-	buf[1] = 0x00;
-	if (cmd->data_length < 8)
-		return 0;
-
-	buf[4] = 0x0;
-	/*
-	 * Only report the INQUIRY EVPD=1 pages after a valid NAA
-	 * Registered Extended LUN WWN has been set via ConfigFS
-	 * during device creation/restart.
-	 */
-	if (cmd->se_dev->se_sub_dev->su_dev_flags &
-			SDF_EMULATED_VPD_UNIT_SERIAL) {
-		buf[3] = 3;
-		buf[5] = 0x80;
-		buf[6] = 0x83;
-		buf[7] = 0x86;
-	}
-
-	return 0;
-}
-
 /* unit serial number */
 static int
 target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
@@ -146,7 +121,6 @@ target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
 	struct se_device *dev = cmd->se_dev;
 	u16 len = 0;
 
-	buf[1] = 0x80;
 	if (dev->se_sub_dev->su_dev_flags &
 			SDF_EMULATED_VPD_UNIT_SERIAL) {
 		u32 unit_serial_len;
@@ -190,7 +164,6 @@ target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
 	int i;
 	u16 len = 0, id_len;
 
-	buf[1] = 0x83;
 	off = 4;
 
 	/*
@@ -471,7 +444,6 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
 	if (cmd->data_length < 60)
 		return 0;
 
-	buf[1] = 0x86;
 	buf[2] = 0x3c;
 	/* Set HEADSUP, ORDSUP, SIMPSUP */
 	buf[5] = 0x07;
@@ -512,7 +484,6 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 	}
 
 	buf[0] = dev->transport->get_device_type(dev);
-	buf[1] = 0xb0;
 	buf[3] = have_tp ? 0x3c : 0x10;
 
 	/*
@@ -579,7 +550,6 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
 	 * defined in table 162.
 	 */
 	buf[0] = dev->transport->get_device_type(dev);
-	buf[1] = 0xb2;
 
 	/*
 	 * Set Hardcoded length mentioned above for DP=0
@@ -618,11 +588,51 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
 }
 
 static int
+target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf);
+
+static struct {
+	uint8_t		page;
+	int		(*emulate)(struct se_cmd *, unsigned char *);
+} evpd_handlers[] = {
+	{ .page = 0x00, .emulate = target_emulate_evpd_00 },
+	{ .page = 0x80, .emulate = target_emulate_evpd_80 },
+	{ .page = 0x83, .emulate = target_emulate_evpd_83 },
+	{ .page = 0x86, .emulate = target_emulate_evpd_86 },
+	{ .page = 0xb0, .emulate = target_emulate_evpd_b0 },
+	{ .page = 0xb2, .emulate = target_emulate_evpd_b2 },
+};
+
+/* supported vital product data pages */
+static int
+target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
+{
+	int p;
+
+	if (cmd->data_length < 8)
+		return 0;
+	/*
+	 * Only report the INQUIRY EVPD=1 pages after a valid NAA
+	 * Registered Extended LUN WWN has been set via ConfigFS
+	 * during device creation/restart.
+	 */
+	if (cmd->se_dev->se_sub_dev->su_dev_flags &
+			SDF_EMULATED_VPD_UNIT_SERIAL) {
+		buf[3] = ARRAY_SIZE(evpd_handlers);
+		for (p = 0; p < min_t(int, ARRAY_SIZE(evpd_handlers),
+				      cmd->data_length - 4); ++p)
+			buf[p + 4] = evpd_handlers[p].page;
+	}
+
+	return 0;
+}
+
+static int
 target_emulate_inquiry(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
 	unsigned char *buf = cmd->t_task_buf;
 	unsigned char *cdb = cmd->t_task_cdb;
+	int p;
 
 	if (!(cdb[1] & 0x1))
 		return target_emulate_inquiry_std(cmd);
@@ -641,25 +651,14 @@ target_emulate_inquiry(struct se_cmd *cmd)
 	}
 	buf[0] = dev->transport->get_device_type(dev);
 
-	switch (cdb[2]) {
-	case 0x00:
-		return target_emulate_evpd_00(cmd, buf);
-	case 0x80:
-		return target_emulate_evpd_80(cmd, buf);
-	case 0x83:
-		return target_emulate_evpd_83(cmd, buf);
-	case 0x86:
-		return target_emulate_evpd_86(cmd, buf);
-	case 0xb0:
-		return target_emulate_evpd_b0(cmd, buf);
-	case 0xb2:
-		return target_emulate_evpd_b2(cmd, buf);
-	default:
-		printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
-		return -EINVAL;
-	}
+	for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p)
+		if (cdb[2] == evpd_handlers[p].page) {
+			buf[1] = cdb[2];
+			return evpd_handlers[p].emulate(cmd, buf);
+		}
 
-	return 0;
+	printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
+	return -EINVAL;
 }
 
 static int
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 084/103] target: Implement Block Device Characteristics VPD page
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (20 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 083/103] target: Fix reporting of supported VPD pages Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 085/103] target: Remove ifdeffed code in t_g_process_write Nicholas A. Bellinger
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Roland Dreier

From: Roland Dreier <roland@purestorage.com>

Implement page B1h, Block Device Characteristics, so that we can report
a medium rotation rate of 1 (non-rotating / solid state) if the
is_nonrot device attribute is set; we update the iblock backend to set
this attribute if the underlying Linux block device has its nonrot
flag set.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_cdb.c       |   17 +++++++++++++++++
 drivers/target/target_core_configfs.c  |    4 ++++
 drivers/target/target_core_device.c    |   13 +++++++++++++
 drivers/target/target_core_iblock.c    |    3 +++
 include/target/target_core_base.h      |    1 +
 include/target/target_core_device.h    |    1 +
 include/target/target_core_transport.h |    2 ++
 7 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 1157e0c..4322530 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -535,6 +535,22 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 	return 0;
 }
 
+/* Block Device Characteristics VPD page */
+static int
+target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
+{
+	struct se_device *dev = cmd->se_dev;
+
+	buf[0] = dev->transport->get_device_type(dev);
+	buf[3] = 0x3c;
+
+	if (cmd->data_length >= 5 &&
+	    dev->se_sub_dev->se_dev_attrib.is_nonrot)
+		buf[5] = 1;
+
+	return 0;
+}
+
 /* Thin Provisioning VPD */
 static int
 target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
@@ -599,6 +615,7 @@ static struct {
 	{ .page = 0x83, .emulate = target_emulate_evpd_83 },
 	{ .page = 0x86, .emulate = target_emulate_evpd_86 },
 	{ .page = 0xb0, .emulate = target_emulate_evpd_b0 },
+	{ .page = 0xb1, .emulate = target_emulate_evpd_b1 },
 	{ .page = 0xb2, .emulate = target_emulate_evpd_b2 },
 };
 
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 8d2aba5..6b00810 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -698,6 +698,9 @@ SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR);
 DEF_DEV_ATTRIB(enforce_pr_isids);
 SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);
 
+DEF_DEV_ATTRIB(is_nonrot);
+SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);
+
 DEF_DEV_ATTRIB_RO(hw_block_size);
 SE_DEV_ATTR_RO(hw_block_size);
 
@@ -746,6 +749,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
 	&target_core_dev_attrib_emulate_tpu.attr,
 	&target_core_dev_attrib_emulate_tpws.attr,
 	&target_core_dev_attrib_enforce_pr_isids.attr,
+	&target_core_dev_attrib_is_nonrot.attr,
 	&target_core_dev_attrib_hw_block_size.attr,
 	&target_core_dev_attrib_block_size.attr,
 	&target_core_dev_attrib_hw_max_sectors.attr,
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index f13e294..440e6b6 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -853,6 +853,7 @@ void se_dev_set_default_attribs(
 	dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
 	dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
 	dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
+	dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
 	/*
 	 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
 	 * iblock_create_virtdevice() from struct queue_limits values
@@ -1117,6 +1118,18 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag)
 	return 0;
 }
 
+int se_dev_set_is_nonrot(struct se_device *dev, int flag)
+{
+	if ((flag != 0) && (flag != 1)) {
+		printk(KERN_ERR "Illegal value %d\n", flag);
+		return -EINVAL;
+	}
+	dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
+	printk(KERN_INFO "dev[%p]: SE Device is_nonrot bit: %d\n",
+	       dev, flag);
+	return 0;
+}
+
 /*
  * Note, this can only be called on unexported SE Device Object.
  */
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 160c484..392e75f 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -196,6 +196,9 @@ static struct se_device *iblock_create_virtdevice(
 				" disabled by default\n");
 	}
 
+	if (blk_queue_nonrot(q))
+		dev->se_sub_dev->se_dev_attrib.is_nonrot = 1;
+
 	return dev;
 
 failed:
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index cd163dd..81deb39 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -661,6 +661,7 @@ struct se_dev_attrib {
 	int		emulate_reservations;
 	int		emulate_alua;
 	int		enforce_pr_isids;
+	int		is_nonrot;
 	u32		hw_block_size;
 	u32		block_size;
 	u32		hw_max_sectors;
diff --git a/include/target/target_core_device.h b/include/target/target_core_device.h
index 96586cc..f3b6ae6 100644
--- a/include/target/target_core_device.h
+++ b/include/target/target_core_device.h
@@ -39,6 +39,7 @@ extern int se_dev_set_emulate_tas(struct se_device *, int);
 extern int se_dev_set_emulate_tpu(struct se_device *, int);
 extern int se_dev_set_emulate_tpws(struct se_device *, int);
 extern int se_dev_set_enforce_pr_isids(struct se_device *, int);
+extern int se_dev_set_is_nonrot(struct se_device *, int);
 extern int se_dev_set_queue_depth(struct se_device *, u32);
 extern int se_dev_set_max_sectors(struct se_device *, u32);
 extern int se_dev_set_optimal_sectors(struct se_device *, u32);
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 2aae764..b27ce1a 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -101,6 +101,8 @@
 #define DA_ENFORCE_PR_ISIDS			1
 #define DA_STATUS_MAX_SECTORS_MIN		16
 #define DA_STATUS_MAX_SECTORS_MAX		8192
+/* By default don't report non-rotating (solid state) medium */
+#define DA_IS_NONROT				0
 
 #define SE_MODE_PAGE_BUF			512
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 085/103] target: Remove ifdeffed code in t_g_process_write
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (21 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 084/103] target: Implement Block Device Characteristics VPD page Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 086/103] target: Pass 2nd param of transport_split_cdb by value Nicholas A. Bellinger
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |   58 --------------------------------
 1 files changed, 0 insertions(+), 58 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 056c4cb..e0be171 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4939,64 +4939,6 @@ EXPORT_SYMBOL(transport_generic_new_cmd);
  */
 void transport_generic_process_write(struct se_cmd *cmd)
 {
-#if 0
-	/*
-	 * Copy SCSI Presented DTL sector(s) from received buffers allocated to
-	 * original EDTL
-	 */
-	if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
-		if (!cmd->t_tasks_se_num) {
-			unsigned char *dst, *buf =
-				(unsigned char *)cmd->t_task_buf;
-
-			dst = kzalloc(cmd->cmd_spdtl), GFP_KERNEL);
-			if (!(dst)) {
-				printk(KERN_ERR "Unable to allocate memory for"
-						" WRITE underflow\n");
-				transport_generic_request_failure(cmd, NULL,
-					PYX_TRANSPORT_REQ_TOO_MANY_SECTORS, 1);
-				return;
-			}
-			memcpy(dst, buf, cmd->cmd_spdtl);
-
-			kfree(cmd->t_task_buf);
-			cmd->t_task_buf = dst;
-		} else {
-			struct scatterlist *sg =
-				(struct scatterlist *sg)cmd->t_task_buf;
-			struct scatterlist *orig_sg;
-
-			orig_sg = kzalloc(sizeof(struct scatterlist) *
-					cmd->t_tasks_se_num,
-					GFP_KERNEL))) {
-			if (!(orig_sg)) {
-				printk(KERN_ERR "Unable to allocate memory"
-						" for WRITE underflow\n");
-				transport_generic_request_failure(cmd, NULL,
-					PYX_TRANSPORT_REQ_TOO_MANY_SECTORS, 1);
-				return;
-			}
-
-			memcpy(orig_sg, cmd->t_task_buf,
-					sizeof(struct scatterlist) *
-					cmd->t_tasks_se_num);
-
-			cmd->data_length = cmd->cmd_spdtl;
-			/*
-			 * FIXME, clear out original struct se_task and state
-			 * information.
-			 */
-			if (transport_generic_new_cmd(cmd) < 0) {
-				transport_generic_request_failure(cmd, NULL,
-					PYX_TRANSPORT_REQ_TOO_MANY_SECTORS, 1);
-				kfree(orig_sg);
-				return;
-			}
-
-			transport_memcpy_write_sg(cmd, orig_sg);
-		}
-	}
-#endif
 	transport_execute_tasks(cmd);
 }
 EXPORT_SYMBOL(transport_generic_process_write);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 086/103] target: Pass 2nd param of transport_split_cdb by value
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (22 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 085/103] target: Remove ifdeffed code in t_g_process_write Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 087/103] target: Make all control CDBs scatter-gather Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 088/103] target: Enforce 1 page max for control cdb buffer sizes Nicholas A. Bellinger
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

Since sectors is not modified, it's more straightforward to do this.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_scdb.c      |   20 ++++++++++----------
 drivers/target/target_core_scdb.h      |   10 +++++-----
 drivers/target/target_core_transport.c |    3 +--
 include/target/target_core_base.h      |    2 +-
 4 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/target/target_core_scdb.c b/drivers/target/target_core_scdb.c
index dc6fed0..7284344 100644
--- a/drivers/target/target_core_scdb.c
+++ b/drivers/target/target_core_scdb.c
@@ -42,13 +42,13 @@
  */
 void split_cdb_XX_6(
 	unsigned long long lba,
-	u32 *sectors,
+	u32 sectors,
 	unsigned char *cdb)
 {
 	cdb[1] = (lba >> 16) & 0x1f;
 	cdb[2] = (lba >> 8) & 0xff;
 	cdb[3] = lba & 0xff;
-	cdb[4] = *sectors & 0xff;
+	cdb[4] = sectors & 0xff;
 }
 
 /*	split_cdb_XX_10():
@@ -57,11 +57,11 @@ void split_cdb_XX_6(
  */
 void split_cdb_XX_10(
 	unsigned long long lba,
-	u32 *sectors,
+	u32 sectors,
 	unsigned char *cdb)
 {
 	put_unaligned_be32(lba, &cdb[2]);
-	put_unaligned_be16(*sectors, &cdb[7]);
+	put_unaligned_be16(sectors, &cdb[7]);
 }
 
 /*	split_cdb_XX_12():
@@ -70,11 +70,11 @@ void split_cdb_XX_10(
  */
 void split_cdb_XX_12(
 	unsigned long long lba,
-	u32 *sectors,
+	u32 sectors,
 	unsigned char *cdb)
 {
 	put_unaligned_be32(lba, &cdb[2]);
-	put_unaligned_be32(*sectors, &cdb[6]);
+	put_unaligned_be32(sectors, &cdb[6]);
 }
 
 /*	split_cdb_XX_16():
@@ -83,11 +83,11 @@ void split_cdb_XX_12(
  */
 void split_cdb_XX_16(
 	unsigned long long lba,
-	u32 *sectors,
+	u32 sectors,
 	unsigned char *cdb)
 {
 	put_unaligned_be64(lba, &cdb[2]);
-	put_unaligned_be32(*sectors, &cdb[10]);
+	put_unaligned_be32(sectors, &cdb[10]);
 }
 
 /*
@@ -97,9 +97,9 @@ void split_cdb_XX_16(
  */
 void split_cdb_XX_32(
 	unsigned long long lba,
-	u32 *sectors,
+	u32 sectors,
 	unsigned char *cdb)
 {
 	put_unaligned_be64(lba, &cdb[12]);
-	put_unaligned_be32(*sectors, &cdb[28]);
+	put_unaligned_be32(sectors, &cdb[28]);
 }
diff --git a/drivers/target/target_core_scdb.h b/drivers/target/target_core_scdb.h
index 98cd1c0..48e9ccc 100644
--- a/drivers/target/target_core_scdb.h
+++ b/drivers/target/target_core_scdb.h
@@ -1,10 +1,10 @@
 #ifndef TARGET_CORE_SCDB_H
 #define TARGET_CORE_SCDB_H
 
-extern void split_cdb_XX_6(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_XX_10(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_XX_12(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_XX_16(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_XX_32(unsigned long long, u32 *, unsigned char *);
+extern void split_cdb_XX_6(unsigned long long, u32, unsigned char *);
+extern void split_cdb_XX_10(unsigned long long, u32, unsigned char *);
+extern void split_cdb_XX_12(unsigned long long, u32, unsigned char *);
+extern void split_cdb_XX_16(unsigned long long, u32, unsigned char *);
+extern void split_cdb_XX_32(unsigned long long, u32, unsigned char *);
 
 #endif /* TARGET_CORE_SCDB_H */
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index e0be171..ca8307e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4756,8 +4756,7 @@ static u32 transport_allocate_tasks(
 		       scsi_command_size(cmd->t_task_cdb));
 
 		/* Update new cdb with updated lba/sectors */
-		cmd->transport_split_cdb(task->task_lba,
-					 &task->task_sectors, cdb);
+		cmd->transport_split_cdb(task->task_lba, task->task_sectors, cdb);
 
 		/*
 		 * Perform the SE OBJ plugin and/or Transport plugin specific
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 81deb39..df354b9 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -480,7 +480,7 @@ struct se_cmd {
 	struct list_head	se_queue_node;
 	struct target_core_fabric_ops *se_tfo;
 	int (*transport_emulate_cdb)(struct se_cmd *);
-	void (*transport_split_cdb)(unsigned long long, u32 *, unsigned char *);
+	void (*transport_split_cdb)(unsigned long long, u32, unsigned char *);
 	void (*transport_wait_for_tasks)(struct se_cmd *, int, int);
 	void (*transport_complete_callback)(struct se_cmd *);
 	int (*transport_qf_callback)(struct se_cmd *);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 087/103] target: Make all control CDBs scatter-gather
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (23 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 086/103] target: Pass 2nd param of transport_split_cdb by value Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  2011-07-21  7:12 ` [PATCH 088/103] target: Enforce 1 page max for control cdb buffer sizes Nicholas A. Bellinger
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

Previously, some control CDBs did not allocate memory in pages for their
data buffer, but just did a kmalloc. This patch makes all cdbs allocate
pages.

This has the benefit of streamlining some paths that had to behave
differently when we used two allocation methods. The downside is that
all accesses to the data buffer need to kmap it before use, and need to
handle data in page-sized chunks if more than a page is needed for a given
command's data buffer.

Finally, note that cdbs with no data buffers are handled a little
differently. Before, SCSI_NON_DATA_CDBs would not call get_mem at all
(they'd be in the final else in transport_allocate_resources) but now
these will make it into generic_get_mem, but just not allocate any
buffers.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_alua.c      |   42 ++++++--
 drivers/target/target_core_cdb.c       |   69 +++++++++++---
 drivers/target/target_core_device.c    |    5 +-
 drivers/target/target_core_pr.c        |   60 ++++++++++--
 drivers/target/target_core_pscsi.c     |   32 +------
 drivers/target/target_core_transport.c |  159 +++++++++++---------------------
 drivers/target/tcm_fc/tfc_cmd.c        |    4 +-
 drivers/target/tcm_fc/tfc_io.c         |   61 ++++---------
 include/target/target_core_base.h      |    5 +-
 include/target/target_core_transport.h |    6 +-
 10 files changed, 218 insertions(+), 225 deletions(-)

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 76d506f..dba412f 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -65,10 +65,12 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd)
 	struct se_port *port;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u32 rd_len = 0, off = 4; /* Skip over RESERVED area to first
 				    Target port group descriptor */
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
 	list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
 			tg_pt_gp_list) {
@@ -141,6 +143,8 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd)
 	buf[2] = ((rd_len >> 8) & 0xff);
 	buf[3] = (rd_len & 0xff);
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -157,14 +161,17 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 	struct se_node_acl *nacl = cmd->se_sess->se_node_acl;
 	struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
-	unsigned char *ptr = &buf[4]; /* Skip over RESERVED area in header */
+	unsigned char *buf;
+	unsigned char *ptr;
 	u32 len = 4; /* Skip over RESERVED area in header */
 	int alua_access_state, primary = 0, rc;
 	u16 tg_pt_id, rtpi;
 
 	if (!(l_port))
 		return PYX_TRANSPORT_LU_COMM_FAILURE;
+
+	buf = transport_kmap_first_data_page(cmd);
+
 	/*
 	 * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed
 	 * for the local tg_pt_gp.
@@ -172,14 +179,16 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 	l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
 	if (!(l_tg_pt_gp_mem)) {
 		printk(KERN_ERR "Unable to access l_port->sep_alua_tg_pt_gp_mem\n");
-		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		goto out;
 	}
 	spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
 	l_tg_pt_gp = l_tg_pt_gp_mem->tg_pt_gp;
 	if (!(l_tg_pt_gp)) {
 		spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
 		printk(KERN_ERR "Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n");
-		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		goto out;
 	}
 	rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA);
 	spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -187,9 +196,12 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 	if (!(rc)) {
 		printk(KERN_INFO "Unable to process SET_TARGET_PORT_GROUPS"
 				" while TPGS_EXPLICT_ALUA is disabled\n");
-		return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+		goto out;
 	}
 
+	ptr = &buf[4]; /* Skip over RESERVED area in header */
+
 	while (len < cmd->data_length) {
 		alua_access_state = (ptr[0] & 0x0f);
 		/*
@@ -209,7 +221,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 			 * REQUEST, and the additional sense code set to INVALID
 			 * FIELD IN PARAMETER LIST.
 			 */
-			return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+			rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+			goto out;
 		}
 		rc = -1;
 		/*
@@ -260,8 +273,10 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 			 * If not matching target port group ID can be located
 			 * throw an exception with ASCQ: INVALID_PARAMETER_LIST
 			 */
-			if (rc != 0)
-				return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+			if (rc != 0) {
+				rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+				goto out;
+			}
 		} else {
 			/*
 			 * Extact the RELATIVE TARGET PORT IDENTIFIER to identify
@@ -295,14 +310,19 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 			 * be located, throw an exception with ASCQ:
 			 * INVALID_PARAMETER_LIST
 			 */
-			if (rc != 0)
-				return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+			if (rc != 0) {
+				rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+				goto out;
+			}
 		}
 
 		ptr += 4;
 		len += 4;
 	}
 
+out:
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 4322530..418282d 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -66,7 +66,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 {
 	struct se_lun *lun = cmd->se_lun;
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf = cmd->t_task_buf;
+	unsigned char *buf;
 
 	/*
 	 * Make sure we at least have 6 bytes of INQUIRY response
@@ -78,6 +78,8 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 		return -EINVAL;
 	}
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = dev->transport->get_device_type(dev);
 	if (buf[0] == TYPE_TAPE)
 		buf[1] = 0x80;
@@ -91,7 +93,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 
 	if (cmd->data_length < 8) {
 		buf[4] = 1; /* Set additional length to 1 */
-		return 0;
+		goto out;
 	}
 
 	buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
@@ -102,7 +104,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 	 */
 	if (cmd->data_length < 36) {
 		buf[4] = 3; /* Set additional length to 3 */
-		return 0;
+		goto out;
 	}
 
 	snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
@@ -111,6 +113,9 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
 	snprintf((unsigned char *)&buf[32], 4, "%s",
 		 &dev->se_sub_dev->t10_wwn.revision[0]);
 	buf[4] = 31; /* Set additional length to 31 */
+
+out:
+	transport_kunmap_first_data_page(cmd);
 	return 0;
 }
 
@@ -647,9 +652,9 @@ static int
 target_emulate_inquiry(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf = cmd->t_task_buf;
+	unsigned char *buf;
 	unsigned char *cdb = cmd->t_task_cdb;
-	int p;
+	int p, ret;
 
 	if (!(cdb[1] & 0x1))
 		return target_emulate_inquiry_std(cmd);
@@ -666,14 +671,20 @@ target_emulate_inquiry(struct se_cmd *cmd)
 			" too small for EVPD=1\n", cmd->data_length);
 		return -EINVAL;
 	}
+
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = dev->transport->get_device_type(dev);
 
 	for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p)
 		if (cdb[2] == evpd_handlers[p].page) {
 			buf[1] = cdb[2];
-			return evpd_handlers[p].emulate(cmd, buf);
+			ret = evpd_handlers[p].emulate(cmd, buf);
+			transport_kunmap_first_data_page(cmd);
+			return ret;
 		}
 
+	transport_kunmap_first_data_page(cmd);
 	printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
 	return -EINVAL;
 }
@@ -682,7 +693,7 @@ static int
 target_emulate_readcapacity(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf = cmd->t_task_buf;
+	unsigned char *buf;
 	unsigned long long blocks_long = dev->transport->get_blocks(dev);
 	u32 blocks;
 
@@ -691,6 +702,8 @@ target_emulate_readcapacity(struct se_cmd *cmd)
 	else
 		blocks = (u32)blocks_long;
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = (blocks >> 24) & 0xff;
 	buf[1] = (blocks >> 16) & 0xff;
 	buf[2] = (blocks >> 8) & 0xff;
@@ -705,6 +718,8 @@ target_emulate_readcapacity(struct se_cmd *cmd)
 	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
 		put_unaligned_be32(0xFFFFFFFF, &buf[0]);
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -712,9 +727,11 @@ static int
 target_emulate_readcapacity_16(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf = cmd->t_task_buf;
+	unsigned char *buf;
 	unsigned long long blocks = dev->transport->get_blocks(dev);
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = (blocks >> 56) & 0xff;
 	buf[1] = (blocks >> 48) & 0xff;
 	buf[2] = (blocks >> 40) & 0xff;
@@ -734,6 +751,8 @@ target_emulate_readcapacity_16(struct se_cmd *cmd)
 	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
 		buf[14] = 0x80;
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -848,7 +867,7 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
 {
 	struct se_device *dev = cmd->se_dev;
 	char *cdb = cmd->t_task_cdb;
-	unsigned char *rbuf = cmd->t_task_buf;
+	unsigned char *rbuf;
 	int type = dev->transport->get_device_type(dev);
 	int offset = (ten) ? 8 : 4;
 	int length = 0;
@@ -911,7 +930,10 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
 		if ((offset + 1) > cmd->data_length)
 			offset = cmd->data_length;
 	}
+
+	rbuf = transport_kmap_first_data_page(cmd);
 	memcpy(rbuf, buf, offset);
+	transport_kunmap_first_data_page(cmd);
 
 	return 0;
 }
@@ -920,14 +942,18 @@ static int
 target_emulate_request_sense(struct se_cmd *cmd)
 {
 	unsigned char *cdb = cmd->t_task_cdb;
-	unsigned char *buf = cmd->t_task_buf;
+	unsigned char *buf;
 	u8 ua_asc = 0, ua_ascq = 0;
+	int err = 0;
 
 	if (cdb[1] & 0x01) {
 		printk(KERN_ERR "REQUEST_SENSE description emulation not"
 			" supported\n");
 		return PYX_TRANSPORT_INVALID_CDB_FIELD;
 	}
+
+	buf = transport_kmap_first_data_page(cmd);
+
 	if (!(core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))) {
 		/*
 		 * CURRENT ERROR, UNIT ATTENTION
@@ -940,7 +966,8 @@ target_emulate_request_sense(struct se_cmd *cmd)
 		 */
 		if (cmd->data_length <= 18) {
 			buf[7] = 0x00;
-			return 0;
+			err = -EINVAL;
+			goto end;
 		}
 		/*
 		 * The Additional Sense Code (ASC) from the UNIT ATTENTION
@@ -960,7 +987,8 @@ target_emulate_request_sense(struct se_cmd *cmd)
 		 */
 		if (cmd->data_length <= 18) {
 			buf[7] = 0x00;
-			return 0;
+			err = -EINVAL;
+			goto end;
 		}
 		/*
 		 * NO ADDITIONAL SENSE INFORMATION
@@ -969,6 +997,9 @@ target_emulate_request_sense(struct se_cmd *cmd)
 		buf[7] = 0x0A;
 	}
 
+end:
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -981,11 +1012,11 @@ target_emulate_unmap(struct se_task *task)
 {
 	struct se_cmd *cmd = task->task_se_cmd;
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf = cmd->t_task_buf, *ptr = NULL;
+	unsigned char *buf, *ptr = NULL;
 	unsigned char *cdb = &cmd->t_task_cdb[0];
 	sector_t lba;
 	unsigned int size = cmd->data_length, range;
-	int ret, offset;
+	int ret = 0, offset;
 	unsigned short dl, bd_dl;
 
 	/* First UNMAP block descriptor starts at 8 byte offset */
@@ -993,6 +1024,9 @@ target_emulate_unmap(struct se_task *task)
 	size -= 8;
 	dl = get_unaligned_be16(&cdb[0]);
 	bd_dl = get_unaligned_be16(&cdb[2]);
+
+	buf = transport_kmap_first_data_page(cmd);
+
 	ptr = &buf[offset];
 	printk(KERN_INFO "UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
 		" ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
@@ -1007,7 +1041,7 @@ target_emulate_unmap(struct se_task *task)
 		if (ret < 0) {
 			printk(KERN_ERR "blkdev_issue_discard() failed: %d\n",
 					ret);
-			return ret;
+			goto err;
 		}
 
 		ptr += 16;
@@ -1016,7 +1050,10 @@ target_emulate_unmap(struct se_task *task)
 
 	task->task_scsi_status = GOOD;
 	transport_complete_task(task, 1);
-	return 0;
+err:
+	transport_kunmap_first_data_page(cmd);
+
+	return ret;
 }
 
 /*
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 440e6b6..1185c3b 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -657,7 +657,7 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd)
 	struct se_lun *se_lun;
 	struct se_session *se_sess = se_cmd->se_sess;
 	struct se_task *se_task;
-	unsigned char *buf = se_cmd->t_task_buf;
+	unsigned char *buf;
 	u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
 
 	list_for_each_entry(se_task, &se_cmd->t_task_list, t_list)
@@ -668,6 +668,8 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd)
 		return PYX_TRANSPORT_LU_COMM_FAILURE;
 	}
 
+	buf = transport_kmap_first_data_page(se_cmd);
+
 	/*
 	 * If no struct se_session pointer is present, this struct se_cmd is
 	 * coming via a target_core_mod PASSTHROUGH op, and not through
@@ -704,6 +706,7 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd)
 	 * See SPC3 r07, page 159.
 	 */
 done:
+	transport_kunmap_first_data_page(se_cmd);
 	lun_count *= 8;
 	buf[0] = ((lun_count >> 24) & 0xff);
 	buf[1] = ((lun_count >> 16) & 0xff);
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 4fdede8..3342843 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1482,7 +1482,7 @@ static int core_scsi3_decode_spec_i_port(
 	struct list_head tid_dest_list;
 	struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
 	struct target_core_fabric_ops *tmp_tf_ops;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident;
 	char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
 	u32 tpdl, tid_len = 0;
@@ -1524,6 +1524,8 @@ static int core_scsi3_decode_spec_i_port(
 	 */
 	tidh_new->dest_local_nexus = 1;
 	list_add_tail(&tidh_new->dest_list, &tid_dest_list);
+
+	buf = transport_kmap_first_data_page(cmd);
 	/*
 	 * For a PERSISTENT RESERVE OUT specify initiator ports payload,
 	 * first extract TransportID Parameter Data Length, and make sure
@@ -1760,6 +1762,9 @@ static int core_scsi3_decode_spec_i_port(
 		tid_len = 0;
 
 	}
+
+	transport_kunmap_first_data_page(cmd);
+
 	/*
 	 * Go ahead and create a registrations from tid_dest_list for the
 	 * SPEC_I_PT provided TransportID for the *tidh referenced dest_node_acl
@@ -1806,6 +1811,7 @@ static int core_scsi3_decode_spec_i_port(
 
 	return 0;
 out:
+	transport_kunmap_first_data_page(cmd);
 	/*
 	 * For the failure case, release everything from tid_dest_list
 	 * including *dest_pr_reg and the configfs dependances..
@@ -3307,7 +3313,7 @@ static int core_scsi3_emulate_pro_register_and_move(
 	struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops;
 	struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
 	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	unsigned char *initiator_str;
 	char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
 	u32 tid_len, tmp_tid_len;
@@ -3357,17 +3363,21 @@ static int core_scsi3_emulate_pro_register_and_move(
 		core_scsi3_put_pr_reg(pr_reg);
 		return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
 	}
+
 	/*
 	 * Determine the Relative Target Port Identifier where the reservation
 	 * will be moved to for the TransportID containing SCSI initiator WWN
 	 * information.
 	 */
+	buf = transport_kmap_first_data_page(cmd);
 	rtpi = (buf[18] & 0xff) << 8;
 	rtpi |= buf[19] & 0xff;
 	tid_len = (buf[20] & 0xff) << 24;
 	tid_len |= (buf[21] & 0xff) << 16;
 	tid_len |= (buf[22] & 0xff) << 8;
 	tid_len |= buf[23] & 0xff;
+	transport_kunmap_first_data_page(cmd);
+	buf = NULL;
 
 	if ((tid_len + 24) != cmd->data_length) {
 		printk(KERN_ERR "SPC-3 PR: Illegal tid_len: %u + 24 byte header"
@@ -3414,6 +3424,8 @@ static int core_scsi3_emulate_pro_register_and_move(
 		core_scsi3_put_pr_reg(pr_reg);
 		return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
 	}
+
+	buf = transport_kmap_first_data_page(cmd);
 	proto_ident = (buf[24] & 0x0f);
 #if 0
 	printk("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
@@ -3444,6 +3456,9 @@ static int core_scsi3_emulate_pro_register_and_move(
 		goto out;
 	}
 
+	transport_kunmap_first_data_page(cmd);
+	buf = NULL;
+
 	printk(KERN_INFO "SPC-3 PR [%s] Extracted initiator %s identifier: %s"
 		" %s\n", dest_tf_ops->get_fabric_name(), (iport_ptr != NULL) ?
 		"port" : "device", initiator_str, (iport_ptr != NULL) ?
@@ -3696,9 +3711,13 @@ after_iport_check:
 					" REGISTER_AND_MOVE\n");
 	}
 
+	transport_kunmap_first_data_page(cmd);
+
 	core_scsi3_put_pr_reg(dest_pr_reg);
 	return 0;
 out:
+	if (buf)
+		transport_kunmap_first_data_page(cmd);
 	if (dest_se_deve)
 		core_scsi3_lunacl_undepend_item(dest_se_deve);
 	if (dest_node_acl)
@@ -3723,7 +3742,7 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
  */
 static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
 {
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u64 res_key, sa_res_key;
 	int sa, scope, type, aptpl;
 	int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
@@ -3745,6 +3764,8 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
 	sa = (cdb[1] & 0x1f);
 	scope = (cdb[2] & 0xf0);
 	type = (cdb[2] & 0x0f);
+
+	buf = transport_kmap_first_data_page(cmd);
 	/*
 	 * From PERSISTENT_RESERVE_OUT parameter list (payload)
 	 */
@@ -3762,6 +3783,9 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
 		aptpl = (buf[17] & 0x01);
 		unreg = (buf[17] & 0x02);
 	}
+	transport_kunmap_first_data_page(cmd);
+	buf = NULL;
+
 	/*
 	 * SPEC_I_PT=1 is only valid for Service action: REGISTER
 	 */
@@ -3830,7 +3854,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 	struct se_device *se_dev = cmd->se_dev;
 	struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
 	struct t10_pr_registration *pr_reg;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u32 add_len = 0, off = 8;
 
 	if (cmd->data_length < 8) {
@@ -3839,6 +3863,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 		return PYX_TRANSPORT_INVALID_CDB_FIELD;
 	}
 
+	buf = transport_kmap_first_data_page(cmd);
 	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
 	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
 	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -3872,6 +3897,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 	buf[6] = ((add_len >> 8) & 0xff);
 	buf[7] = (add_len & 0xff);
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -3885,7 +3912,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 	struct se_device *se_dev = cmd->se_dev;
 	struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
 	struct t10_pr_registration *pr_reg;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u64 pr_res_key;
 	u32 add_len = 16; /* Hardcoded to 16 when a reservation is held. */
 
@@ -3895,6 +3922,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 		return PYX_TRANSPORT_INVALID_CDB_FIELD;
 	}
 
+	buf = transport_kmap_first_data_page(cmd);
 	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
 	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
 	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -3911,10 +3939,9 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 		buf[6] = ((add_len >> 8) & 0xff);
 		buf[7] = (add_len & 0xff);
 
-		if (cmd->data_length < 22) {
-			spin_unlock(&se_dev->dev_reservation_lock);
-			return 0;
-		}
+		if (cmd->data_length < 22)
+			goto err;
+
 		/*
 		 * Set the Reservation key.
 		 *
@@ -3951,7 +3978,10 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 		buf[21] = (pr_reg->pr_res_scope & 0xf0) |
 			  (pr_reg->pr_res_type & 0x0f);
 	}
+
+err:
 	spin_unlock(&se_dev->dev_reservation_lock);
+	transport_kunmap_first_data_page(cmd);
 
 	return 0;
 }
@@ -3965,7 +3995,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
 	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u16 add_len = 8; /* Hardcoded to 8. */
 
 	if (cmd->data_length < 6) {
@@ -3974,6 +4004,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
 		return PYX_TRANSPORT_INVALID_CDB_FIELD;
 	}
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = ((add_len << 8) & 0xff);
 	buf[1] = (add_len & 0xff);
 	buf[2] |= 0x10; /* CRH: Compatible Reservation Hanlding bit. */
@@ -4004,6 +4036,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
 	buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
 	buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
@@ -4020,7 +4054,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
 	struct t10_reservation *pr_tmpl = &se_dev->se_sub_dev->t10_pr;
-	unsigned char *buf = (unsigned char *)cmd->t_task_buf;
+	unsigned char *buf;
 	u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
 	u32 off = 8; /* off into first Full Status descriptor */
 	int format_code = 0;
@@ -4031,6 +4065,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 		return PYX_TRANSPORT_INVALID_CDB_FIELD;
 	}
 
+	buf = transport_kmap_first_data_page(cmd);
+
 	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
 	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
 	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
@@ -4150,6 +4186,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 	buf[6] = ((add_len >> 8) & 0xff);
 	buf[7] = (add_len & 0xff);
 
+	transport_kunmap_first_data_page(cmd);
+
 	return 0;
 }
 
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 3574c52..d956924 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -695,7 +695,7 @@ static int pscsi_transport_complete(struct se_task *task)
 
 		if (task->task_se_cmd->se_deve->lun_flags &
 				TRANSPORT_LUNFLAGS_READ_ONLY) {
-			unsigned char *buf = task->task_se_cmd->t_task_buf;
+			unsigned char *buf = transport_kmap_first_data_page(task->task_se_cmd);
 
 			if (cdb[0] == MODE_SENSE_10) {
 				if (!(buf[3] & 0x80))
@@ -704,6 +704,8 @@ static int pscsi_transport_complete(struct se_task *task)
 				if (!(buf[2] & 0x80))
 					buf[2] |= 0x80;
 			}
+
+			transport_kunmap_first_data_page(task->task_se_cmd);
 		}
 	}
 after_mode_sense:
@@ -1246,33 +1248,6 @@ static int pscsi_map_task_SG(struct se_task *task)
 	return 0;
 }
 
-/*	pscsi_map_task_non_SG():
- *
- *
- */
-static int pscsi_map_task_non_SG(struct se_task *task)
-{
-	struct se_cmd *cmd = task->task_se_cmd;
-	struct pscsi_plugin_task *pt = PSCSI_TASK(task);
-	struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr;
-	int ret = 0;
-
-	if (pscsi_blk_get_request(task) < 0)
-		return PYX_TRANSPORT_LU_COMM_FAILURE;
-
-	if (!task->task_size)
-		return 0;
-
-	ret = blk_rq_map_kern(pdv->pdv_sd->request_queue,
-			pt->pscsi_req, cmd->t_task_buf,
-			task->task_size, GFP_KERNEL);
-	if (ret < 0) {
-		printk(KERN_ERR "PSCSI: blk_rq_map_kern() failed: %d\n", ret);
-		return PYX_TRANSPORT_LU_COMM_FAILURE;
-	}
-	return 0;
-}
-
 static int pscsi_CDB_none(struct se_task *task)
 {
 	return pscsi_blk_get_request(task);
@@ -1392,7 +1367,6 @@ static struct se_subsystem_api pscsi_template = {
 	.owner			= THIS_MODULE,
 	.transport_type		= TRANSPORT_PLUGIN_PHBA_PDEV,
 	.cdb_none		= pscsi_CDB_none,
-	.map_task_non_SG	= pscsi_map_task_non_SG,
 	.map_task_SG		= pscsi_map_task_SG,
 	.attach_hba		= pscsi_attach_hba,
 	.detach_hba		= pscsi_detach_hba,
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index ca8307e..253dcd7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -213,7 +213,7 @@ static u32 transport_allocate_tasks(struct se_cmd *cmd,
 		unsigned long long starting_lba, u32 sectors,
 		enum dma_data_direction data_direction,
 		struct list_head *mem_list, int set_counts);
-static int transport_generic_get_mem(struct se_cmd *cmd, u32 length);
+static int transport_generic_get_mem(struct se_cmd *cmd);
 static int transport_generic_remove(struct se_cmd *cmd,
 		int session_reinstatement);
 static int transport_cmd_get_valid_sectors(struct se_cmd *cmd);
@@ -2233,23 +2233,6 @@ static void transport_generic_request_timeout(struct se_cmd *cmd)
 	transport_generic_remove(cmd, 0);
 }
 
-static int
-transport_generic_allocate_buf(struct se_cmd *cmd, u32 data_length)
-{
-	unsigned char *buf;
-
-	buf = kzalloc(data_length, GFP_KERNEL);
-	if (!(buf)) {
-		printk(KERN_ERR "Unable to allocate memory for buffer\n");
-		return -ENOMEM;
-	}
-
-	cmd->t_tasks_se_num = 0;
-	cmd->t_task_buf = buf;
-
-	return 0;
-}
-
 static inline u32 transport_lba_21(unsigned char *cdb)
 {
 	return ((cdb[1] & 0x1f) << 16) | (cdb[2] << 8) | cdb[3];
@@ -2966,19 +2949,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
 	return -1;
 }
 
-static int transport_allocate_resources(struct se_cmd *cmd)
-{
-	u32 length = cmd->data_length;
-
-	if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) ||
-	    (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB))
-		return transport_generic_get_mem(cmd, length);
-	else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB)
-		return transport_generic_allocate_buf(cmd, length);
-	else
-		return 0;
-}
-
 static int
 transport_handle_reservation_conflict(struct se_cmd *cmd)
 {
@@ -3265,7 +3235,7 @@ static int transport_generic_cmd_sequencer(
 			/* GPCMD_SEND_KEY from multi media commands */
 			size = (cdb[8] << 8) + cdb[9];
 		}
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case MODE_SELECT:
 		size = cdb[4];
@@ -3277,7 +3247,7 @@ static int transport_generic_cmd_sequencer(
 		break;
 	case MODE_SENSE:
 		size = cdb[4];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case MODE_SENSE_10:
 	case GPCMD_READ_BUFFER_CAPACITY:
@@ -3285,11 +3255,11 @@ static int transport_generic_cmd_sequencer(
 	case LOG_SELECT:
 	case LOG_SENSE:
 		size = (cdb[7] << 8) + cdb[8];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case READ_BLOCK_LIMITS:
 		size = READ_BLOCK_LEN;
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case GPCMD_GET_CONFIGURATION:
 	case GPCMD_READ_FORMAT_CAPACITIES:
@@ -3305,7 +3275,7 @@ static int transport_generic_cmd_sequencer(
 			 SPC3_PERSISTENT_RESERVATIONS) ?
 			core_scsi3_emulate_pr : NULL;
 		size = (cdb[7] << 8) + cdb[8];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case GPCMD_MECHANISM_STATUS:
 	case GPCMD_READ_DVD_STRUCTURE:
@@ -3314,7 +3284,7 @@ static int transport_generic_cmd_sequencer(
 		break;
 	case READ_POSITION:
 		size = READ_POSITION_LEN;
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case MAINTENANCE_OUT:
 		if (dev->transport->get_device_type(dev) != TYPE_ROM) {
@@ -3336,7 +3306,7 @@ static int transport_generic_cmd_sequencer(
 			/* GPCMD_REPORT_KEY from multi media commands */
 			size = (cdb[8] << 8) + cdb[9];
 		}
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case INQUIRY:
 		size = (cdb[3] << 8) + cdb[4];
@@ -3346,21 +3316,21 @@ static int transport_generic_cmd_sequencer(
 		 */
 		if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
 			cmd->sam_task_attr = MSG_HEAD_TAG;
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case READ_BUFFER:
 		size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case READ_CAPACITY:
 		size = READ_CAP_LEN;
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case READ_MEDIA_SERIAL_NUMBER:
 	case SECURITY_PROTOCOL_IN:
 	case SECURITY_PROTOCOL_OUT:
 		size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case SERVICE_ACTION_IN:
 	case ACCESS_CONTROL_IN:
@@ -3371,36 +3341,36 @@ static int transport_generic_cmd_sequencer(
 	case WRITE_ATTRIBUTE:
 		size = (cdb[10] << 24) | (cdb[11] << 16) |
 		       (cdb[12] << 8) | cdb[13];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case RECEIVE_DIAGNOSTIC:
 	case SEND_DIAGNOSTIC:
 		size = (cdb[3] << 8) | cdb[4];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 /* #warning FIXME: Figure out correct GPCMD_READ_CD blocksize. */
 #if 0
 	case GPCMD_READ_CD:
 		sectors = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
 		size = (2336 * sectors);
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 #endif
 	case READ_TOC:
 		size = cdb[8];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case REQUEST_SENSE:
 		size = cdb[4];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case READ_ELEMENT_STATUS:
 		size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case WRITE_BUFFER:
 		size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case RESERVE:
 	case RESERVE_10:
@@ -3480,7 +3450,7 @@ static int transport_generic_cmd_sequencer(
 		break;
 	case UNMAP:
 		size = get_unaligned_be16(&cdb[7]);
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	case WRITE_SAME_16:
 		sectors = transport_get_sectors_16(cdb, cmd, &sector_ret);
@@ -3547,7 +3517,7 @@ static int transport_generic_cmd_sequencer(
 		 */
 		if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
 			cmd->sam_task_attr = MSG_HEAD_TAG;
-		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
+		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
 		break;
 	default:
 		printk(KERN_WARNING "TARGET_CORE[%s]: Unsupported SCSI Opcode"
@@ -3804,16 +3774,6 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
 					cmd->data_length;
 		}
 		spin_unlock(&cmd->se_lun->lun_sep_lock);
-		/*
-		 * If enabled by TCM fabric module pre-registered SGL
-		 * memory, perform the memcpy() from the TCM internal
-		 * contiguous buffer back to the original SGL.
-		 */
-		if (cmd->se_cmd_flags & SCF_PASSTHROUGH_CONTIG_TO_SG)
-			sg_copy_from_buffer(cmd->t_task_pt_sgl,
-					    cmd->t_task_pt_sgl_num,
-					    cmd->t_task_buf,
-					    cmd->data_length);
 
 		ret = cmd->se_tfo->queue_data_in(cmd);
 		if (ret == -EAGAIN)
@@ -3899,12 +3859,6 @@ static inline void transport_free_pages(struct se_cmd *cmd)
 	if (cmd->se_dev->transport->do_se_mem_map)
 		free_page = 0;
 
-	if (cmd->t_task_buf) {
-		kfree(cmd->t_task_buf);
-		cmd->t_task_buf = NULL;
-		return;
-	}
-
 	list_for_each_entry_safe(se_mem, se_mem_tmp,
 			&cmd->t_mem_list, se_list) {
 		/*
@@ -4068,25 +4022,6 @@ int transport_generic_map_mem_to_cmd(
 			cmd->t_tasks_se_bidi_num = ret;
 		}
 		cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC;
-
-	} else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
-		if (sgl_bidi || sgl_bidi_count) {
-			printk(KERN_ERR "BIDI-Commands not supported using "
-				"SCF_SCSI_CONTROL_NONSG_IO_CDB\n");
-			return -ENOSYS;
-		}
-		/*
-		 * For incoming CDBs using a contiguous buffer internal with TCM,
-		 * save the passed struct scatterlist memory.  After TCM storage object
-		 * processing has completed for this struct se_cmd, TCM core will call
-		 * transport_memcpy_[write,read]_contig() as necessary from
-		 * transport_generic_complete_ok() and transport_write_pending() in order
-		 * to copy the TCM buffer to/from the original passed *mem in SGL ->
-		 * struct scatterlist format.
-		 */
-		cmd->se_cmd_flags |= SCF_PASSTHROUGH_CONTIG_TO_SG;
-		cmd->t_task_pt_sgl = sgl;
-		cmd->t_task_pt_sgl_num = sgl_count;
 	}
 
 	return 0;
@@ -4184,10 +4119,41 @@ static int transport_new_cmd_obj(struct se_cmd *cmd)
 	return 0;
 }
 
+void *transport_kmap_first_data_page(struct se_cmd *cmd)
+{
+	struct se_mem *se_mem;
+
+	BUG_ON(list_empty(&cmd->t_mem_list));
+
+	se_mem = list_first_entry(&cmd->t_mem_list, struct se_mem, se_list);
+
+	/*
+	 * 1st se_mem should point to a page, and we shouldn't need more than
+	 * that for this cmd
+	 */
+	BUG_ON(cmd->data_length > PAGE_SIZE);
+
+	return kmap(se_mem->se_page);
+}
+EXPORT_SYMBOL(transport_kmap_first_data_page);
+
+void transport_kunmap_first_data_page(struct se_cmd *cmd)
+{
+	struct se_mem *se_mem;
+
+	BUG_ON(list_empty(&cmd->t_mem_list));
+
+	se_mem = list_first_entry(&cmd->t_mem_list, struct se_mem, se_list);
+
+	kunmap(se_mem->se_page);
+}
+EXPORT_SYMBOL(transport_kunmap_first_data_page);
+
 static int
-transport_generic_get_mem(struct se_cmd *cmd, u32 length)
+transport_generic_get_mem(struct se_cmd *cmd)
 {
 	struct se_mem *se_mem;
+	int length = cmd->data_length;
 
 	/*
 	 * If the device uses memory mapping this is enough.
@@ -4195,6 +4161,7 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length)
 	if (cmd->se_dev->transport->do_se_mem_map)
 		return 0;
 
+	/* Even cmds with length 0 will get here, btw */
 	while (length) {
 		se_mem = kmem_cache_zalloc(se_mem_cache, GFP_KERNEL);
 		if (!(se_mem)) {
@@ -4850,10 +4817,6 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd)
 		if (dev->transport->map_task_SG)
 			return dev->transport->map_task_SG(task);
 		return 0;
-	} else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
-		if (dev->transport->map_task_non_SG)
-			return dev->transport->map_task_non_SG(task);
-		return 0;
 	} else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
 		if (dev->transport->cdb_none)
 			return dev->transport->cdb_none(task);
@@ -4886,7 +4849,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
 	 * cmd->t_mem_list of struct se_mem->se_page
 	 */
 	if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
-		ret = transport_allocate_resources(cmd);
+		ret = transport_generic_get_mem(cmd);
 		if (ret < 0)
 			return ret;
 	}
@@ -4970,17 +4933,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
 		cmd->transport_qf_callback = NULL;
 		return 0;
 	}
-	/*
-	 * For the TCM control CDBs using a contiguous buffer, do the memcpy
-	 * from the passed Linux/SCSI struct scatterlist located at
-	 * se_cmd->t_task_pt_sgl to the contiguous buffer at
-	 * se_cmd->t_task_buf.
-	 */
-	if (cmd->se_cmd_flags & SCF_PASSTHROUGH_CONTIG_TO_SG)
-		sg_copy_to_buffer(cmd->t_task_pt_sgl,
-				    cmd->t_task_pt_sgl_num,
-				    cmd->t_task_buf,
-				    cmd->data_length);
+
 	/*
 	 * Clear the se_cmd for WRITE_PENDING status in order to set
 	 * cmd->t_transport_active=0 so that transport_generic_handle_data
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index a00951c..1017f56 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -71,9 +71,9 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
 		caller, cmd, cmd->cdb);
 	printk(KERN_INFO "%s: cmd %p lun %d\n", caller, cmd, cmd->lun);
 
-	printk(KERN_INFO "%s: cmd %p se_num %u buf %p len %u se_cmd_flags <0x%x>\n",
+	printk(KERN_INFO "%s: cmd %p se_num %u len %u se_cmd_flags <0x%x>\n",
 	       caller, cmd, se_cmd->t_tasks_se_num,
-	       se_cmd->t_task_buf, se_cmd->data_length, se_cmd->se_cmd_flags);
+	       se_cmd->data_length, se_cmd->se_cmd_flags);
 
 	list_for_each_entry(mem, &se_cmd->t_mem_list, se_list)
 		printk(KERN_INFO "%s: cmd %p mem %p page %p "
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index 8560182..8376607 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -92,19 +92,15 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 	remaining = se_cmd->data_length;
 
 	/*
-	 * Setup to use first mem list entry if any.
+	 * Setup to use first mem list entry, unless no data.
 	 */
-	if (se_cmd->t_tasks_se_num) {
+	BUG_ON(remaining && list_empty(&se_cmd->t_mem_list));
+	if (remaining) {
 		mem = list_first_entry(&se_cmd->t_mem_list,
 			 struct se_mem, se_list);
 		mem_len = mem->se_len;
 		mem_off = mem->se_off;
 		page = mem->se_page;
-	} else {
-		mem = NULL;
-		mem_len = remaining;
-		mem_off = 0;
-		page = NULL;
 	}
 
 	/* no scatter/gather in skb for odd word length due to fc_seq_send() */
@@ -145,18 +141,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 		tlen = min(mem_len, frame_len);
 
 		if (use_sg) {
-			if (!mem) {
-				BUG_ON(!se_cmd->t_task_buf);
-				page_addr = se_cmd->t_task_buf + mem_off;
-				/*
-				 * In this case, offset is 'offset_in_page' of
-				 * (t_task_buf + mem_off) instead of 'mem_off'.
-				 */
-				off_in_page = offset_in_page(page_addr);
-				page = virt_to_page(page_addr);
-				tlen = min(tlen, PAGE_SIZE - off_in_page);
-			} else
-				off_in_page = mem_off;
+			off_in_page = mem_off;
 			BUG_ON(!page);
 			get_page(page);
 			skb_fill_page_desc(fp_skb(fp),
@@ -166,7 +151,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 			fp_skb(fp)->data_len += tlen;
 			fp_skb(fp)->truesize +=
 					PAGE_SIZE << compound_order(page);
-		} else if (mem) {
+		} else {
 			BUG_ON(!page);
 			from = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
 					   KM_SOFTIRQ0);
@@ -177,10 +162,6 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 			memcpy(to, from, tlen);
 			kunmap_atomic(page_addr, KM_SOFTIRQ0);
 			to += tlen;
-		} else {
-			from = se_cmd->t_task_buf + mem_off;
-			memcpy(to, from, tlen);
-			to += tlen;
 		}
 
 		mem_off += tlen;
@@ -305,19 +286,15 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
 		frame_len = se_cmd->data_length - rel_off;
 
 	/*
-	 * Setup to use first mem list entry if any.
+	 * Setup to use first mem list entry, unless no data.
 	 */
-	if (se_cmd->t_tasks_se_num) {
+	BUG_ON(frame_len && list_empty(&se_cmd->t_mem_list));
+	if (frame_len) {
 		mem = list_first_entry(&se_cmd->t_mem_list,
 				       struct se_mem, se_list);
 		mem_len = mem->se_len;
 		mem_off = mem->se_off;
 		page = mem->se_page;
-	} else {
-		mem = NULL;
-		page = NULL;
-		mem_off = 0;
-		mem_len = frame_len;
 	}
 
 	while (frame_len) {
@@ -340,19 +317,15 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
 
 		tlen = min(mem_len, frame_len);
 
-		if (mem) {
-			to = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
-					 KM_SOFTIRQ0);
-			page_addr = to;
-			to += mem_off & ~PAGE_MASK;
-			tlen = min(tlen, (size_t)(PAGE_SIZE -
-						(mem_off & ~PAGE_MASK)));
-			memcpy(to, from, tlen);
-			kunmap_atomic(page_addr, KM_SOFTIRQ0);
-		} else {
-			to = se_cmd->t_task_buf + mem_off;
-			memcpy(to, from, tlen);
-		}
+		to = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
+				 KM_SOFTIRQ0);
+		page_addr = to;
+		to += mem_off & ~PAGE_MASK;
+		tlen = min(tlen, (size_t)(PAGE_SIZE -
+					  (mem_off & ~PAGE_MASK)));
+		memcpy(to, from, tlen);
+		kunmap_atomic(page_addr, KM_SOFTIRQ0);
+
 		from += tlen;
 		frame_len -= tlen;
 		mem_off += tlen;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index df354b9..ed35624 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -109,7 +109,6 @@ enum se_cmd_flags_table {
 	SCF_EMULATED_TASK_SENSE		= 0x00000004,
 	SCF_SCSI_DATA_SG_IO_CDB		= 0x00000008,
 	SCF_SCSI_CONTROL_SG_IO_CDB	= 0x00000010,
-	SCF_SCSI_CONTROL_NONSG_IO_CDB	= 0x00000020,
 	SCF_SCSI_NON_DATA_CDB		= 0x00000040,
 	SCF_SCSI_CDB_EXCEPTION		= 0x00000080,
 	SCF_SCSI_RESERVATION_CONFLICT	= 0x00000100,
@@ -123,7 +122,6 @@ enum se_cmd_flags_table {
 	SCF_ALUA_NON_OPTIMIZED		= 0x00040000,
 	SCF_DELAYED_CMD_FROM_SAM_ATTR	= 0x00080000,
 	SCF_UNUSED			= 0x00100000,
-	SCF_PASSTHROUGH_CONTIG_TO_SG	= 0x00200000,
 	SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
 	SCF_EMULATE_CDB_ASYNC		= 0x01000000,
 	SCF_EMULATE_QUEUE_FULL		= 0x02000000,
@@ -516,8 +514,7 @@ struct se_cmd {
 	struct completion	transport_lun_fe_stop_comp;
 	struct completion	transport_lun_stop_comp;
 	struct scatterlist	*t_tasks_sg_chained;
-	struct scatterlist	t_tasks_sg_bounce;
-	void			*t_task_buf;
+
 	/*
 	 * Used for pre-registered fabric SGL passthrough WRITE and READ
 	 * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index b27ce1a..123df92 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -165,6 +165,8 @@ extern void transport_init_se_cmd(struct se_cmd *,
 					struct target_core_fabric_ops *,
 					struct se_session *, u32, int, int,
 					unsigned char *);
+void *transport_kmap_first_data_page(struct se_cmd *cmd);
+void transport_kunmap_first_data_page(struct se_cmd *cmd);
 extern void transport_free_se_cmd(struct se_cmd *);
 extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
 extern int transport_generic_handle_cdb(struct se_cmd *);
@@ -237,10 +239,6 @@ struct se_subsystem_api {
 	 */
 	int (*cdb_none)(struct se_task *);
 	/*
-	 * For SCF_SCSI_CONTROL_NONSG_IO_CDB
-	 */
-	int (*map_task_non_SG)(struct se_task *);
-	/*
 	 * For SCF_SCSI_DATA_SG_IO_CDB and SCF_SCSI_CONTROL_SG_IO_CDB
 	 */
 	int (*map_task_SG)(struct se_task *);
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 088/103] target: Enforce 1 page max for control cdb buffer sizes
  2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
                   ` (24 preceding siblings ...)
  2011-07-21  7:12 ` [PATCH 087/103] target: Make all control CDBs scatter-gather Nicholas A. Bellinger
@ 2011-07-21  7:12 ` Nicholas A. Bellinger
  25 siblings, 0 replies; 27+ messages in thread
From: Nicholas A. Bellinger @ 2011-07-21  7:12 UTC (permalink / raw)
  To: target-devel; +Cc: linux-scsi, Andy Grover

From: Andy Grover <agrover@redhat.com>

Due to all cdbs' data buffers being referenced by scatterlists, buffers
of more than a page are not contiguous. Instead of handling this in all
control command handlers, we may be able to get away with just limiting
control cdb data buffers to one page. The only control CDBs we handle that
have potentially large data buffers are REPORT LUNS and UNMAP, so if we
didn't want to live with this limitation, they would need to be modified
to walk the pages in the data buffer's sgl.

Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c |    5 +++++
 include/target/target_core_base.h      |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 253dcd7..1eb76f4 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -3562,6 +3562,11 @@ static int transport_generic_cmd_sequencer(
 		cmd->data_length = size;
 	}
 
+	/* Let's limit control cdbs to a page, for simplicity's sake. */
+	if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) &&
+	    size > PAGE_SIZE)
+		goto out_invalid_cdb_field;
+
 	transport_set_supported_SAM_opcode(cmd);
 	return ret;
 
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index ed35624..d97618a 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -15,6 +15,7 @@
 /* Used by transport_generic_allocate_iovecs() */
 #define TRANSPORT_IOV_DATA_BUFFER		5
 /* Maximum Number of LUNs per Target Portal Group */
+/* Don't raise above 511 or REPORT_LUNS needs to handle >1 page */
 #define TRANSPORT_MAX_LUNS_PER_TPG		256
 /*
  * By default we use 32-byte CDBs in TCM Core and subsystem plugin code.
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2011-07-21  7:09 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-21  7:11 [PATCH 062/103] target/pscsi: Unused param for pscsi_get_bio() Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 063/103] target: Rename get_cdb_count to allocate_tasks Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 064/103] target: Make transport_generic_new_cmd() available for iscsi-target Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 065/103] target: Remove fabric callback to allocate iovecs Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 066/103] target: Fix transport_generic_new_cmd WRITE comment Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 067/103] target: remove the always-noop ->new_cmd_failure method Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 068/103] target: remove the unused SCF_SE_DISABLE_ONLINE_CHECK flag Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 069/103] target: remove the unused SCF_CMD_PASSTHROUGH_NOALLOC flag Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 070/103] target: remove the unused SCF_EMULATE_SYNC_UNMAP flag Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 071/103] target: remove the unused SCF_EMULATE_SYNC_CACHE flag Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 072/103] target: merge release_cmd methods Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 073/103] target: Add transport_handle_cdb_direct optimization Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 074/103] target: Add SCF_EMULATE_QUEUE_FULL -> transport_handle_queue_full Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 075/103] target: Make transport_lookup_cmd_lun() locking IRQ-safe Nicholas A. Bellinger
2011-07-21  7:11 ` [PATCH 076/103] target: Make se_dev_check_online() " Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 077/103] target/iblock: Use request_queue->nr_request for se_device defaults Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 078/103] loopback: Remove duplicate scsi/scsi_tcq.h include Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 079/103] target: Make se_tmr_lock IRQ-safe Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 080/103] loopback: Fix memory leak in tcm_loop_make_scsi_hba() Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 081/103] target/iblock: Remove unused iblock_dev members Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 082/103] target: Allow for built-in target modules Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 083/103] target: Fix reporting of supported VPD pages Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 084/103] target: Implement Block Device Characteristics VPD page Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 085/103] target: Remove ifdeffed code in t_g_process_write Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 086/103] target: Pass 2nd param of transport_split_cdb by value Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 087/103] target: Make all control CDBs scatter-gather Nicholas A. Bellinger
2011-07-21  7:12 ` [PATCH 088/103] target: Enforce 1 page max for control cdb buffer sizes Nicholas A. Bellinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.