nbd/server: Implement sparse reads atop structured reply
commit418638d3e448e0ed79d55cc43a26f7a65c22007f
authorEric Blake <eblake@redhat.com>
Tue, 7 Nov 2017 03:09:11 +0000 (6 21:09 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 8 Jan 2018 15:12:23 +0000 (8 09:12 -0600)
treedb8bfcc61d6ed96ef88fee003124339cc2366a9c
parent799044b6a3a0fc63e1e020e4d9266786a2dc7a0b
nbd/server: Implement sparse reads atop structured reply

The reason that NBD added structured reply in the first place was
to allow for efficient reads of sparse files, by allowing the
reply to include chunks to quickly communicate holes to the client
without sending lots of zeroes over the wire.  Time to implement
this in the server; our client can already read such data.

We can only skip holes insofar as the block layer can query them;
and only if the client is okay with a fragmented request (if a
client requests NBD_CMD_FLAG_DF and the entire read is a hole, we
could technically return a single NBD_REPLY_TYPE_OFFSET_HOLE, but
that's a fringe case not worth catering to here).  Sadly, the
control flow is a bit wonkier than I would have preferred, but
it was minimally invasive to have a split in the action between
a fragmented read (handled directly where we recognize
NBD_CMD_READ with the right conditions, and sending multiple
chunks) vs. a single read (handled at the end of nbd_trip, for
both simple and structured replies, when we know there is only
one thing being read).  Likewise, I didn't make any effort to
optimize the final chunk of a fragmented read to set the
NBD_REPLY_FLAG_DONE, but unconditionally send that as a separate
NBD_REPLY_TYPE_NONE.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20171107030912.23930-2-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
nbd/server.c
nbd/trace-events