mirror of https://gitee.com/openkylin/qemu.git
nbd-client: Short-circuit 0-length operations
The NBD spec was recently clarified to state that clients should not send 0-length requests to the server, as the server behavior is undefined [1]. We know that qemu-nbd's behavior is a successful no-op (once it has filtered for read-only exports), but other NBD implementations might return an error. To avoid any questionable server implementations, it is better to just short-circuit such requests on the client side (we are relying on the block layer to already filter out requests such as invalid offset, write to a read-only volume, and so forth); do the short-circuit as late as possible to still benefit from protections from assertions that the block layer is not violating our assumptions. [1] https://github.com/NetworkBlockDevice/nbd/commit/ee926037 Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20171108215703.9295-6-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
This commit is contained in:
parent
efdc0c103d
commit
9d8f818cde
|
@ -674,6 +674,9 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
|
|||
assert(bytes <= NBD_MAX_BUFFER_SIZE);
|
||||
assert(!flags);
|
||||
|
||||
if (!bytes) {
|
||||
return 0;
|
||||
}
|
||||
ret = nbd_co_send_request(bs, &request, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -705,6 +708,9 @@ int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
|||
|
||||
assert(bytes <= NBD_MAX_BUFFER_SIZE);
|
||||
|
||||
if (!bytes) {
|
||||
return 0;
|
||||
}
|
||||
return nbd_co_request(bs, &request, qiov);
|
||||
}
|
||||
|
||||
|
@ -731,6 +737,9 @@ int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
|||
request.flags |= NBD_CMD_FLAG_NO_HOLE;
|
||||
}
|
||||
|
||||
if (!bytes) {
|
||||
return 0;
|
||||
}
|
||||
return nbd_co_request(bs, &request, NULL);
|
||||
}
|
||||
|
||||
|
@ -759,7 +768,7 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
|
|||
};
|
||||
|
||||
assert(!(client->info.flags & NBD_FLAG_READ_ONLY));
|
||||
if (!(client->info.flags & NBD_FLAG_SEND_TRIM)) {
|
||||
if (!(client->info.flags & NBD_FLAG_SEND_TRIM) || !bytes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue