Slightly modified patch from Bart Van Assche <bvanassche@acm.org> cleaning VERIFY commands processing

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4131 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2012-02-15 22:32:05 +00:00
parent 448a7bdd29
commit 293c2f3abd
5 changed files with 93 additions and 45 deletions
-3
View File
@@ -767,9 +767,6 @@ Bits of scst_cdb_flags can be:
<item> <bf/SCST_INFO_VALID/ - bits of op_flags are valid
<item> <bf/SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED/ - mismatch of data_direction with
the value supplied by target driver is allowed
<item> <bf/SCST_IMPLICIT_HQ/ - this command is an implicit HEAD OF QUEUE command
<item> <bf/SCST_SKIP_UA/ - Unit Attentions shouldn't be delivered for this command
-1
View File
@@ -182,7 +182,6 @@ enum scst_cdb_flags {
SCST_LONG_TIMEOUT = 0x0004,
SCST_UNKNOWN_LENGTH = 0x0008,
SCST_INFO_VALID = 0x0010, /* must be single bit */
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED = 0x0020,
SCST_IMPLICIT_HQ = 0x0040,
SCST_SKIP_UA = 0x0080,
SCST_WRITE_MEDIUM = 0x0100,
+24 -11
View File
@@ -1151,20 +1151,29 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
case READ_12:
case WRITE_10:
case WRITE_12:
case VERIFY:
case WRITE_VERIFY:
case WRITE_VERIFY_12:
case VERIFY_12:
lba_start = get_unaligned_be32(&cdb[2]);
data_len = cmd->bufflen;
break;
case READ_16:
case WRITE_16:
case WRITE_VERIFY_16:
case VERIFY_16:
lba_start = get_unaligned_be64(&cdb[2]);
data_len = cmd->bufflen;
break;
case VERIFY:
lba_start = get_unaligned_be32(&cdb[2]);
data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
break;
case VERIFY_12:
lba_start = get_unaligned_be32(&cdb[2]);
data_len = get_unaligned_be32(&cdb[6]) << virt_dev->block_shift;
break;
case VERIFY_16:
lba_start = get_unaligned_be64(&cdb[2]);
data_len = get_unaligned_be32(&cdb[10]) << virt_dev->block_shift;
break;
case SYNCHRONIZE_CACHE:
lba_start = get_unaligned_be32(&cdb[2]);
data_len = get_unaligned_be16(&cdb[7]) << virt_dev->block_shift;
@@ -3364,6 +3373,10 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
* from the file/disk yet.
*/
compare = scst_cmd_get_data_direction(cmd) == SCST_DATA_WRITE;
TRACE_DBG("VERIFY with BYTCHK=%d at offset %lld and with len = %lld\n",
compare, loff, p->data_len);
/* SEEK */
old_fs = get_fs();
set_fs(get_ds());
@@ -3392,13 +3405,12 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
goto out_set_fs;
}
length = scst_get_buf_first(cmd, &address);
address_sav = address;
if (!length && cmd->data_len) {
length = cmd->data_len;
compare = 0;
} else
compare = 1;
if (compare) {
length = scst_get_buf_first(cmd, &address);
address_sav = address;
} else {
length = p->data_len;
}
while (length > 0) {
len_mem = (length > LEN_MEM) ? LEN_MEM : length;
@@ -3430,7 +3442,8 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
goto out_set_fs;
}
length -= len_mem;
address += len_mem;
if (compare)
address += len_mem;
if (compare && length <= 0) {
scst_put_buf(cmd, address_sav);
length = scst_get_buf_next(cmd, &address);
+69 -22
View File
@@ -76,6 +76,10 @@ static int get_trans_len_4(struct scst_cmd *cmd, uint8_t off);
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off);
static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off);
static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off);
static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off);
/* for special commands */
static int get_trans_len_block_limit(struct scst_cmd *cmd, uint8_t off);
static int get_trans_len_read_capacity(struct scst_cmd *cmd, uint8_t off);
@@ -262,10 +266,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
3, get_trans_len_2},
{0x13, "VOVVVV ", "VERIFY(6)",
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
SCST_WRITE_EXCL_ALLOWED,
2, get_trans_len_3},
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
2, get_verify_trans_len_3},
{0x14, "VOOVVV ", "RECOVER BUFFERED DATA",
SCST_DATA_READ, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
@@ -358,10 +361,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
7, get_trans_len_2},
{0x2F, "O OO O ", "VERIFY(10)",
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
SCST_WRITE_EXCL_ALLOWED,
7, get_trans_len_2},
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
7, get_verify_trans_len_2},
{0x33, "O OO O ", "SET LIMITS(10)",
SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none},
{0x34, " O ", "READ POSITION",
@@ -537,10 +539,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
10, get_trans_len_4},
{0x8F, "O OO O ", "VERIFY(16)",
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
SCST_WRITE_EXCL_ALLOWED,
10, get_trans_len_4},
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
10, get_verify_trans_len_4},
{0x90, "O OO O ", "PRE-FETCH(16)",
SCST_DATA_NONE, SCST_WRITE_EXCL_ALLOWED,
0, get_trans_len_none},
@@ -624,10 +625,9 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
SCST_DATA_WRITE, SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM,
6, get_trans_len_4},
{0xAF, "O OO O ", "VERIFY(12)",
SCST_DATA_NONE, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED|
SCST_WRITE_EXCL_ALLOWED,
6, get_trans_len_4},
SCST_DATA_UNKNOWN, SCST_TRANSFER_LEN_TYPE_FIXED|
SCST_WRITE_EXCL_ALLOWED,
6, get_verify_trans_len_4},
#if 0 /* No need to support at all */
{0xB0, " OO O ", "SEARCH DATA HIGH(12)",
SCST_DATA_WRITE, FLAG_NONE, 9, get_trans_len_1},
@@ -5116,6 +5116,59 @@ static int get_trans_len_3_read_elem_stat(struct scst_cmd *cmd, uint8_t off)
return 0;
}
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off)
{
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
cmd->out_bufflen = cmd->bufflen;
return 0;
}
/*
* get_verify_trans_len_2() - Compute transport len and dir for SCSI VERIFY.
*
* Whether a data-out buffer is associated with a SCSI VERIFY command depends on
* the BYTCHK bit in that command. Check that bit and compute the data out
* buffer length and the data transfer direction.
*/
static int get_verify_trans_len_2(struct scst_cmd *cmd, uint8_t off)
{
if (cmd->cdb[1] & BYTCHK) {
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
cmd->data_direction = SCST_DATA_NONE;
}
return 0;
}
static int get_verify_trans_len_3(struct scst_cmd *cmd, uint8_t off)
{
if (cmd->cdb[1] & BYTCHK) {
cmd->bufflen = get_unaligned_be24(cmd->cdb + off);
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
cmd->data_direction = SCST_DATA_NONE;
}
return 0;
}
static int get_verify_trans_len_4(struct scst_cmd *cmd, uint8_t off)
{
if (cmd->cdb[1] & BYTCHK) {
cmd->bufflen = get_unaligned_be32(cmd->cdb + off);
cmd->data_direction = SCST_DATA_WRITE;
} else {
cmd->bufflen = 0;
cmd->data_direction = SCST_DATA_NONE;
}
return 0;
}
static int get_trans_len_1(struct scst_cmd *cmd, uint8_t off)
{
cmd->bufflen = (u32)cmd->cdb[off];
@@ -5164,12 +5217,6 @@ static int get_trans_len_none(struct scst_cmd *cmd, uint8_t off)
return 0;
}
static int get_bidi_trans_len_2(struct scst_cmd *cmd, uint8_t off)
{
cmd->bufflen = get_unaligned_be16(cmd->cdb + off);
cmd->out_bufflen = cmd->bufflen;
return 0;
}
/**
* scst_get_cdb_info() - fill various info about the command's CDB
-8
View File
@@ -532,13 +532,6 @@ static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd)
{
bool res = false;
/* VERIFY commands with BYTCHK unset shouldn't fail here */
if ((cmd->op_flags & SCST_VERIFY_BYTCHK_MISMATCH_ALLOWED) &&
(cmd->cdb[1] & BYTCHK) == 0) {
res = true;
goto out;
}
switch (cmd->cdb[0]) {
case TEST_UNIT_READY:
/* Crazy VMware people sometimes do TUR with READ direction */
@@ -548,7 +541,6 @@ static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd)
break;
}
out:
return res;
}
#endif