Mike Christie wrote:
> Hannes Reinecke wrote:
>> Whenever we send a Data-Out response to an affected LUN during
>> LU Reset, we should be setting the 'FINAL' bit. This will
>> indicate to the target that we consider this transfer finished.
>>
>> Signed-off-by: Hannes Reinecke <h...@suse.de>
>> ---
>>  drivers/scsi/libiscsi.c |    4 ++++
>>  1 files changed, 4 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
>> index a0d1217..16d35f0 100644
>> --- a/drivers/scsi/libiscsi.c
>> +++ b/drivers/scsi/libiscsi.c
>> @@ -321,6 +321,10 @@ static int iscsi_check_tmf_restrictions(struct
>> iscsi_task *task, int opcode)
>>                        task->itt, task->hdr_itt, hdr_lun);
>>              return -EACCES;
>>          }
>> +        /*
>> +         * Set FINAL flag to terminate data transfer.
>> +         */
>> +        task->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
> 
> 
> Wasn't this in the first patch before?
> 
Yes. But I split it off as it's a different issue.
And this one apparently requires more discussion :-)

> The data-out hdr is not prepd yet.  The entire thing gets memset'd, so
> ORing it does not help.
> 
Yes, and no.
We're hitting this section for Data-Out PDUs only, ie for tasks on the
'requeue' list. All other tasks (for which iscsi_prep_scsi_cmd() would
be called) are filtered out here:

                if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
                        iscsi_conn_printk(KERN_INFO, conn,

as 'opcode' is the parameter passed during invocation, not the actual
opcode of the task.
So the 'FINAL' bit will only be set when we're here:

        list_for_each_entry_safe(task, tmptask, &conn->requeue, running) {
                /*
                 * we always do fastlogout - conn stop code will clean up.
                 */
                if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
                        break;

                if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT))
                        continue;

                conn->task = task;
                list_del_init(&conn->task->running);
                if (conn->task->state == ISCSI_TASK_PENDING)
                        conn->task->state = ISCSI_TASK_RUNNING;
                if (conn->conn_debug)
                        iscsi_conn_printk(KERN_INFO, conn,
                                          "requeue cmdpdu [itt 0x%x cmdsn %u "
                                          "lun %u] xmit\n", conn->task->itt,
                                          be32_to_cpu(conn->task->cmdsn),
                                          conn->task->sc ? 
conn->task->sc->device->lun : -1);
                rc = iscsi_xmit_task(conn);

and there we don't do any header prep()ing.

> Plus you only set the F bit for the final PDU. This would send multiple
> PDUs with the final bit set. I think the point of sending a pdu with the
> F bit set is that you do not have to send all the data-outs for the
> sequence (if a tmf was executing then it does not have to wait for MB of
> data). Just send one with the F bit set.
> 
Yes, that was the plan. But I'm not _that_ firm with the R2T code, so
the following argumentation might be wrong.
So, I was under the impression that we're only ever send 1 Data-Out
PDU in response to a R2T. However, there might be more than one
R2T/Data-Out pairs exchanged until the entire data is transferred.
The idea here was that we're setting the 'FINAL' flag for a Data-Out
PDU whenever the data transfer should be stopped.
This _should_ induce the Target to stop sending us R2Ts.
If it does, the transfer is terminated and everyone's happy.
If it doesn't (ie it'll ignore the FINAL flag) we would still
have to send a Data-Out Response.

> You want to modify iscsi_prep_data_out_pdu to check if a tmf would
> affect that task, and if so then hit the final bit on it. We probably
> also want to indicate to the caller that we ended it early so it it can
> stop sending more data-outs for that r2t.
> 
Does it make a difference?
When changing iscsi_prep_data_out_pdu() we would be modifying the
header when it's being prep()ed, ie after the SCSI cmd PDU is sent.
But then the task is being rescheduled on the 'requeue' list after
a R2T has been received, and my patch sends the flag just before
it's being sent.
Or am I wrong?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                   zSeries & Storage
h...@suse.de                          +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

Reply via email to