Merge pull request #332 from bytedance/fix_cancellation_handling
Fix cancellation handling
This commit is contained in:
@@ -271,7 +271,7 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
|
iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
|
||||||
|
|
||||||
/* cmdsn */
|
/* cmdsn */
|
||||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++);
|
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||||
|
|
||||||
/* cdb */
|
/* cdb */
|
||||||
iscsi_pdu_set_cdb(pdu, task);
|
iscsi_pdu_set_cdb(pdu, task);
|
||||||
@@ -285,6 +285,7 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
iscsi->drv->free_pdu(iscsi, pdu);
|
iscsi->drv->free_pdu(iscsi, pdu);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
iscsi->cmdsn++;
|
||||||
|
|
||||||
/* The F flag is not set. This means we haven't sent all the unsolicited
|
/* The F flag is not set. This means we haven't sent all the unsolicited
|
||||||
* data yet. Sent as much as we are allowed as a train of DATA-OUT PDUs.
|
* data yet. Sent as much as we are allowed as a train of DATA-OUT PDUs.
|
||||||
@@ -2667,6 +2668,9 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
|
|||||||
struct scsi_task *task)
|
struct scsi_task *task)
|
||||||
{
|
{
|
||||||
struct iscsi_pdu *pdu;
|
struct iscsi_pdu *pdu;
|
||||||
|
struct iscsi_pdu *next_pdu;
|
||||||
|
uint32_t cmdsn_gap = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
||||||
if (pdu->itt == task->itt) {
|
if (pdu->itt == task->itt) {
|
||||||
@@ -2679,22 +2683,45 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
|
for (pdu = iscsi->outqueue; pdu; pdu = next_pdu) {
|
||||||
|
next_pdu = pdu->next;
|
||||||
|
|
||||||
|
if (cmdsn_gap > 0) {
|
||||||
|
iscsi_pdu_set_cmdsn(pdu, pdu->cmdsn - cmdsn_gap);
|
||||||
|
}
|
||||||
|
|
||||||
if (pdu->itt == task->itt) {
|
if (pdu->itt == task->itt) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if (pdu->callback) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
|
if (!(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) &&
|
||||||
|
(pdu->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) {
|
||||||
|
iscsi->cmdsn--;
|
||||||
|
cmdsn_gap++;
|
||||||
|
}
|
||||||
iscsi->drv->free_pdu(iscsi, pdu);
|
iscsi->drv->free_pdu(iscsi, pdu);
|
||||||
return 0;
|
ret = 0;
|
||||||
|
if (!cmdsn_gap) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
if (iscsi->old_iscsi) {
|
||||||
|
return iscsi_scsi_cancel_task(iscsi->old_iscsi, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi)
|
iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi)
|
||||||
{
|
{
|
||||||
iscsi_cancel_pdus(iscsi);
|
iscsi_cancel_pdus(iscsi);
|
||||||
|
|
||||||
|
if (iscsi->old_iscsi) {
|
||||||
|
iscsi_cancel_pdus(iscsi->old_iscsi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
iscsi_pdu_set_lun(pdu, 0);
|
iscsi_pdu_set_lun(pdu, 0);
|
||||||
|
|
||||||
/* cmdsn */
|
/* cmdsn */
|
||||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++);
|
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||||
|
|
||||||
pdu->callback = cb;
|
pdu->callback = cb;
|
||||||
pdu->private_data = private_data;
|
pdu->private_data = private_data;
|
||||||
@@ -83,6 +83,7 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iscsi->cmdsn++;
|
||||||
iscsi->nops_in_flight++;
|
iscsi->nops_in_flight++;
|
||||||
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
||||||
"NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)",
|
"NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)",
|
||||||
|
|||||||
25
lib/pdu.c
25
lib/pdu.c
@@ -719,10 +719,14 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
|||||||
struct iscsi_pdu *pdu;
|
struct iscsi_pdu *pdu;
|
||||||
struct iscsi_pdu *next_pdu;
|
struct iscsi_pdu *next_pdu;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
uint32_t cmdsn_gap = 0;
|
||||||
|
|
||||||
for (pdu = iscsi->outqueue; pdu; pdu = next_pdu) {
|
for (pdu = iscsi->outqueue; pdu; pdu = next_pdu) {
|
||||||
next_pdu = pdu->next;
|
next_pdu = pdu->next;
|
||||||
|
|
||||||
|
if (cmdsn_gap > 0) {
|
||||||
|
iscsi_pdu_set_cmdsn(pdu, pdu->cmdsn - cmdsn_gap);
|
||||||
|
}
|
||||||
if (pdu->scsi_timeout == 0) {
|
if (pdu->scsi_timeout == 0) {
|
||||||
/* no timeout for this pdu */
|
/* no timeout for this pdu */
|
||||||
continue;
|
continue;
|
||||||
@@ -731,6 +735,11 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
|||||||
/* not expired yet */
|
/* not expired yet */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) &&
|
||||||
|
(pdu->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) {
|
||||||
|
iscsi->cmdsn--;
|
||||||
|
cmdsn_gap++;
|
||||||
|
}
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
iscsi_set_error(iscsi, "command timed out");
|
iscsi_set_error(iscsi, "command timed out");
|
||||||
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
||||||
@@ -775,21 +784,21 @@ iscsi_cancel_pdus(struct iscsi_context *iscsi)
|
|||||||
|
|
||||||
while ((pdu = iscsi->outqueue)) {
|
while ((pdu = iscsi->outqueue)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if (iscsi->is_loggedin && pdu->callback) {
|
if (pdu->callback) {
|
||||||
/* If an error happened during connect/login,
|
|
||||||
we don't want to call any of the callbacks.
|
|
||||||
*/
|
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
||||||
NULL, pdu->private_data);
|
NULL, pdu->private_data);
|
||||||
}
|
}
|
||||||
iscsi->drv->free_pdu(iscsi, pdu);
|
iscsi->drv->free_pdu(iscsi, pdu);
|
||||||
|
if (!(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) &&
|
||||||
|
(pdu->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) {
|
||||||
|
iscsi->cmdsn--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
while ((pdu = iscsi->waitpdu)) {
|
while ((pdu = iscsi->waitpdu)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
if (iscsi->is_loggedin && pdu->callback) {
|
if (pdu->callback) {
|
||||||
/* If an error happened during connect/login,
|
|
||||||
we don't want to call any of the callbacks.
|
|
||||||
*/
|
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
||||||
NULL, pdu->private_data);
|
NULL, pdu->private_data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -913,7 +913,7 @@ iscsi_tcp_service(struct iscsi_context *iscsi, int revents)
|
|||||||
return iscsi_reconnect(iscsi);
|
return iscsi_reconnect(iscsi);
|
||||||
} else {
|
} else {
|
||||||
if (iscsi->old_iscsi) {
|
if (iscsi->old_iscsi) {
|
||||||
return 0;
|
goto check_timeout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -999,8 +999,14 @@ iscsi_tcp_service(struct iscsi_context *iscsi, int revents)
|
|||||||
return iscsi_service_reconnect_if_loggedin(iscsi);
|
return iscsi_service_reconnect_if_loggedin(iscsi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_timeout:
|
||||||
iscsi_timeout_scan(iscsi);
|
iscsi_timeout_scan(iscsi);
|
||||||
|
|
||||||
|
if (iscsi->old_iscsi) {
|
||||||
|
iscsi_timeout_scan(iscsi->old_iscsi);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user