Merge branch 'requeue-pdu'
This commit is contained in:
@@ -257,12 +257,9 @@ struct iscsi_pdu {
|
||||
|
||||
struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi,
|
||||
enum iscsi_opcode opcode,
|
||||
enum iscsi_opcode response_opcode);
|
||||
struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi,
|
||||
enum iscsi_opcode opcode,
|
||||
enum iscsi_opcode response_opcode,
|
||||
uint32_t itt,
|
||||
uint32_t flags);
|
||||
enum iscsi_opcode response_opcode,
|
||||
uint32_t itt,
|
||||
uint32_t flags);
|
||||
void iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
||||
void iscsi_pdu_set_pduflags(struct iscsi_pdu *pdu, unsigned char flags);
|
||||
void iscsi_pdu_set_immediate(struct iscsi_pdu *pdu);
|
||||
@@ -279,7 +276,6 @@ void iscsi_pdu_set_bufferoffset(struct iscsi_pdu *pdu, uint32_t bufferoffset);
|
||||
int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
unsigned char *dptr, int dsize);
|
||||
int iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
||||
int iscsi_send_unsolicited_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
||||
|
||||
int iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
|
||||
unsigned char *dptr, int dsize, int pdualignment);
|
||||
@@ -328,6 +324,7 @@ void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string,
|
||||
|
||||
struct scsi_iovector *iscsi_get_scsi_task_iovector_in(struct iscsi_context *iscsi, struct iscsi_in_pdu *in);
|
||||
struct scsi_iovector *iscsi_get_scsi_task_iovector_out(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
||||
void scsi_task_reset_iov(struct scsi_iovector *iovector);
|
||||
|
||||
void* iscsi_malloc(struct iscsi_context *iscsi, size_t size);
|
||||
void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size);
|
||||
|
||||
@@ -343,37 +343,29 @@ try_again:
|
||||
|
||||
if (pdu->flags & ISCSI_PDU_DROP_ON_RECONNECT) {
|
||||
/*
|
||||
* We don't want to requeue NOPs or DATA-OUT PDUs.
|
||||
* In case of DATA-OUT PDUs that are part of the
|
||||
* initial unsolicited data we have to regenerate
|
||||
* them forther down so that we end the re-queued
|
||||
* WRITE + DATA-OUT train with a PDU with the F bit.
|
||||
*/
|
||||
* We only want to re-queue SCSI COMMAND PDUs.
|
||||
* All other PDUs are discarded at this point.
|
||||
* This includes DATA-OUT, NOP and task management.
|
||||
*/
|
||||
iscsi_free_pdu(old_iscsi, pdu);
|
||||
continue;
|
||||
}
|
||||
|
||||
pdu->itt = iscsi_itt_post_increment(iscsi);
|
||||
iscsi_pdu_set_itt(pdu, pdu->itt);
|
||||
scsi_task_reset_iov(&pdu->scsi_cbdata.task->iovector_in);
|
||||
scsi_task_reset_iov(&pdu->scsi_cbdata.task->iovector_out);
|
||||
|
||||
/* do not increase cmdsn for PDUs marked for immediate delivery
|
||||
* this will result in a protocol error */
|
||||
pdu->cmdsn = (pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE)?iscsi->cmdsn:iscsi->cmdsn++;
|
||||
iscsi_pdu_set_cmdsn(pdu, pdu->cmdsn);
|
||||
|
||||
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn);
|
||||
iscsi->statsn++;
|
||||
|
||||
pdu->outdata_written = 0;
|
||||
pdu->payload_written = 0;
|
||||
iscsi_queue_pdu(iscsi, pdu);
|
||||
/* Requeue any unsolicited data-out for the command PDU we
|
||||
* just re-queued. These are commands that write data to the
|
||||
* device but does not have the F bit set.
|
||||
/* We pass NULL as 'd' since any databuffer has already
|
||||
* been converted to a task-> iovector first time this
|
||||
* PDU was sent.
|
||||
*/
|
||||
if ((pdu->outdata.data[1] & (ISCSI_PDU_SCSI_WRITE | ISCSI_PDU_SCSI_FINAL)) == ISCSI_PDU_SCSI_WRITE) {
|
||||
iscsi_send_unsolicited_data_out(iscsi, pdu);
|
||||
if (iscsi_scsi_command_async(iscsi, pdu->lun,
|
||||
pdu->scsi_cbdata.task,
|
||||
pdu->scsi_cbdata.callback,
|
||||
NULL,
|
||||
pdu->scsi_cbdata.private_data)) {
|
||||
/* not much we can really do at this point */
|
||||
}
|
||||
iscsi_free_pdu(old_iscsi, pdu);
|
||||
}
|
||||
|
||||
if (dup2(iscsi->fd, old_iscsi->fd) == -1) {
|
||||
|
||||
@@ -46,7 +46,9 @@ iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_TEXT_REQUEST,
|
||||
ISCSI_PDU_TEXT_RESPONSE);
|
||||
ISCSI_PDU_TEXT_RESPONSE,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
ISCSI_PDU_DROP_ON_RECONNECT);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
||||
"text pdu.");
|
||||
|
||||
@@ -78,10 +78,11 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
|
||||
|
||||
len = MIN(len, iscsi->target_max_recv_data_segment_length);
|
||||
|
||||
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT,
|
||||
ISCSI_PDU_NO_PDU,
|
||||
cmd_pdu->itt,
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_DATA_OUT,
|
||||
ISCSI_PDU_NO_PDU,
|
||||
cmd_pdu->itt,
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
||||
"scsi data out pdu.");
|
||||
@@ -188,7 +189,7 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
iscsi_send_unsolicited_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
{
|
||||
uint32_t len = MIN(pdu->expxferlen, iscsi->first_burst_length) - pdu->payload_len;
|
||||
@@ -235,8 +236,11 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
||||
scsi_task_set_iov_out(task, iov, 1);
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_SCSI_REQUEST,
|
||||
ISCSI_PDU_SCSI_RESPONSE);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_SCSI_REQUEST,
|
||||
ISCSI_PDU_SCSI_RESPONSE,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
0);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
||||
"scsi pdu.");
|
||||
|
||||
17
lib/login.c
17
lib/login.c
@@ -730,10 +730,11 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi,
|
||||
ISCSI_PDU_LOGIN_REQUEST,
|
||||
ISCSI_PDU_LOGIN_RESPONSE,
|
||||
iscsi->itt, 0);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_LOGIN_REQUEST,
|
||||
ISCSI_PDU_LOGIN_RESPONSE,
|
||||
iscsi->itt,
|
||||
ISCSI_PDU_DROP_ON_RECONNECT);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
||||
"login pdu.");
|
||||
@@ -1122,8 +1123,11 @@ iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_LOGOUT_REQUEST,
|
||||
ISCSI_PDU_LOGOUT_RESPONSE);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_LOGOUT_REQUEST,
|
||||
ISCSI_PDU_LOGOUT_RESPONSE,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_CORK_WHEN_SENT|flags);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
||||
"logout pdu.");
|
||||
@@ -1145,7 +1149,6 @@ iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
|
||||
pdu->callback = cb;
|
||||
pdu->private_data = private_data;
|
||||
pdu->flags |= ISCSI_PDU_CORK_WHEN_SENT | flags;
|
||||
|
||||
if (iscsi_queue_pdu(iscsi, pdu) != 0) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
|
||||
|
||||
16
lib/nop.c
16
lib/nop.c
@@ -36,15 +36,16 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_NOP_OUT, ISCSI_PDU_NOP_IN);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_NOP_OUT,
|
||||
ISCSI_PDU_NOP_IN,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
ISCSI_PDU_DROP_ON_RECONNECT);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Failed to allocate nop-out pdu");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We don't want to requeue these on reconnect */
|
||||
pdu->flags |= ISCSI_PDU_DROP_ON_RECONNECT;
|
||||
|
||||
/* immediate flag */
|
||||
iscsi_pdu_set_immediate(pdu);
|
||||
|
||||
@@ -91,8 +92,11 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt)
|
||||
{
|
||||
struct iscsi_pdu *pdu;
|
||||
|
||||
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_NOP_OUT, ISCSI_PDU_NO_PDU,
|
||||
0xffffffff,ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_NOP_OUT,
|
||||
ISCSI_PDU_NO_PDU,
|
||||
0xffffffff,
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Failed to allocate nop-out pdu");
|
||||
return -1;
|
||||
|
||||
16
lib/pdu.c
16
lib/pdu.c
@@ -104,8 +104,9 @@ void iscsi_dump_pdu_header(struct iscsi_context *iscsi, unsigned char *data) {
|
||||
}
|
||||
|
||||
struct iscsi_pdu *
|
||||
iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
||||
enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags)
|
||||
iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
||||
enum iscsi_opcode response_opcode, uint32_t itt,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct iscsi_pdu *pdu;
|
||||
|
||||
@@ -143,13 +144,6 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode
|
||||
return pdu;
|
||||
}
|
||||
|
||||
struct iscsi_pdu *
|
||||
iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
||||
enum iscsi_opcode response_opcode)
|
||||
{
|
||||
return iscsi_allocate_pdu_with_itt_flags(iscsi, opcode, response_opcode, iscsi_itt_post_increment(iscsi), 0);
|
||||
}
|
||||
|
||||
void
|
||||
iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
{
|
||||
@@ -371,7 +365,7 @@ int iscsi_process_reject(struct iscsi_context *iscsi,
|
||||
|
||||
if (reason == ISCSI_REJECT_WAITING_FOR_LOGOUT) {
|
||||
ISCSI_LOG(iscsi, 1, "target rejects request with reason: %s", iscsi_reject_reason_str(reason));
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_URGENT_DELIVERY);
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_URGENT_DELIVERY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -441,7 +435,7 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
||||
ISCSI_LOG(iscsi, 2, "dropping connection to fix errors with broken DELL Equallogic firmware 7.x");
|
||||
return -1;
|
||||
}
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_URGENT_DELIVERY);
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_URGENT_DELIVERY);
|
||||
return 0;
|
||||
case 0x2:
|
||||
ISCSI_LOG(iscsi, 2, "target will drop this connection. Time2Wait is %u seconds", param2);
|
||||
|
||||
@@ -3817,6 +3817,14 @@ scsi_task_set_iov_in(struct scsi_task *task, struct scsi_iovec *iov, int niov)
|
||||
task->iovector_in.niov = niov;
|
||||
}
|
||||
|
||||
void
|
||||
scsi_task_reset_iov(struct scsi_iovector *iovector)
|
||||
{
|
||||
iovector->nalloc = 0;
|
||||
iovector->offset = 0;
|
||||
iovector->consumed = 0;
|
||||
}
|
||||
|
||||
#define IOVECTOR_INITAL_ALLOC (16)
|
||||
|
||||
static int
|
||||
|
||||
@@ -49,8 +49,11 @@ iscsi_task_mgmt_async(struct iscsi_context *iscsi,
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_SCSI_TASK_MANAGEMENT_REQUEST,
|
||||
ISCSI_PDU_SCSI_TASK_MANAGEMENT_RESPONSE);
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_SCSI_TASK_MANAGEMENT_REQUEST,
|
||||
ISCSI_PDU_SCSI_TASK_MANAGEMENT_RESPONSE,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
ISCSI_PDU_DROP_ON_RECONNECT);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Failed to allocate task mgmt pdu");
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user