Fix race between queueing the pdu and update the task data
After we have called iscsi_queue_pdu from iscsi_scsi_command_async the pdu might have already completed if we are using multithreading so we should not dereference pdu at that point. Move the assignment of task->cmdsn and task->itt we need for task management into iscsi_pdu_set_cmdsn instead. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
@@ -267,6 +267,7 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
/* lun */
|
/* lun */
|
||||||
iscsi_pdu_set_lun(pdu, lun);
|
iscsi_pdu_set_lun(pdu, lun);
|
||||||
pdu->lun = lun;
|
pdu->lun = lun;
|
||||||
|
task->lun = lun;
|
||||||
|
|
||||||
/* expxferlen */
|
/* expxferlen */
|
||||||
iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
|
iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
|
||||||
@@ -290,11 +291,6 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
iscsi_send_unsolicited_data_out(iscsi, pdu);
|
iscsi_send_unsolicited_data_out(iscsi, pdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remember cmdsn and itt so we can use task management */
|
|
||||||
task->cmdsn = pdu->cmdsn;
|
|
||||||
task->itt = pdu->itt;
|
|
||||||
task->lun = lun;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -800,6 +800,11 @@ iscsi_pdu_set_cmdsn(struct iscsi_pdu *pdu, uint32_t cmdsn)
|
|||||||
{
|
{
|
||||||
scsi_set_uint32(&pdu->outdata.data[24], cmdsn);
|
scsi_set_uint32(&pdu->outdata.data[24], cmdsn);
|
||||||
pdu->cmdsn = cmdsn;
|
pdu->cmdsn = cmdsn;
|
||||||
|
if (pdu->scsi_cbdata.task) {
|
||||||
|
/* remember cmdsn and itt so we can use task management */
|
||||||
|
pdu->scsi_cbdata.task->cmdsn = pdu->cmdsn;
|
||||||
|
pdu->scsi_cbdata.task->itt = pdu->itt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
|||||||
|
|
||||||
finished:
|
finished:
|
||||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||||
|
|
||||||
/* TODO QQQ need to immediately send for the non multithreading case too
|
/* TODO QQQ need to immediately send for the non multithreading case too
|
||||||
* and for the Windows API too */
|
* and for the Windows API too */
|
||||||
#if defined(HAVE_MULTITHREADING) && defined(HAVE_PTHREAD)
|
#if defined(HAVE_MULTITHREADING) && defined(HAVE_PTHREAD)
|
||||||
|
|||||||
Reference in New Issue
Block a user