From 83dd83c82ae2bed638dd2ecd72e904aaa2183f38 Mon Sep 17 00:00:00 2001 From: Sebastian Vater Date: Wed, 17 Sep 2025 09:35:41 +0200 Subject: Implemented iSCSI SCSI emulation read and write operations on DNBD3 image without threading. Also fixed some bugs and finally, fixed doxygen documention. --- src/server/iscsi.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 3 deletions(-) (limited to 'src/server/iscsi.h') diff --git a/src/server/iscsi.h b/src/server/iscsi.h index 40f6438..e379370 100644 --- a/src/server/iscsi.h +++ b/src/server/iscsi.h @@ -283,7 +283,7 @@ typedef struct iscsi_hashmap { } iscsi_hashmap; /** - * @brief A Callback for iterating over map, freeing and removing entries. user_data is free for personal use. + * @brief Callback for iterating over map, freeing and removing entries. user_data is free for personal use. * * Callback function. This is a pointer to a * function for various purposes like iterating @@ -9923,12 +9923,67 @@ typedef struct iscsi_scsi_task iscsi_scsi_task; typedef struct iscsi_scsi_lun iscsi_scsi_lun; -/// Callback function when SCSI transfer is completed. +/** + * @brief Callback when iSCSI SCSI transfer task completed. + * + * This function is invoked when an iSCSI task + * finished a transfer. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task which + * completed the transfer and may NOT be NULL, + * so be careful. + */ typedef void (*iscsi_scsi_task_xfer_complete_callback)(iscsi_scsi_task *scsi_task); -/// Callback function for SCSI task destruction. +/** + * @brief Callback when iSCSI SCSI transfer task destruction. + * + * This function is invoked when an iSCSI task + * needs to be destroyed. + * + * @param[in] scsi_task Pointer to iSCSI SCSI task which + * is about to be destroyed and may NOT be + * NULL, so be careful. + */ typedef void (*iscsi_scsi_task_destroy_callback)(iscsi_scsi_task *scsi_task); +/** + * @brief Callback for I/O operation completion. + * + * This function is invoked when an I/O operation + * has been completed. + * + * @param[in] image Pointer to DNBD3 image which completed the + * I/O operation. + * @param[in] user_data Pointer to user data. + * @param[in] success true if I/O completed successfully or false + * if it failed instead. + */ +typedef void (*iscsi_scsi_emu_io_complete_callback)(dnbd3_image_t *image, uint8_t *user_data, const bool success); + +/** + * @brief Callback for I/O wait operation. + * + * This function is invoked when an I/O + * operation needs waiting. + * + * @param[in] user_data Pointer to user data. + * @return Pointer to optional user data. + */ +typedef uint8_t *(*iscsi_scsi_emu_io_wait_callback)(uint8_t *user_data); + + +typedef struct iscsi_scsi_emu_io_wait { + /// I/O task wait callback associated DNBD3 image. + dnbd3_image_t *image; + + /// I/O task wait callback function. + iscsi_scsi_emu_io_wait_callback callback; + + /// I/O task wait callback user data. + uint8_t *user_data; +} iscsi_scsi_emu_io_wait; + /// iSCSI SCSI task flags: Read. #define ISCSI_SCSI_TASK_FLAGS_XFER_READ (1 << 0) @@ -9965,6 +10020,12 @@ typedef struct iscsi_scsi_task { /// Task destruction callback function. iscsi_scsi_task_destroy_callback destroy_callback; + /// I/O task complete callback function. + iscsi_scsi_emu_io_complete_callback io_complete_callback; + + /// I/O task wait. + iscsi_scsi_emu_io_wait io_wait; + /// Output buffer. uint8_t *buf; @@ -10075,6 +10136,14 @@ int iscsi_scsi_pr_in(iscsi_scsi_task *scsi_task, iscsi_scsi_pr_reserve_in_parame int iscsi_scsi_pr_reserve_scsi2(iscsi_scsi_task *scsi_task, const iscsi_scsi_cdb_pr_reserve_6 *cdb_pr_reserve_6); // Reserves an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task int iscsi_scsi_pr_release_scsi2(iscsi_scsi_task *scsi_task); // Releases an iSCSI SCSI Persistent Reservation (PR) of an iSCSI SCSI task +int iscsi_scsi_emu_io_blocks_read(iscsi_scsi_task *scsi_task, uint8_t *buf, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Reads a number of blocks from a block offset of a DNBD3 image to a specified buffer +void iscsi_scsi_emu_block_read_complete_callback(dnbd3_image_t *image, uint8_t *user_data, const bool success); // Completes an iSCSI SCSI task after a finished I/O read operation +int iscsi_scsi_emu_io_blocks_cmp_write(iscsi_scsi_task *scsi_task, uint8_t *buf, uint8_t *cmp_buf, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Compares and writes a number of blocks starting from a block offset in a DNBD3 image with specified buffers +void iscsi_scsi_emu_block_write_complete_callback(dnbd3_image_t *image, uint8_t *user_data, const bool success); // Completes an iSCSI SCSI task after a finished I/O write operation +int iscsi_scsi_emu_io_blocks_write(iscsi_scsi_task *scsi_task, uint8_t *buf, dnbd3_image_t *image, const uint64_t offset_blocks, const uint64_t num_blocks, const uint32_t block_size, iscsi_scsi_emu_io_complete_callback callback, uint8_t *user_data); // Writes a number of blocks from a block offset to a DNBD3 image of a specified buffer +int iscsi_scsi_emu_io_queue(iscsi_scsi_emu_io_wait *io_wait); // Enqueues an I/O wait in the thread pool to execute +uint8_t *iscsi_scsi_emu_block_resubmit_process_callback(uint8_t *user_data); // Resubmits an iSCSI SCSI task for execution + int iscsi_scsi_emu_primary_inquiry_callback(uint8_t *key, const size_t key_size, uint8_t *value, uint8_t *user_data); // Fills in a single Vital Product Data (VPD) SCSI Port Designation Descriptor entry of an INQUIRY operation int iscsi_scsi_emu_exec(iscsi_scsi_task *scsi_task); // Executes the iSCSI SCSI emulation for an iSCSI SCSI task -- cgit v1.2.3-55-g7522