On Thu, Jun 27, 2013 at 03:11:27PM +0200, Peter Lieven wrote: > @@ -113,6 +122,45 @@ iscsi_schedule_bh(IscsiAIOCB *acb) > qemu_bh_schedule(acb->bh); > } > > +static void > +iscsi_co_generic_cb(struct iscsi_context *iscsi, int status, > + void *command_data, void *opaque) > +{ > + struct IscsiTask *iTask = opaque; > + struct scsi_task *task = command_data; > + > + iTask->complete = 1; > + iTask->status = status; > + iTask->do_retry = 0; > + iTask->task = task; > + > + if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION > + && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) { > + iTask->do_retry = 1; > + goto out; > + } > + > + if (status != SCSI_STATUS_GOOD) { > + error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi)); > + goto out; > + } > + > +out: > + if (iTask->status != SCSI_STATUS_GOOD) { > + scsi_free_scsi_task(iTask->task); > + iTask->task = NULL; > + }
Not sure about freeing the task here since the caller is still responsible for freeing the task in the success case and higher-level error cases. I suggest keeping iTask->task alive here so the caller is easier to maintain (it can use a single out/error path).