libiscsi: Avoid discontinuities in cmdsn ordering in some cases
We should plug the cmdsn gap in order to continue to use the session when the pdus is cancelled before sending out. Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
This commit is contained in:
15
lib/pdu.c
15
lib/pdu.c
@@ -719,10 +719,14 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
||||
struct iscsi_pdu *pdu;
|
||||
struct iscsi_pdu *next_pdu;
|
||||
time_t t = time(NULL);
|
||||
uint32_t cmdsn_gap = 0;
|
||||
|
||||
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->scsi_timeout == 0) {
|
||||
/* no timeout for this pdu */
|
||||
continue;
|
||||
@@ -731,6 +735,11 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
||||
/* not expired yet */
|
||||
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_set_error(iscsi, "command timed out");
|
||||
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
||||
@@ -783,6 +792,12 @@ iscsi_cancel_pdus(struct iscsi_context *iscsi)
|
||||
NULL, pdu->private_data);
|
||||
}
|
||||
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)) {
|
||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||
|
||||
Reference in New Issue
Block a user