Merge branch 'requeue-pdu'

This commit is contained in:
Ronnie Sahlberg
2015-03-02 19:47:23 -08:00
9 changed files with 72 additions and 65 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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.");

View File

@@ -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.");

View File

@@ -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 "

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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;