From 07f7cadb34caa732395217f489d00084381dc937 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 23 Jun 2008 16:32:51 +0000 Subject: [PATCH] - Fixes incorrect allocation length 0 by scst_user module - Fixes missed case of "allocation length 0 for READ6/WRITE6 means 256". git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@420 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_user.c | 6 ++++++ scst/src/scst_cdbprobe.h | 5 +++-- scst/src/scst_lib.c | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 2dcd3ec17..68654b9a0 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -490,6 +490,12 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) TRACE_ENTRY(); + /* User space can return from PARSE bufflen 0 and direction non-NONE */ + if (unlikely(bufflen == 0)) { + cmd->data_direction = SCST_DATA_NONE; + goto out; + } + gfp_mask = __GFP_NOWARN; gfp_mask |= (scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL); diff --git a/scst/src/scst_cdbprobe.h b/scst/src/scst_cdbprobe.h index ac0dcf860..c4b94e864 100644 --- a/scst/src/scst_cdbprobe.h +++ b/scst/src/scst_cdbprobe.h @@ -23,6 +23,7 @@ /* get_trans_len_x extract x bytes from cdb as length starting from off */ static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off); +static int get_trans_len_1_256(struct scst_cmd *cmd, uint8_t off); static int get_trans_len_2(struct scst_cmd *cmd, uint8_t off); static int get_trans_len_3(struct scst_cmd *cmd, uint8_t off); static int get_trans_len_4(struct scst_cmd *cmd, uint8_t off); @@ -131,7 +132,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { {0x07, "OVV O OV ", "REASSIGN BLOCKS", SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none}, {0x08, "O ", "READ(6)", - SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1}, + SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1_256}, {0x08, " MV OO OV ", "READ(6)", SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3}, {0x08, " M ", "GET MESSAGE(6)", @@ -141,7 +142,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { {0x09, "VVVVVV V ", "", SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none}, {0x0A, "O ", "WRITE(6)", - SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1}, + SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 4, get_trans_len_1_256}, {0x0A, " M O OV ", "WRITE(6)", SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED, 2, get_trans_len_3}, {0x0A, " M ", "PRINT", diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 2b1638b3f..e4d0a9cb2 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1657,6 +1657,7 @@ int scst_alloc_space(struct scst_cmd *cmd) flags |= SCST_POOL_ALLOC_NO_CACHED; if (unlikely(cmd->bufflen == 0)) { + /* ToDo: remove when 1.0.1 will be started */ TRACE(TRACE_MGMT_MINOR, "Warning: data direction %d or/and " "zero buffer length. Opcode 0x%x, handler %s, target " "%s", cmd->data_direction, cmd->cdb[0], @@ -1811,6 +1812,14 @@ static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off) return 0; } +static int get_trans_len_1_256(struct scst_cmd *cmd, uint8_t off) +{ + cmd->bufflen = (u32)cmd->cdb[off]; + if (cmd->bufflen == 0) + cmd->bufflen = 256; + return 0; +} + static int get_trans_len_2(struct scst_cmd *cmd, uint8_t off) { const uint8_t *p = cmd->cdb + off; @@ -1907,6 +1916,15 @@ int scst_get_cdb_info(struct scst_cmd *cmd) cmd->data_direction = ptr->direction; cmd->op_flags = ptr->flags; res = (*ptr->get_trans_len)(cmd, ptr->off); +#if 0 /* ToDo: enable when 1.0.1 will be started and fix all scst_get_buf_first() returns 0 cases */ + if (unlikely(cmd->bufflen == 0)) { + /* + * According to SPC bufflen 0 for data transfer commands isn't + * an error, so we need to fix the transfer direction. + */ + cmd->data_direction = SCST_DATA_NONE; + } +#endif out: TRACE_EXIT();