aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-06-07 18:24:08 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-07 18:24:08 +0100
commitbbfa326fc8028e275eddf8c9965c2a1b59405b2e (patch)
tree18462ee41801d922e941ee50e1e4a54a96324464 /block
parent64175afc695c0672876fbbfc31b299c86d562cb4 (diff)
parentac06724a715864942e2b5e28f92d5d5421f0a0b0 (diff)
downloadqemu-bbfa326fc8028e275eddf8c9965c2a1b59405b2e.zip
qemu-bbfa326fc8028e275eddf8c9965c2a1b59405b2e.tar.gz
qemu-bbfa326fc8028e275eddf8c9965c2a1b59405b2e.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* virtio-scsi use-after-free fix (Fam) * SMM fixes and improvements for TCG (myself, Mihail) * irqchip and AddressSpaceDispatch cleanups and fixes (Peter) * Coverity fix (Stefano) * NBD cleanups and fixes (Vladimir, Eric, myself) * RTC accuracy improvements and code cleanups (Guangrong+Yunfang) * socket error reporting improvement (Daniel) * GDB XML description for SSE registers (Abdallah) * kvmclock update fix (Denis) * SMM memory savings (Gonglei) * -cpu 486 fix (myself) * various bugfixes (Roman, Peter, myself, Thomas) * rtc-test improvement (Guangrong) * migration throttling fix (Felipe) * create docs/ subdirectories (myself) # gpg: Signature made Wed 07 Jun 2017 17:22:07 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (31 commits) docs: create config/, devel/ and spin/ subdirectories cpus: reset throttle_thread_scheduled after sleep kvm: don't register smram_listener when smm is off nbd: make it thread-safe, fix qcow2 over nbd target/i386: Add GDB XML description for SSE registers i386/kvm: do not zero out segment flags if segment is unusable or not present edu: fix memory leak on msi_broken platforms linuxboot_dma: compile for i486 kvmclock: update system_time_msr address forcibly nbd: Fully initialize client in case of failed negotiation sockets: improve error reporting if UNIX socket path is too long i386: fix read/write cr with icount option target/i386: use multiple CPU AddressSpaces target/i386: enable A20 automatically in system management mode virtio-scsi: Unset hotplug handler when unrealize exec: simplify phys_page_find() params nbd/client.c: use errp instead of LOG nbd: add errp to read_sync, write_sync and drop_sync nbd: add errp parameter to nbd_wr_syncv() nbd: read_sync and friends: return 0 on success ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block')
-rw-r--r--block/nbd-client.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 1e2952f..87d19c7 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -28,6 +28,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "nbd-client.h"
#define HANDLE_TO_INDEX(bs, handle) ((handle) ^ ((uint64_t)(intptr_t)bs))
@@ -70,10 +71,14 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
NBDClientSession *s = opaque;
uint64_t i;
int ret;
+ Error *local_err = NULL;
for (;;) {
assert(s->reply.handle == 0);
- ret = nbd_receive_reply(s->ioc, &s->reply);
+ ret = nbd_receive_reply(s->ioc, &s->reply, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
if (ret <= 0) {
break;
}
@@ -114,6 +119,10 @@ static int nbd_co_send_request(BlockDriverState *bs,
int rc, ret, i;
qemu_co_mutex_lock(&s->send_mutex);
+ while (s->in_flight == MAX_NBD_REQUESTS) {
+ qemu_co_queue_wait(&s->free_sema, &s->send_mutex);
+ }
+ s->in_flight++;
for (i = 0; i < MAX_NBD_REQUESTS; i++) {
if (s->recv_coroutine[i] == NULL) {
@@ -136,7 +145,7 @@ static int nbd_co_send_request(BlockDriverState *bs,
rc = nbd_send_request(s->ioc, request);
if (rc >= 0) {
ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len,
- false);
+ false, NULL);
if (ret != request->len) {
rc = -EIO;
}
@@ -165,7 +174,7 @@ static void nbd_co_receive_reply(NBDClientSession *s,
} else {
if (qiov && reply->error == 0) {
ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len,
- true);
+ true, NULL);
if (ret != request->len) {
reply->error = EIO;
}
@@ -176,20 +185,6 @@ static void nbd_co_receive_reply(NBDClientSession *s,
}
}
-static void nbd_coroutine_start(NBDClientSession *s,
- NBDRequest *request)
-{
- /* Poor man semaphore. The free_sema is locked when no other request
- * can be accepted, and unlocked after receiving one reply. */
- if (s->in_flight == MAX_NBD_REQUESTS) {
- qemu_co_queue_wait(&s->free_sema, NULL);
- assert(s->in_flight < MAX_NBD_REQUESTS);
- }
- s->in_flight++;
-
- /* s->recv_coroutine[i] is set as soon as we get the send_lock. */
-}
-
static void nbd_coroutine_end(BlockDriverState *bs,
NBDRequest *request)
{
@@ -197,13 +192,16 @@ static void nbd_coroutine_end(BlockDriverState *bs,
int i = HANDLE_TO_INDEX(s, request->handle);
s->recv_coroutine[i] = NULL;
- s->in_flight--;
- qemu_co_queue_next(&s->free_sema);
/* Kick the read_reply_co to get the next reply. */
if (s->read_reply_co) {
aio_co_wake(s->read_reply_co);
}
+
+ qemu_co_mutex_lock(&s->send_mutex);
+ s->in_flight--;
+ qemu_co_queue_next(&s->free_sema);
+ qemu_co_mutex_unlock(&s->send_mutex);
}
int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
@@ -221,7 +219,6 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
assert(bytes <= NBD_MAX_BUFFER_SIZE);
assert(!flags);
- nbd_coroutine_start(client, &request);
ret = nbd_co_send_request(bs, &request, NULL);
if (ret < 0) {
reply.error = -ret;
@@ -251,7 +248,6 @@ int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
assert(bytes <= NBD_MAX_BUFFER_SIZE);
- nbd_coroutine_start(client, &request);
ret = nbd_co_send_request(bs, &request, qiov);
if (ret < 0) {
reply.error = -ret;
@@ -286,7 +282,6 @@ int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
request.flags |= NBD_CMD_FLAG_NO_HOLE;
}
- nbd_coroutine_start(client, &request);
ret = nbd_co_send_request(bs, &request, NULL);
if (ret < 0) {
reply.error = -ret;
@@ -311,7 +306,6 @@ int nbd_client_co_flush(BlockDriverState *bs)
request.from = 0;
request.len = 0;
- nbd_coroutine_start(client, &request);
ret = nbd_co_send_request(bs, &request, NULL);
if (ret < 0) {
reply.error = -ret;
@@ -337,7 +331,6 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
return 0;
}
- nbd_coroutine_start(client, &request);
ret = nbd_co_send_request(bs, &request, NULL);
if (ret < 0) {
reply.error = -ret;