[PATCH] tcm: Drop ->max_cdb_len from struct se_dev_limits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch drops the backend subsystem plugin provided ->max_cdb_len value
in favor of a single check in transport_generic_allocate_tasks() against
the Linux/SCSI defined SCSI_MAX_VARLEN_CDB_SIZE of (252 + 8) bytes for all
received CDBs.

It also follows the recommendation by Boaz to drop the SCF_ECDB_ALLOCATION
flag and use (T_TASK(se_cmd)->t_task_cdb != T_TASK(se_cmd)->__t_task_cdb)
conditionals to signal that a T_TASK(cmd)->t_task_cdb allocation exists.

Many thanks to Boaz for his comments!

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/target/target_core_configfs.c  |    4 ----
 drivers/target/target_core_device.c    |    4 ----
 drivers/target/target_core_file.c      |    1 -
 drivers/target/target_core_iblock.c    |    1 -
 drivers/target/target_core_pscsi.c     |   16 +++-------------
 drivers/target/target_core_pscsi.h     |    3 ---
 drivers/target/target_core_rd.c        |    1 -
 drivers/target/target_core_transport.c |   32 ++++++++++++++------------------
 include/target/target_core_base.h      |    6 +-----
 9 files changed, 18 insertions(+), 50 deletions(-)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index b9b756d..bd2d4af 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -751,9 +751,6 @@ 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_RO(max_cdb_len);
-SE_DEV_ATTR_RO(max_cdb_len);
-
 DEF_DEV_ATTRIB_RO(hw_block_size);
 SE_DEV_ATTR_RO(hw_block_size);
 
