On 26/09/2017 00:19, Eric Blake wrote:
>> + /* here we deal with successful structured reply */
>> + switch (s->reply.type) {
>> + QEMUIOVector sub_qiov;
>> + case NBD_SREP_TYPE_OFFSET_DATA:
> This is putting a LOT of smarts directly into the receive routine.
> Here's where I was previously wondering (and I think Paolo as well)
> whether it might be better to split the efforts: the generic function
> reads off the chunk information and any payload, but a per-command
> callback function then parses the chunks. Especially since the
> definition of the chunks differs on a per-command basis (yes, the NBD
> spec will try to not reuse an SREP chunk type across multiple commands
> unless the semantics are similar, but that's a bit more fragile). This
> particularly matters given my statement above that you want a
> discriminated union, rather than a struct that contains unused fields,
> for handling different SREP chunk types.
I think there should be two kinds of replies: 1) read directly into a
QEMUIOVector, using structured replies only as an encapsulation of the
payload; 2) read a chunk at a time into malloc-ed memory, yielding back
to the calling coroutine after receiving one complete chunk.
In the end this probably means that you have a read_chunk_header
function and a read_chunk function. READ has a loop that calls
read_chunk_header followed by direct reading into the QEMUIOVector,
while everyone else calls read_chunk.
Maybe qio_channel_readv/writev_full could have "offset" and "bytes"
arguments. Most code in iov_send_recv could be cut-and-pasted. (When
sheepdog is converted to QIOChannel, iov_send_recv can go away).
Paolo