diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 9591b11..f4d12d5 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -981,9 +981,9 @@ iscsi_compareandwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba, struct scsi_task *task; struct iscsi_data d; - if (datalen % blocksize != 0) { + if (datalen % (blocksize * 2) != 0) { iscsi_set_error(iscsi, "Datalen:%d is not a multiple of the " - "blocksize:%d.", datalen, blocksize); + "blocksize * 2:%d.", datalen, blocksize * 2); return NULL; } diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index d766772..331fce5 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -1802,7 +1802,7 @@ scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrpr scsi_set_uint32(&task->cdb[2], lba >> 32); scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); - task->cdb[13] = xferlen/blocksize; + task->cdb[13] = xferlen/blocksize/2; task->cdb[14] |= (group_number & 0x1f); task->cdb_size = 16; diff --git a/test-tool/0340_compareandwrite_simple.c b/test-tool/0340_compareandwrite_simple.c index 535542b..3567205 100644 --- a/test-tool/0340_compareandwrite_simple.c +++ b/test-tool/0340_compareandwrite_simple.c @@ -21,6 +21,14 @@ #include "scsi-lowlevel.h" #include "iscsi-test.h" +static void bitwise_invert(unsigned char data[], int len) { + int j; + + for (j = 0; j < len; j++) { + data[j] = ~data[j]; + } +} + int T0340_compareandwrite_simple(const char *initiator, const char *url) { struct iscsi_context *iscsi; @@ -80,9 +88,11 @@ int T0340_compareandwrite_simple(const char *initiator, const char *url) goto finished; } memcpy(data, task->datain.data, i * block_size); + memcpy(data + (i * block_size), task->datain.data, i * block_size); + bitwise_invert(data + (i * block_size), i * block_size); scsi_free_scsi_task(task); - task = iscsi_compareandwrite_sync(iscsi, lun, 0, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, 0, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); @@ -136,9 +146,11 @@ int T0340_compareandwrite_simple(const char *initiator, const char *url) goto finished; } memcpy(data, task->datain.data, i * block_size); + memcpy(data + (i * block_size), task->datain.data, i * block_size); + bitwise_invert(data + (i * block_size), i * block_size); scsi_free_scsi_task(task); - task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 1 - i, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 1 - i, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0341_compareandwrite_mismatch.c b/test-tool/0341_compareandwrite_mismatch.c index ca5adc0..645daa8 100644 --- a/test-tool/0341_compareandwrite_mismatch.c +++ b/test-tool/0341_compareandwrite_mismatch.c @@ -58,7 +58,7 @@ int T0341_compareandwrite_mismatch(const char *initiator, const char *url) /* write the first 1 - 255 blocks at the start of the LUN */ printf("Compare and write first 1-255 blocks (data is not matching) ... "); for (i = 1; i < 256; i++) { - task = iscsi_read16_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_read16_sync(iscsi, lun, 0, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send READ16 command: %s\n", iscsi_get_error(iscsi)); @@ -85,8 +85,10 @@ int T0341_compareandwrite_mismatch(const char *initiator, const char *url) /* flip some bits */ data[ (i - 1) * block_size] ^= 0xa5; + /* set the write part of the data-out buffer to 1s */ + memset(data + (i * block_size), 0xff, (i * block_size)); - task = iscsi_compareandwrite_sync(iscsi, lun, 0, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, 0, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); @@ -153,8 +155,10 @@ int T0341_compareandwrite_mismatch(const char *initiator, const char *url) /* flip some bits */ data[ (i - 1) * block_size] ^= 0xa5; + /* set the write part of the data-out buffer to 1s */ + memset(data + (i * block_size), 0xff, (i * block_size)); - task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 1 - i, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 1 - i, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0343_compareandwrite_beyondeol.c b/test-tool/0343_compareandwrite_beyondeol.c index 9451991..b416a1e 100644 --- a/test-tool/0343_compareandwrite_beyondeol.c +++ b/test-tool/0343_compareandwrite_beyondeol.c @@ -57,7 +57,7 @@ int T0343_compareandwrite_beyondeol(const char *initiator, const char *url) /* read 1 - 255 blocks beyond the end of the device */ printf("Writing 1-255 blocks with one block beyond end-of-device ... "); for (i = 1; i <= 255; i++) { - task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 2 - i, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks + 2 - i, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); @@ -97,7 +97,7 @@ int T0343_compareandwrite_beyondeol(const char *initiator, const char *url) /* read 1 - 255 blocks at lba 2^63 */ printf("Writing 1-255 blocks at LBA 2^63 ... "); for (i = 1; i < 256; i++) { - task = iscsi_compareandwrite_sync(iscsi, lun, 0x8000000000000000, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, 0x8000000000000000, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); @@ -128,7 +128,7 @@ int T0343_compareandwrite_beyondeol(const char *initiator, const char *url) /* read 1 - 255 blocks at lba -1 */ printf("Writing 1-255 blocks at LBA -1 ... "); for (i = 1; i < 256; i++) { - task = iscsi_compareandwrite_sync(iscsi, lun, 0xffffffffffffffff, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, 0xffffffffffffffff, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi)); @@ -159,7 +159,7 @@ int T0343_compareandwrite_beyondeol(const char *initiator, const char *url) /* read 2-255 blocks, all but one block beyond the eol */ printf("Writing 1-255 blocks beyond eol starting at last block ... "); for (i = 2; i < 256; i++) { - task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks, data, i * block_size, block_size, 0, 0, 0, 0, 0); + task = iscsi_compareandwrite_sync(iscsi, lun, num_blocks, data, i * 2 * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi));