[PATCH] sbc: support large block sizes

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

 



This adds 512, 1024, 2048, and 4096 block sizes support to sbc.

I chose the global option. We could have this as a per lun option. But
I'm not sure it's worth to provide an option for block size; I even
think that we can just change the block size to 4096.

=
This adds 512, 1024, 2048, and 4096 block sizes support to sbc.

tgtd --sbc blocksize=4096

blocksize can be set to 512, 1024, 2048, and 4096.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>
---
 usr/sbc.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/usr/sbc.c b/usr/sbc.c
index 253f17c..fbe5601 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -41,7 +41,9 @@
 #include "spc.h"
 #include "tgtadm_error.h"
 
-#define BLK_SHIFT	9
+#define DEFAULT_BLK_SHIFT 9
+
+static unsigned int blk_shift = DEFAULT_BLK_SHIFT;
 
 static int sbc_mode_page_update(struct scsi_cmd *cmd, uint8_t *data, int *changed)
 {
@@ -84,7 +86,7 @@ static int sbc_rw(int host_no, struct scsi_cmd *cmd)
 
 	cmd->scsi_cmd_done = target_cmd_io_done;
 
-	cmd->offset = (scsi_rw_offset(cmd->scb) << BLK_SHIFT);
+	cmd->offset = (scsi_rw_offset(cmd->scb) << blk_shift);
 	ret = cmd->dev->bst->bs_cmd_submit(cmd);
 	if (ret) {
 		key = HARDWARE_ERROR;
@@ -137,11 +139,11 @@ static int sbc_read_capacity(int host_no, struct scsi_cmd *cmd)
 		goto overflow;
 
 	data = scsi_get_in_buffer(cmd);
-	size = cmd->dev->size >> BLK_SHIFT;
+	size = cmd->dev->size >> blk_shift;
 
 	data[0] = (size >> 32) ?
 		__cpu_to_be32(0xffffffff) : __cpu_to_be32(size - 1);
-	data[1] = __cpu_to_be32(1U << BLK_SHIFT);
+	data[1] = __cpu_to_be32(1U << blk_shift);
 
 overflow:
 	scsi_set_in_resid_by_actual(cmd, 8);
@@ -171,10 +173,10 @@ static int sbc_service_action(int host_no, struct scsi_cmd *cmd)
 	data = scsi_get_in_buffer(cmd);
 	memset(data, 0, 12);
 
-	size = cmd->dev->size >> BLK_SHIFT;
+	size = cmd->dev->size >> blk_shift;
 
 	*((uint64_t *)(data)) = __cpu_to_be64(size - 1);
-	data[2] = __cpu_to_be32(1UL << BLK_SHIFT);
+	data[2] = __cpu_to_be32(1UL << blk_shift);
 
 overflow:
 	scsi_set_in_resid_by_actual(cmd, 12);
@@ -233,11 +235,11 @@ static int sbc_lu_init(struct scsi_lu *lu)
 	lu->attrs.version_desc[2] = 0x0300; /* SPC-3 */
 
 	data = lu->mode_block_descriptor;
-	size = lu->size >> BLK_SHIFT;
+	size = lu->size >> blk_shift;
 
 	*(uint32_t *)(data) = (size >> 32) ?
 			__cpu_to_be32(0xffffffff) : __cpu_to_be32(size);
-	*(uint32_t *)(data + 4) = __cpu_to_be32(1 << BLK_SHIFT);
+	*(uint32_t *)(data + 4) = __cpu_to_be32(1 << blk_shift);
 
 	/* Vendor uniq - However most apps seem to call for mode page 0*/
 	add_mode_page(lu, "0:0:0");
@@ -429,7 +431,48 @@ static struct device_type_template sbc_template = {
 	}
 };
 
+static int get_blk_shift(unsigned int size)
+{
+	int shift = 0;
+
+	while (size > (1 << shift))
+		shift++;
+
+	return shift;
+}
+
+static int sbc_param_parser(char *p)
+{
+
+	while (*p) {
+		if (!strncmp(p, "blocksize=", 10)) {
+			unsigned int blocksize;
+
+			blocksize = atoi(p + 10);
+
+			switch (blocksize) {
+			case 4096:
+			case 2048:
+			case 1024:
+			case 512:
+				blk_shift = get_blk_shift(blocksize);
+				break;
+			default:
+				eprintf("%u is invalid block size\n", blocksize);
+			}
+		}
+
+		p += strcspn(p, ",");
+		if (*p == ',')
+			++p;
+	}
+
+	return 0;
+}
+
 __attribute__((constructor)) static void sbc_init(void)
 {
 	device_type_register(&sbc_template);
+
+	setup_param("sbc", sbc_param_parser);
 }
-- 
1.5.6.5

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

[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux