From 4bc5f962e2f0655734d0cc9cfe327d2800b7ac79 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 3 Jan 2017 23:58:20 +0100 Subject: [PATCH] Libiscsi: add support for EXTENDED COPY Build on existing scsi_cdb_extended_copy() functionality. This operation can be used to offload inter and intra LU copies to the target. The API is rather primitive, in that the caller needs to construct the parameter buffer, including CSCD and segment descriptor lists, etc. 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 58385de..cb8a557 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1134,6 +1134,11 @@ 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); +EXTERN struct scsi_task * +iscsi_extended_copy_task(struct iscsi_context *iscsi, int lun, + struct iscsi_data *param_data, + iscsi_command_cb cb, void *private_data); + /* * Sync commands for SCSI */ @@ -1459,6 +1464,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_extended_copy_sync(struct iscsi_context *iscsi, int lun, + struct iscsi_data *param_data); + EXTERN struct scsi_task * iscsi_receive_copy_results_sync(struct iscsi_context *iscsi, int lun, int sa, int list_id, int alloc_len); diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 3375974..f9ca8e0 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -2634,6 +2634,29 @@ iscsi_receive_copy_results_task(struct iscsi_context *iscsi, int lun, return task; } +struct scsi_task * +iscsi_extended_copy_task(struct iscsi_context *iscsi, int lun, + struct iscsi_data *param_data, + iscsi_command_cb cb, void *private_data) +{ + struct scsi_task *task; + + task = scsi_cdb_extended_copy(param_data->size); + if (task == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to create " + "EXTENDED COPY cdb."); + return NULL; + } + + if (iscsi_scsi_command_async(iscsi, lun, task, cb, + param_data, 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 3bf1fd8..ea5c940 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_extended_copy_sync +iscsi_extended_copy_task iscsi_receive_copy_results_sync iscsi_receive_copy_results_task iscsi_reconnect diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index 946dc2c..5d81f44 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_extended_copy_sync +iscsi_extended_copy_task iscsi_receive_copy_results_sync iscsi_receive_copy_results_task iscsi_reconnect diff --git a/lib/sync.c b/lib/sync.c index c5a82a6..3b907c0 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -1687,6 +1687,26 @@ iscsi_receive_copy_results_sync(struct iscsi_context *iscsi, int lun, return state.task; } +struct scsi_task * +iscsi_extended_copy_sync(struct iscsi_context *iscsi, int lun, + struct iscsi_data *param_data) +{ + struct iscsi_sync_state state; + + memset(&state, 0, sizeof(state)); + + if (iscsi_extended_copy_task(iscsi, lun, param_data, + scsi_sync_cb, &state) == NULL) { + iscsi_set_error(iscsi, "Failed to send EXTENDED COPY" + " 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)