X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=nbd%2Fserver.c;h=982de67816a7b4d4e56fba0544244f95d3f9b5a5;hb=270b33cc1c40ce2eff1abdf67b04fc008167b525;hp=5357f588f05aaae2ffb3701b7f3e305abc6d40e7;hpb=795d946d0797e7ba28ed97c86e2592e346b02b0e;p=mirror_qemu.git diff --git a/nbd/server.c b/nbd/server.c index 5357f588f0..982de67816 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -102,6 +102,8 @@ struct NBDExport { }; static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); +static QTAILQ_HEAD(, NBDExport) closed_exports = + QTAILQ_HEAD_INITIALIZER(closed_exports); /* NBDExportMetaContexts represents a list of contexts to be exported, * as selected by NBD_OPT_SET_META_CONTEXT. Also used for @@ -1565,13 +1567,13 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, if (bitmap) { BdrvDirtyBitmap *bm = NULL; - while (true) { + while (bs) { bm = bdrv_find_dirty_bitmap(bs, bitmap); - if (bm != NULL || bs->backing == NULL) { + if (bm != NULL) { break; } - bs = bs->backing->bs; + bs = bdrv_filter_or_cow_bs(bs); } if (bm == NULL) { @@ -1659,6 +1661,7 @@ void nbd_export_close(NBDExport *exp) g_free(exp->name); exp->name = NULL; QTAILQ_REMOVE(&exports, exp, next); + QTAILQ_INSERT_TAIL(&closed_exports, exp, next); } g_free(exp->description); exp->description = NULL; @@ -1722,7 +1725,9 @@ void nbd_export_put(NBDExport *exp) g_free(exp->export_bitmap_context); } + QTAILQ_REMOVE(&closed_exports, exp, next); g_free(exp); + aio_wait_kick(); } } @@ -1742,6 +1747,9 @@ void nbd_export_close_all(void) nbd_export_close(exp); aio_context_release(aio_context); } + + AIO_WAIT_WHILE(NULL, !(QTAILQ_EMPTY(&exports) && + QTAILQ_EMPTY(&closed_exports))); } static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov, @@ -2370,8 +2378,17 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, if (request->flags & NBD_CMD_FLAG_FAST_ZERO) { flags |= BDRV_REQ_NO_FALLBACK; } - ret = blk_pwrite_zeroes(exp->blk, request->from + exp->dev_offset, - request->len, flags); + ret = 0; + /* FIXME simplify this when blk_pwrite_zeroes switches to 64-bit */ + while (ret >= 0 && request->len) { + int align = client->check_align ?: 1; + int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, + align)); + ret = blk_pwrite_zeroes(exp->blk, request->from + exp->dev_offset, + len, flags); + request->len -= len; + request->from += len; + } return nbd_send_generic_reply(client, request->handle, ret, "writing to file failed", errp); @@ -2385,9 +2402,18 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, "flush failed", errp); case NBD_CMD_TRIM: - ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset, - request->len); - if (ret == 0 && request->flags & NBD_CMD_FLAG_FUA) { + ret = 0; + /* FIXME simplify this when blk_co_pdiscard switches to 64-bit */ + while (ret >= 0 && request->len) { + int align = client->check_align ?: 1; + int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES, + align)); + ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset, + len); + request->len -= len; + request->from += len; + } + if (ret >= 0 && request->flags & NBD_CMD_FLAG_FUA) { ret = blk_co_flush(exp->blk); } return nbd_send_generic_reply(client, request->handle, ret,