From f475436c5abf4312779f6083e6c76dfe05fb095e Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 3 Jan 2017 19:33:01 +0100 Subject: [PATCH] Libiscsi: add support for RECEIVE COPY RESULTS Build on existing scsi_cdb_receive_copy_results() functionality. This request is most commonly used to determine target-side EXTENDED COPY operational parameters. Signed-off-by: David Disseldorp --- include/iscsi.h | 9 +++++++++ lib/iscsi-command.c | 23 +++++++++++++++++++++++ lib/libiscsi.def | 2 ++ lib/libiscsi.syms | 2 ++ lib/sync.c | 20 ++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/include/iscsi.h b/include/iscsi.h index 30917a0..58385de 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1129,6 +1129,11 @@ iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, int lun, uint32_t alloc_len, iscsi_command_cb cb, void *private_data); +EXTERN struct scsi_task * +iscsi_receive_copy_results_task(struct iscsi_context *iscsi, int lun, + int sa, int list_id, int alloc_len, + iscsi_command_cb cb, void *private_data); + /* * Sync commands for SCSI */ @@ -1454,6 +1459,10 @@ iscsi_report_supported_opcodes_sync(struct iscsi_context *iscsi, int lun, int opcode, int sa, uint32_t alloc_len); +EXTERN struct scsi_task * +iscsi_receive_copy_results_sync(struct iscsi_context *iscsi, int lun, + int sa, int list_id, int alloc_len); + /* * These functions are used when the application wants to specify its own buffers to read the data * from the DATA-IN PDUs into, or write the data to DATA-OUT PDUs from. diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 9f8c0e8..3375974 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -2611,6 +2611,29 @@ iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, int lun, return task; } +struct scsi_task * +iscsi_receive_copy_results_task(struct iscsi_context *iscsi, int lun, + int sa, int list_id, int alloc_len, + iscsi_command_cb cb, void *private_data) +{ + struct scsi_task *task; + + task = scsi_cdb_receive_copy_results(sa, list_id, alloc_len); + if (task == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to create " + "RECEIVE COPY RESULTS cdb."); + return NULL; + } + + if (iscsi_scsi_command_async(iscsi, lun, task, cb, + NULL, private_data) != 0) { + scsi_free_scsi_task(task); + return NULL; + } + + return task; +} + struct scsi_task * iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu) { diff --git a/lib/libiscsi.def b/lib/libiscsi.def index 81ebe60..3bf1fd8 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -83,6 +83,8 @@ iscsi_release6_sync iscsi_release6_task iscsi_report_supported_opcodes_sync iscsi_report_supported_opcodes_task +iscsi_receive_copy_results_sync +iscsi_receive_copy_results_task iscsi_reconnect iscsi_sanitize_sync iscsi_sanitize_task diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index b3f3cac..946dc2c 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -81,6 +81,8 @@ iscsi_release6_sync iscsi_release6_task iscsi_report_supported_opcodes_sync iscsi_report_supported_opcodes_task +iscsi_receive_copy_results_sync +iscsi_receive_copy_results_task iscsi_reconnect iscsi_sanitize_sync iscsi_sanitize_task diff --git a/lib/sync.c b/lib/sync.c index 9fb78e7..c5a82a6 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -1667,6 +1667,26 @@ iscsi_report_supported_opcodes_sync(struct iscsi_context *iscsi, int lun, return state.task; } +struct scsi_task * +iscsi_receive_copy_results_sync(struct iscsi_context *iscsi, int lun, + int sa, int list_id, int alloc_len) +{ + struct iscsi_sync_state state; + + memset(&state, 0, sizeof(state)); + + if (iscsi_receive_copy_results_task(iscsi, lun, sa, list_id, alloc_len, + scsi_sync_cb, &state) == NULL) { + iscsi_set_error(iscsi, "Failed to send RECEIVE COPY RESULTS" + " command"); + return NULL; + } + + event_loop(iscsi, &state); + + return state.task; +} + struct scsi_task * iscsi_scsi_command_sync(struct iscsi_context *iscsi, int lun, struct scsi_task *task, struct iscsi_data *data)