Change iscsi_scsi_command_async() to use iovectors for writes.
Change iscsi_scsi_command_async() to write data-out using iovectors attached to the scsi task structure instead of copying the data into the buffer holding the header. Still allow passing the data via an argument to the funtcion so that the ABI does not change but then just conver the data to an iovector. Update the write_to_socket functions to know about the iovectors and write them as part of the pdu. Convert write10_task to use iovectors. This will allow 'zero-copy' writes through libiscsi. However, as 'zero-copy writes does mean that we do more send() calls into the kernel this may degrade performance for very small i/o. A scsi write will not take at least 2 send() calls. One send call for the iscsi header structure and a second send call for the payload data. This will be more expensive than the old memcpy() of payload data plus one send() call since the send() will be a lot more expensive than memcpy() of a small amount of data.
This commit is contained in:
@@ -211,7 +211,11 @@ struct iscsi_pdu {
|
||||
void *private_data;
|
||||
|
||||
int written;
|
||||
struct iscsi_data outdata; /* Header and Immediate Data */
|
||||
|
||||
struct iscsi_data outdata; /* Header for PDU to send */
|
||||
uint32_t out_offset; /* Offset into data-out iovector */
|
||||
uint32_t out_len; /* Amount of data to sent */
|
||||
|
||||
struct iscsi_data indata;
|
||||
|
||||
struct iscsi_data nidata; /* Non-Immediate Data */
|
||||
@@ -296,7 +300,8 @@ void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string,
|
||||
...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
unsigned char *iscsi_get_user_in_buffer(struct iscsi_context *iscsi, struct iscsi_in_pdu *in, uint32_t pos, ssize_t *count);
|
||||
unsigned char *scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos, ssize_t *count);
|
||||
unsigned char *iscsi_get_user_out_buffer(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, uint32_t pos, ssize_t *count);
|
||||
|
||||
|
||||
inline void* iscsi_malloc(struct iscsi_context *iscsi, size_t size);
|
||||
inline void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size);
|
||||
|
||||
@@ -690,6 +690,9 @@ EXTERN int scsi_datain_getfullsize(struct scsi_task *task);
|
||||
EXTERN void *scsi_datain_unmarshall(struct scsi_task *task);
|
||||
EXTERN void *scsi_cdb_unmarshall(struct scsi_task *task, enum scsi_opcode opcode);
|
||||
|
||||
unsigned char *scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos, ssize_t *count);
|
||||
unsigned char *scsi_task_get_data_out_buffer(struct scsi_task *task, uint32_t pos, ssize_t *count);
|
||||
|
||||
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, 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);
|
||||
|
||||
Reference in New Issue
Block a user