[stgt] [PATCH] Add an optional supported-opcode-array to the backingstore template
Ronnie Sahlberg
ronniesahlberg at gmail.com
Thu Oct 10 04:43:25 CEST 2013
Add an array that describes which opcodes are supported by the RDWR backend
Opcodes that are supported are flagged with 1, and opcodes that are not
supported are flagged with 0.
Add an array for SHEEPDOG backend and zero out the opcodes that are not
supported:
WRITE_VERIFY10/12/16 VERIFY10/12/16 PREFETCH10/16
WRITE_SAME10/16 UNMAP and ORWRITE
This allows backends to specify which opcodes it is prepared to process
and which commands should fail with invalid op code
This is most useful for block devices where we have several different backen
and where some backends only support a subset of the commands
Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
usr/bs_rdwr.c | 20 ++++++++++++++++++++
usr/bs_sheepdog.c | 20 ++++++++++++++++++++
usr/sbc.c | 30 +++++++++++++++---------------
usr/scsi.c | 6 ++++++
usr/tgtd.h | 1 +
5 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index 47d2d99..b65fa6a 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -412,6 +412,25 @@ static void bs_rdwr_exit(struct scsi_lu *lu)
bs_thread_close(info);
}
+static const char bs_ops_supported[256] = {
+/* 0x00-0x0F */ 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+/* 0x10-0x1F */ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
+/* 0x20-0x2F */ 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1,
+/* 0x30-0x3F */ 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x40-0x4F */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x50-0x5F */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+/* 0x60-0x6F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x70-0x7F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x80-0x8F */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+/* 0x90-0x9F */ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+/* 0xA0-0xAF */ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1,
+/* 0xB0-0xBF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xC0-0xCF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xD0-0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xE0-0xEF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xF0-0xFF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
static struct backingstore_template rdwr_bst = {
.bs_name = "rdwr",
.bs_datasize = sizeof(struct bs_thread_info),
@@ -421,6 +440,7 @@ static struct backingstore_template rdwr_bst = {
.bs_exit = bs_rdwr_exit,
.bs_cmd_submit = bs_thread_cmd_submit,
.bs_oflags_supported = O_SYNC | O_DIRECT,
+ .bs_ops_supported = bs_ops_supported,
};
__attribute__((constructor)) static void bs_rdwr_constructor(void)
diff --git a/usr/bs_sheepdog.c b/usr/bs_sheepdog.c
index 4b5a951..e4744e0 100644
--- a/usr/bs_sheepdog.c
+++ b/usr/bs_sheepdog.c
@@ -1017,6 +1017,25 @@ static void bs_sheepdog_exit(struct scsi_lu *lu)
}
}
+static const char bs_ops_supported[256] = {
+/* 0x00-0x0F */ 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+/* 0x10-0x1F */ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
+/* 0x20-0x2F */ 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+/* 0x30-0x3F */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x40-0x4F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x50-0x5F */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+/* 0x60-0x6F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x70-0x7F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x80-0x8F */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+/* 0x90-0x9F */ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+/* 0xA0-0xAF */ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+/* 0xB0-0xBF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xC0-0xCF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xD0-0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xE0-0xEF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xF0-0xFF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
static struct backingstore_template sheepdog_bst = {
.bs_name = "sheepdog",
.bs_datasize =
@@ -1026,6 +1045,7 @@ static struct backingstore_template sheepdog_bst = {
.bs_init = bs_sheepdog_init,
.bs_exit = bs_sheepdog_exit,
.bs_cmd_submit = bs_thread_cmd_submit,
+ .bs_ops_supported = bs_ops_supported,
};
__attribute__((constructor)) static void __constructor(void)
diff --git a/usr/sbc.c b/usr/sbc.c
index c4f012c..bc872ed 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -788,9 +788,9 @@ static struct device_type_template sbc_template = {
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* READ_6 */
{spc_illegal_op,},
- {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
+ {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN}, /* WRITE_6 */
{spc_illegal_op,},
{spc_illegal_op,},
{spc_illegal_op,},
@@ -826,14 +826,14 @@ static struct device_type_template sbc_template = {
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* READ_10 */
{spc_illegal_op,},
- {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
+ {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN}, /* WRITE_10 */
{spc_illegal_op,},
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
- {sbc_verify, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* WRITE_VERIFY */
+ {sbc_verify, NULL, PR_EA_FA|PR_EA_FN}, /* VERIFY_10 */
/* 0x30 */
{spc_illegal_op,},
@@ -904,15 +904,15 @@ static struct device_type_template sbc_template = {
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* READ_16 */
/* {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, */
{spc_illegal_op,},
- {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN}, /* WRITE_16 */
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* ORWRITE_16 */
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
- {sbc_verify, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* WRITE_VERIFY16 */
+ {sbc_verify, NULL, PR_EA_FA|PR_EA_FN}, /* VERIFY_16 */
/* 0x90 */
{sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /*PRE_FETCH_16 */
@@ -943,14 +943,14 @@ static struct device_type_template sbc_template = {
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* READ_12 */
{spc_illegal_op,},
- {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN},
+ {sbc_rw, NULL, PR_WE_FA|PR_EA_FA|PR_WE_FN|PR_EA_FN}, /* READ_12 */
{spc_illegal_op,},
{spc_illegal_op,},
{spc_illegal_op,},
- {sbc_rw, NULL, PR_EA_FA|PR_EA_FN},
- {sbc_verify, NULL, PR_EA_FA|PR_EA_FN},
+ {sbc_rw, NULL, PR_EA_FA|PR_EA_FN}, /* WRITE_VERIFY_12 */
+ {sbc_verify, NULL, PR_EA_FA|PR_EA_FN}, /* VERIFY_12 */
[0xb0 ... 0xff] = {spc_illegal_op},
}
diff --git a/usr/scsi.c b/usr/scsi.c
index 2636a5c..991974d 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -492,6 +492,12 @@ int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd)
if (spc_access_check(cmd))
return SAM_STAT_RESERVATION_CONFLICT;
+ if (cmd->dev->bst->bs_ops_supported
+ && !cmd->dev->bst->bs_ops_supported[op]) {
+ sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_OP_CODE);
+ return SAM_STAT_CHECK_CONDITION;
+ }
+
return cmd->dev->dev_type_template.ops[op].cmd_perform(host_no, cmd);
}
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 484e6e9..70f6306 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -165,6 +165,7 @@ struct backingstore_template {
void (*bs_exit)(struct scsi_lu *dev);
int (*bs_cmd_submit)(struct scsi_cmd *cmd);
int bs_oflags_supported;
+ const char *bs_ops_supported;
struct list_head backingstore_siblings;
};
--
1.7.3.1
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list