@@ -802,7 +799,6 @@ 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_max_cdb_len.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 7b7fd42..de8a8cb 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -924,10 +924,6 @@ void se_dev_set_default_attribs(
 	DEV_ATTRIB(dev)->unmap_granularity_alignment =
 				DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
 	/*
-	 * max_cdb_len is based on subsystem plugin dependent requirements.
-	 */
-	DEV_ATTRIB(dev)->max_cdb_len = dev_limits->max_cdb_len;
-	/*
 	 * block_size is based on subsystem plugin dependent requirements.
 	 */
 	DEV_ATTRIB(dev)->hw_block_size = limits->logical_block_size;
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 4b20a8d..34ab402 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -231,7 +231,6 @@ static struct se_device *fd_create_virtdevice(
 		fd_dev->fd_block_size = FD_BLOCKSIZE;
 	}
 
-	dev_limits.max_cdb_len = TCM_MAX_COMMAND_SIZE;
 	dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
 	dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;
 
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index de67a5b..890db59 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -179,7 +179,6 @@ 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.max_cdb_len = TCM_MAX_COMMAND_SIZE;
 	dev_limits.hw_queue_depth = IBLOCK_MAX_DEVICE_QUEUE_DEPTH;
 	dev_limits.queue_depth = IBLOCK_DEVICE_QUEUE_DEPTH;
 
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index de412ea..6296a0f 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -251,7 +251,6 @@ static struct se_device *pscsi_add_device_to_list(
 				  queue_max_hw_sectors(q) : sd->host->max_sectors; 
 	limits->max_sectors = (sd->host->max_sectors > queue_max_sectors(q)) ?
 				  queue_max_sectors(q) : sd->host->max_sectors;
-	dev_limits.max_cdb_len = PSCSI_MAX_CDB_SIZE;
 	dev_limits.hw_queue_depth = sd->queue_depth;
 	dev_limits.queue_depth = sd->queue_depth;
 	/*
@@ -711,17 +710,7 @@ static void *pscsi_allocate_request(
 	 * allocate the extended CDB buffer for per struct se_task context
 	 * pt->pscsi_cdb now.
 	 */
-	if (cmd->se_cmd_flags & SCF_ECDB_ALLOCATION) {
-		/*
-		 * PSCSI_MAX_CDB_SIZE is currently set to 240 bytes which
-		 * allows the largest OSD CDB sizes again.
-		 */
-		if (scsi_command_size(cdb) > PSCSI_MAX_CDB_SIZE) {
-			printk(KERN_ERR "pSCSI: Received CDB of size: %u larger"
-				" than PSCSI_MAX_CDB_SIZE: %u\n",
-				scsi_command_size(cdb), PSCSI_MAX_CDB_SIZE);
-			return NULL;
-		}
+	if (T_TASK(cmd)->t_task_cdb != T_TASK(cmd)->__t_task_cdb) {
 
 		pt->pscsi_cdb = kzalloc(scsi_command_size(cdb), GFP_KERNEL);
 		if (!(pt->pscsi_cdb)) {
@@ -827,11 +816,12 @@ static int pscsi_do_task(struct se_task *task)
 static void pscsi_free_task(struct se_task *task)
 {
 	struct pscsi_plugin_task *pt = task->transport_req;
+	struct se_cmd *cmd = task->task_se_cmd;
 	/*
 	 * Release the extended CDB allocation from pscsi_allocate_request()
 	 * if one exists.
 	 */
-	if (task->task_se_cmd->se_cmd_flags & SCF_ECDB_ALLOCATION)
+	if (T_TASK(cmd)->t_task_cdb != T_TASK(cmd)->__t_task_cdb)
 		kfree(pt->pscsi_cdb);
 	/*
 	 * We do not release the bio(s) here associated with this task, as
diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h
index 4055967..f40d119 100644
--- a/drivers/target/target_core_pscsi.h
+++ b/drivers/target/target_core_pscsi.h
@@ -9,9 +9,6 @@
 #define INQUIRY_DATA_SIZE	0x24
 #endif
 
-/* Maximum extended CDB size for handling OSD passthrough */
-#define PSCSI_MAX_CDB_SIZE	240
-
 /* used in pscsi_add_device_to_list() */
 #define PSCSI_DEFAULT_QUEUEDEPTH	1
 
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 7121647..226c8ca 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -286,7 +286,6 @@ static struct se_device *rd_create_virtdevice(
 	dev_limits.limits.logical_block_size = RD_BLOCKSIZE;
 	dev_limits.limits.max_hw_sectors = RD_MAX_SECTORS;
 	dev_limits.limits.max_sectors = RD_MAX_SECTORS;
-	dev_limits.max_cdb_len = TCM_MAX_COMMAND_SIZE;
 	dev_limits.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH;
 	dev_limits.queue_depth = RD_DEVICE_QUEUE_DEPTH;
 
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 63dbb3e..150c0f8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2777,7 +2777,7 @@ void transport_free_se_cmd(
 	/*
 	 * Check and free any extended CDB buffer that was allocated
 	 */
-	if (se_cmd->se_cmd_flags & SCF_ECDB_ALLOCATION)
+	if (T_TASK(se_cmd)->t_task_cdb != T_TASK(se_cmd)->__t_task_cdb)
 		kfree(T_TASK(se_cmd)->t_task_cdb);
 	/*
 	 * Release any optional TCM fabric dependent iovecs allocated by
@@ -2823,20 +2823,29 @@ int transport_generic_allocate_tasks(
 	if (non_data_cdb < 0)
 		return -1;
 	/*
+	 * Ensure that the received CDB is less than the max (252 + 8) bytes
+	 * for VARIABLE_LENGTH_CMD
+	 */
+	if (scsi_command_size(cdb) > SCSI_MAX_VARLEN_CDB_SIZE) {
+		printk(KERN_ERR "Received SCSI CDB with command_size: %d that"
+			" exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
+			scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE);
+		return -1;
+	}
+	/*
 	 * If the received CDB is larger than TCM_MAX_COMMAND_SIZE,
 	 * allocate the additional extended CDB buffer now..  Otherwise
 	 * setup the pointer from __t_task_cdb to t_task_cdb.
 	 */
-	if (scsi_command_size(cdb) > TCM_MAX_COMMAND_SIZE) {
+	if (scsi_command_size(cdb) > sizeof(T_TASK(cmd)->__t_task_cdb)) {
 		T_TASK(cmd)->t_task_cdb = kzalloc(scsi_command_size(cdb),
 						GFP_KERNEL);
 		if (!(T_TASK(cmd)->t_task_cdb)) {
 			printk(KERN_ERR "Unable to allocate T_TASK(cmd)->t_task_cdb"
-				" %u > TCM_MAX_COMMAND_SIZE ops\n",
-				scsi_command_size(cdb));
+				" %u > sizeof(T_TASK(cmd)->__t_task_cdb): %u ops\n",
+				scsi_command_size(cdb), sizeof(T_TASK(cmd)->__t_task_cdb));
 			return -1;
 		}
-		cmd->se_cmd_flags |= SCF_ECDB_ALLOCATION;
 	} else
 		T_TASK(cmd)->t_task_cdb = &T_TASK(cmd)->__t_task_cdb[0];
 	/*
@@ -4753,19 +4762,6 @@ static int transport_generic_cmd_sequencer(
 	case VARIABLE_LENGTH_CMD:
 		service_action = get_unaligned_be16(&cdb[8]);
 		/*
-		 * Check the additional CDB length (+ 8 bytes for header) does
-		 * not exceed our backsores ->max_cdb_len
-		 */
-		if (scsi_varlen_cdb_length(&cdb[0]) >
-				DEV_ATTRIB(dev)->max_cdb_len) {
-			printk(KERN_INFO "Only %u-byte extended CDBs currently"
-				" supported for VARIABLE_LENGTH_CMD backstore %s,"
-				" received: %d for service action: 0x%04x\n",
-				DEV_ATTRIB(dev)->max_cdb_len, TRANSPORT(dev)->name,
-				scsi_varlen_cdb_length(&cdb[0]), service_action);
-			return TGCS_INVALID_CDB_FIELD;
-		}
-		/*
 		 * Determine if this is TCM/PSCSI device and we should disable
 		 * internal emulation for this CDB.
 		 */
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index ead2caf..49af478 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -137,8 +137,7 @@ enum se_cmd_flags_table {
 	SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00800000,
 	SCF_EMULATE_SYNC_CACHE		= 0x01000000,
 	SCF_EMULATE_CDB_ASYNC		= 0x02000000,
-	SCF_EMULATE_SYNC_UNMAP		= 0x04000000,
-	SCF_ECDB_ALLOCATION		= 0x08000000
+	SCF_EMULATE_SYNC_UNMAP		= 0x04000000
 };
 	
 /* struct se_device->type for known subsystem plugins */
@@ -739,8 +738,6 @@ struct se_dev_entry {
 }  ____cacheline_aligned;
 
 struct se_dev_limits {
-	/* Max supported SCSI CDB length */
-	int		max_cdb_len;
 	/* Max supported HW queue depth */
 	u32		hw_queue_depth;
 	/* Max supported virtual queue depth */
@@ -761,7 +758,6 @@ struct se_dev_attrib {
 	int		emulate_reservations;
 	int		emulate_alua;
 	int		enforce_pr_isids;
-	int		max_cdb_len;
 	u32		hw_block_size;
 	u32		block_size;
 	u32		hw_max_sectors;
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux