iscsi: fix iscsi task refcount for out of order write completions
For large writes that require multiple SCSI tasks (one for immediate data, then one or more for R2T-solicited data), we bump the refcount for the task associated with the initial immediate data PDU, to ensure it does not get freed until all of the child tasks are completed. But in some cases this initial immediate data PDU could complete after all of the R2T-soliciated data PDUs. The completion code was not handling this case correctly which would result in the iSCSI connection thinking it still had outstanding SCSI tasks when the connection closed. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I9f9c5322755462d1918fde0075c87c84295cb10c
This commit is contained in:
parent
eef39e8d35
commit
9459848ce5
@ -920,7 +920,15 @@ void process_task_completion(spdk_event_t event)
|
||||
if (primary->scsi.bytes_completed == primary->scsi.transfer_len) {
|
||||
spdk_del_transfer_task(conn, primary->scsi.id);
|
||||
spdk_iscsi_task_response(conn, primary);
|
||||
if (task != primary) {
|
||||
/*
|
||||
* Check if this is the last task completed for an iSCSI write
|
||||
* that required child subtasks. If task != primary, we know
|
||||
* for sure that it was part of an iSCSI write with child subtasks.
|
||||
* The trickier case is when the last task completed was the initial
|
||||
* task - in this case the task will have a smaller length than
|
||||
* the overall transfer length.
|
||||
*/
|
||||
if (task != primary || task->scsi.length != task->scsi.transfer_len) {
|
||||
TAILQ_REMOVE(&conn->active_r2t_tasks, primary, link);
|
||||
spdk_iscsi_task_put(primary);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user