diff --git a/examples/iscsiclient.c b/examples/iscsiclient.c index 4551164..e93e922 100644 --- a/examples/iscsiclient.c +++ b/examples/iscsiclient.c @@ -183,7 +183,7 @@ void read6_cb(struct iscsi_context *iscsi, int status, void *command_data, void scsi_free_scsi_task(task); - if ((task = iscsi_read10_task(iscsi, clnt->lun, 0, clnt->block_size, clnt->block_size, read10_cb, private_data)) == NULL) { + if ((task = iscsi_read10_task(iscsi, clnt->lun, 0, clnt->block_size, clnt->block_size, 0, 0, 0, 0, 0, read10_cb, private_data)) == NULL) { printf("failed to send read10 command\n"); exit(10); } diff --git a/include/iscsi.h b/include/iscsi.h index 1b567b8..7072379 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -608,13 +608,14 @@ iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba, EXTERN struct scsi_task * iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, - uint32_t datalen, int blocksize, iscsi_command_cb cb, - void *private_data); + uint32_t datalen, int blocksize, + int rdprotect, int dpo, int fua, int fua_nv, int group_number, + iscsi_command_cb cb, void *private_data); EXTERN struct scsi_task * -iscsi_write10_task(struct iscsi_context *iscsi, int lun, - unsigned char *data, uint32_t datalen, uint32_t lba, int fua, - int fua_nv, int blocksize, iscsi_command_cb cb, - void *private_data); +iscsi_write10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, + unsigned char *data, uint32_t datalen, int blocksize, + int wrprotect, int dpo, int fua, int fua_nv, int group_number, + iscsi_command_cb cb, void *private_data); EXTERN struct scsi_task * iscsi_read12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, @@ -708,12 +709,13 @@ iscsi_read6_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, EXTERN struct scsi_task * iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, - uint32_t datalen, int blocksize); + uint32_t datalen, int blocksize, + int rdprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task * -iscsi_write10_sync(struct iscsi_context *iscsi, int lun, - unsigned char *data, uint32_t datalen, uint32_t lba, int fua, - int fua_nv, int blocksize); +iscsi_write10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, + unsigned char *data, uint32_t datalen, int blocksize, + int wrprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task * iscsi_read12_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h index 4589d55..92c0482 100644 --- a/include/scsi-lowlevel.h +++ b/include/scsi-lowlevel.h @@ -616,10 +616,10 @@ EXTERN int scsi_datain_getfullsize(struct scsi_task *task); EXTERN void *scsi_datain_unmarshall(struct scsi_task *task); EXTERN struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize); -EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task *scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task *scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, int blocksize); +EXTERN struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task *scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task *scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); EXTERN struct scsi_task *scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); diff --git a/lib/scsi-command.c b/lib/scsi-command.c index 1a17a27..0e8dfd7 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -677,8 +677,9 @@ iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba, struct scsi_task * iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, - uint32_t datalen, int blocksize, - iscsi_command_cb cb, void *private_data) + uint32_t datalen, int blocksize, + int rdprotect, int dpo, int fua, int fua_nv, int group_number, + iscsi_command_cb cb, void *private_data) { struct scsi_task *task; @@ -688,7 +689,8 @@ iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read10(lba, datalen, blocksize); + task = scsi_cdb_read10(lba, datalen, blocksize, rdprotect, + dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "read10 cdb."); @@ -764,9 +766,10 @@ iscsi_read16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, } struct scsi_task * -iscsi_write10_task(struct iscsi_context *iscsi, int lun, unsigned char *data, - uint32_t datalen, uint32_t lba, int fua, int fuanv, int blocksize, - iscsi_command_cb cb, void *private_data) +iscsi_write10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, + unsigned char *data, uint32_t datalen, int blocksize, + int wrprotect, int dpo, int fua, int fua_nv, int group_number, + iscsi_command_cb cb, void *private_data) { struct scsi_task *task; struct iscsi_data outdata; @@ -777,7 +780,8 @@ iscsi_write10_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_write10(lba, datalen, fua, fuanv, blocksize); + task = scsi_cdb_write10(lba, datalen, blocksize, wrprotect, + dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "write10 cdb."); diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index c371a2c..8672632 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -677,7 +677,7 @@ scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize) * READ10 */ struct scsi_task * -scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize) +scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; @@ -689,9 +689,22 @@ scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize) memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ10; + task->cdb[1] |= ((rdprotect & 0x07) << 5); + if (dpo) { + task->cdb[1] |= 0x10; + } + if (fua) { + task->cdb[1] |= 0x08; + } + if (fua_nv) { + task->cdb[1] |= 0x02; + } + *(uint32_t *)&task->cdb[2] = htonl(lba); *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); + task->cdb[6] |= (group_number & 0x1f); + task->cdb_size = 10; if (xferlen != 0) { task->xfer_dir = SCSI_XFER_READ; @@ -803,7 +816,7 @@ scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, in * WRITE10 */ struct scsi_task * -scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fua_nv, int blocksize) +scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; @@ -815,6 +828,10 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fua_nv, int blocks memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE10; + task->cdb[1] |= ((wrprotect & 0x07) << 5); + if (dpo) { + task->cdb[1] |= 0x10; + } if (fua) { task->cdb[1] |= 0x08; } @@ -825,6 +842,8 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fua_nv, int blocks *(uint32_t *)&task->cdb[2] = htonl(lba); *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); + task->cdb[6] |= (group_number & 0x1f); + task->cdb_size = 10; if (xferlen != 0) { task->xfer_dir = SCSI_XFER_WRITE; diff --git a/lib/sync.c b/lib/sync.c index c449e53..643373b 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -254,14 +254,16 @@ iscsi_read6_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, struct scsi_task * iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, - uint32_t datalen, int blocksize) + uint32_t datalen, int blocksize, + int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct iscsi_sync_state state; memset(&state, 0, sizeof(state)); - if (iscsi_read10_task(iscsi, lun, lba, datalen, blocksize, - scsi_sync_cb, &state) == NULL) { + if (iscsi_read10_task(iscsi, lun, lba, datalen, blocksize, rdprotect, + dpo, fua, fua_nv, group_number, + scsi_sync_cb, &state) == NULL) { iscsi_set_error(iscsi, "Failed to send Read10 command"); return NULL; @@ -438,15 +440,17 @@ iscsi_prefetch16_sync(struct iscsi_context *iscsi, int lun, uint64_t lba, } struct scsi_task * -iscsi_write10_sync(struct iscsi_context *iscsi, int lun, unsigned char *data, uint32_t datalen, uint32_t lba, - int fua, int fuanv, int blocksize) +iscsi_write10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba, + unsigned char *data, uint32_t datalen, int blocksize, + int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct iscsi_sync_state state; memset(&state, 0, sizeof(state)); - if (iscsi_write10_task(iscsi, lun, data, datalen, lba, fua, fuanv, blocksize, - scsi_sync_cb, &state) == NULL) { + if (iscsi_write10_task(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, fua, fua_nv, group_number, + scsi_sync_cb, &state) == NULL) { iscsi_set_error(iscsi, "Failed to send Write10 command"); return NULL; diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 955ea9b..4c10c6a 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -261,7 +261,7 @@ ssize_t read(int fd, void *buf, size_t count) num_blocks = (iscsi_fd_list[fd].offset - offset + count + iscsi_fd_list[fd].block_size - 1) / iscsi_fd_list[fd].block_size; iscsi_fd_list[fd].in_flight = 1; - task = iscsi_read10_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, offset / iscsi_fd_list[fd].block_size, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size); + task = iscsi_read10_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, offset / iscsi_fd_list[fd].block_size, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); iscsi_fd_list[fd].in_flight = 0; if (task == NULL || task->status != SCSI_STATUS_GOOD) { fprintf(stderr, "ld-iscsi: failed to send read10 command\n"); diff --git a/test-tool/0100_read10_simple.c b/test-tool/0100_read10_simple.c index 83bff59..f4dcdf8 100644 --- a/test-tool/0100_read10_simple.c +++ b/test-tool/0100_read10_simple.c @@ -75,7 +75,7 @@ int T0100_read10_simple(const char *initiator, const char *url, int data_loss _U /* read the first 1 - 256 blocks at the start of the LUN */ printf("Reading first 1-256 blocks ... "); for (i=1; i<=256; i++) { - task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); @@ -97,7 +97,7 @@ int T0100_read10_simple(const char *initiator, const char *url, int data_loss _U /* read the last 1 - 256 blocks at the end of the LUN */ printf("Reading last 1-256 blocks ... "); for (i=1; i<=256; i++) { - task = iscsi_read10_sync(iscsi, lun, num_blocks +1 - i, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, num_blocks +1 - i, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0101_read10_beyond_eol.c b/test-tool/0101_read10_beyond_eol.c index 7daace5..7ee143b 100644 --- a/test-tool/0101_read10_beyond_eol.c +++ b/test-tool/0101_read10_beyond_eol.c @@ -75,7 +75,7 @@ int T0101_read10_beyond_eol(const char *initiator, const char *url, int data_los /* read 1-256 blocks, one block beyond the end-of-lun */ printf("Reading last 1-256 blocks one block beyond eol ... "); for (i=1; i<=256; i++) { - task = iscsi_read10_sync(iscsi, lun, num_blocks + 2 - i, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, num_blocks + 2 - i, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); @@ -106,7 +106,7 @@ int T0101_read10_beyond_eol(const char *initiator, const char *url, int data_los /* read 2-256 blocks, all but one block beyond the eol */ printf("Reading 1-255 blocks beyond eol starting at last block ... "); for (i=2; i<=256; i++) { - task = iscsi_read10_sync(iscsi, lun, num_blocks, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, num_blocks, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0102_read10_0blocks.c b/test-tool/0102_read10_0blocks.c index 8a478ec..f31b6bd 100644 --- a/test-tool/0102_read10_0blocks.c +++ b/test-tool/0102_read10_0blocks.c @@ -76,7 +76,7 @@ int T0102_read10_0blocks(const char *initiator, const char *url, int data_loss _ /* read10 0 blocks one block at lba 0 */ printf("Reading 0 blocks at lba:0 ... "); - task = iscsi_read10_sync(iscsi, lun, 0, 0, block_size); + task = iscsi_read10_sync(iscsi, lun, 0, 0, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); @@ -95,7 +95,7 @@ int T0102_read10_0blocks(const char *initiator, const char *url, int data_loss _ /* read10 0 blocks one block beyond the eol */ printf("Reading 0 blocks at one block beyond end ... "); - task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size); + task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); @@ -124,7 +124,7 @@ int T0102_read10_0blocks(const char *initiator, const char *url, int data_loss _ /* read10 0 blocks two blocks beyond the eol */ printf("Reading 0 blocks at two blocks beyond end ... "); - task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size); + task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); @@ -156,7 +156,7 @@ int T0102_read10_0blocks(const char *initiator, const char *url, int data_loss _ goto finished; } printf("Reading 0 blocks at lba:-1 ... "); - task = iscsi_read10_sync(iscsi, lun, 0xffffff, 0, block_size); + task = iscsi_read10_sync(iscsi, lun, 0xffffff, 0, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0130_verify10_simple.c b/test-tool/0130_verify10_simple.c index fef6019..622344e 100644 --- a/test-tool/0130_verify10_simple.c +++ b/test-tool/0130_verify10_simple.c @@ -77,7 +77,7 @@ int T0130_verify10_simple(const char *initiator, const char *url, int data_loss for (i = 1; i <= 256; i++) { unsigned char *buf; - task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0131_verify10_mismatch.c b/test-tool/0131_verify10_mismatch.c index 69cb8d8..24df52d 100644 --- a/test-tool/0131_verify10_mismatch.c +++ b/test-tool/0131_verify10_mismatch.c @@ -78,7 +78,7 @@ int T0131_verify10_mismatch(const char *initiator, const char *url, int data_los for (i = 1; i <= 256; i++) { unsigned char *buf; - task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi)); diff --git a/test-tool/0132_verify10_mismatch_no_cmp.c b/test-tool/0132_verify10_mismatch_no_cmp.c index 729d180..5dfff5b 100644 --- a/test-tool/0132_verify10_mismatch_no_cmp.c +++ b/test-tool/0132_verify10_mismatch_no_cmp.c @@ -78,7 +78,7 @@ int T0132_verify10_mismatch_no_cmp(const char *initiator, const char *url, int d for (i = 1; i <= 256; i++) { unsigned char *buf; - task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size); + task = iscsi_read10_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));