nbd patches for 2018-01-08
- Eric Blake: 0/2 Optimize sparse reads over NBD - Murilo Opsfelder Araujo: block/nbd: fix segmentation fault when .desc is not null-terminated -----BEGIN PGP SIGNATURE----- Comment: Public key at http://people.redhat.com/eblake/eblake.gpg iQEcBAABCAAGBQJaU4xvAAoJEKeha0olJ0NqH9IIAJsWiU7WDVXVpnw4RokluQyB zbXcP011XOvvsDkmUN09qKectJJ2lbAAzBEhu2axXorP78sIXiVEWwDEtPX/aPpt B9irT1muLP3aQIekQRf9soqTs9fPyeiK8/Iy6+E4ad0XwVQ8dMDiGQOhIbiIXQEx IitdrS2SGai7H4BXM/E/qYxY4/UWtNHCG9r/2IoWRqTjU2yj2VreMnnjaEJ9GhTk PMqn58NPEe7U7xtaqPT1aM8py3V35jC6ucOHUrMpm+NpYY2I3BakVT33x+SFgXZi t/Ml53MDK5qh7EeLlosBxbVRf+BKV3+WSdymPRqPuyOUcgOC5iAeIJU5XBoAHvA= =eP1e -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-01-08' into staging nbd patches for 2018-01-08 - Eric Blake: 0/2 Optimize sparse reads over NBD - Murilo Opsfelder Araujo: block/nbd: fix segmentation fault when .desc is not null-terminated # gpg: Signature made Mon 08 Jan 2018 15:21:19 GMT # gpg: using RSA key 0xA7A16B4A2527436A # gpg: Good signature from "Eric Blake <eblake@redhat.com>" # gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" # gpg: aka "[jpeg image of size 6874]" # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * remotes/ericb/tags/pull-nbd-2018-01-08: block/nbd: fix segmentation fault when .desc is not null-terminated nbd/server: Optimize final chunk of sparse read nbd/server: Implement sparse reads atop structured reply Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3cee4db661
@ -388,6 +388,7 @@ static QemuOptsList nbd_runtime_opts = {
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "ID of the TLS credentials to use",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
|
79
nbd/server.c
79
nbd/server.c
@ -1303,6 +1303,7 @@ static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
|
||||
uint64_t offset,
|
||||
void *data,
|
||||
size_t size,
|
||||
bool final,
|
||||
Error **errp)
|
||||
{
|
||||
NBDStructuredReadData chunk;
|
||||
@ -1313,13 +1314,73 @@ static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
|
||||
|
||||
assert(size);
|
||||
trace_nbd_co_send_structured_read(handle, offset, data, size);
|
||||
set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_OFFSET_DATA,
|
||||
handle, sizeof(chunk) - sizeof(chunk.h) + size);
|
||||
set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
|
||||
NBD_REPLY_TYPE_OFFSET_DATA, handle,
|
||||
sizeof(chunk) - sizeof(chunk.h) + size);
|
||||
stq_be_p(&chunk.offset, offset);
|
||||
|
||||
return nbd_co_send_iov(client, iov, 2, errp);
|
||||
}
|
||||
|
||||
static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
|
||||
uint64_t handle,
|
||||
uint64_t offset,
|
||||
uint8_t *data,
|
||||
size_t size,
|
||||
Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
NBDExport *exp = client->exp;
|
||||
size_t progress = 0;
|
||||
|
||||
while (progress < size) {
|
||||
int64_t pnum;
|
||||
int status = bdrv_block_status_above(blk_bs(exp->blk), NULL,
|
||||
offset + progress,
|
||||
size - progress, &pnum, NULL,
|
||||
NULL);
|
||||
bool final;
|
||||
|
||||
if (status < 0) {
|
||||
error_setg_errno(errp, -status, "unable to check for holes");
|
||||
return status;
|
||||
}
|
||||
assert(pnum && pnum <= size - progress);
|
||||
final = progress + pnum == size;
|
||||
if (status & BDRV_BLOCK_ZERO) {
|
||||
NBDStructuredReadHole chunk;
|
||||
struct iovec iov[] = {
|
||||
{.iov_base = &chunk, .iov_len = sizeof(chunk)},
|
||||
};
|
||||
|
||||
trace_nbd_co_send_structured_read_hole(handle, offset + progress,
|
||||
pnum);
|
||||
set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
|
||||
NBD_REPLY_TYPE_OFFSET_HOLE,
|
||||
handle, sizeof(chunk) - sizeof(chunk.h));
|
||||
stq_be_p(&chunk.offset, offset + progress);
|
||||
stl_be_p(&chunk.length, pnum);
|
||||
ret = nbd_co_send_iov(client, iov, 1, errp);
|
||||
} else {
|
||||
ret = blk_pread(exp->blk, offset + progress + exp->dev_offset,
|
||||
data + progress, pnum);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "reading from file failed");
|
||||
break;
|
||||
}
|
||||
ret = nbd_co_send_structured_read(client, handle, offset + progress,
|
||||
data + progress, pnum, final,
|
||||
errp);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
progress += pnum;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
|
||||
uint64_t handle,
|
||||
uint32_t error,
|
||||
@ -1481,6 +1542,17 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
if (client->structured_reply && !(request.flags & NBD_CMD_FLAG_DF) &&
|
||||
request.len) {
|
||||
ret = nbd_co_send_sparse_read(req->client, request.handle,
|
||||
request.from, req->data, request.len,
|
||||
&local_err);
|
||||
if (ret < 0) {
|
||||
goto reply;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = blk_pread(exp->blk, request.from + exp->dev_offset,
|
||||
req->data, request.len);
|
||||
if (ret < 0) {
|
||||
@ -1561,7 +1633,8 @@ reply:
|
||||
} else if (reply_data_len) {
|
||||
ret = nbd_co_send_structured_read(req->client, request.handle,
|
||||
request.from, req->data,
|
||||
reply_data_len, &local_err);
|
||||
reply_data_len, true,
|
||||
&local_err);
|
||||
} else {
|
||||
ret = nbd_co_send_structured_done(req->client, request.handle,
|
||||
&local_err);
|
||||
|
@ -57,6 +57,7 @@ nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients fr
|
||||
nbd_co_send_simple_reply(uint64_t handle, uint32_t error, const char *errname, int len) "Send simple reply: handle = %" PRIu64 ", error = %" PRIu32 " (%s), len = %d"
|
||||
nbd_co_send_structured_done(uint64_t handle) "Send structured reply done: handle = %" PRIu64
|
||||
nbd_co_send_structured_read(uint64_t handle, uint64_t offset, void *data, size_t size) "Send structured read data reply: handle = %" PRIu64 ", offset = %" PRIu64 ", data = %p, len = %zu"
|
||||
nbd_co_send_structured_read_hole(uint64_t handle, uint64_t offset, size_t size) "Send structured read hole reply: handle = %" PRIu64 ", offset = %" PRIu64 ", len = %zu"
|
||||
nbd_co_send_structured_error(uint64_t handle, int err, const char *errname, const char *msg) "Send structured error reply: handle = %" PRIu64 ", error = %d (%s), msg = '%s'"
|
||||
nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char *name) "Decoding type: handle = %" PRIu64 ", type = %" PRIu16 " (%s)"
|
||||
nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) "Payload received: handle = %" PRIu64 ", len = %" PRIu32
|
||||
|
Loading…
Reference in New Issue
Block a user