diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-02-24 12:59:13 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-02-24 12:59:14 +0000 |
commit | 3dc10613c313a042a111e46a977733411495ea8c (patch) | |
tree | ea992fe32d4272c169d7d9f1fd43c621a80aa2d5 /block | |
parent | 3dd2d1a33976a7ec4aa3a6a29e5183af53949237 (diff) | |
parent | b9c649470ba0d4056b2d486105a0f8fb982654ae (diff) |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Pull request
v2:
* Fix C11 typedef redefinitions in ahci and libqos malloc [Peter]
* Fix lx -> PRIx64 format specifiers in ahci [Peter]
# gpg: Signature made Mon Feb 16 15:45:53 2015 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/block-pull-request: (65 commits)
block: Keep bdrv_check*_request()'s return value
block: Remove "growable" from BDS
block: Clamp BlockBackend requests
qemu-io: Use BlockBackend
qemu-io: Remove "growable" option
qemu-io: Use blk_new_open() in openfile()
qemu-nbd: Use blk_new_open() in main()
qemu-img: Use BlockBackend as far as possible
qemu-img: Use blk_new_open() in img_rebase()
qemu-img: Use blk_new_open() in img_open()
block/xen: Use blk_new_open() in blk_connect()
blockdev: Use blk_new_open() in blockdev_init()
iotests: Add test for driver=qcow2, format=qcow2
block: Add Error parameter to bdrv_find_protocol()
block: Add blk_new_open()
block: Lift some BDS functions to the BlockBackend
iotests: Add test for qemu-img convert to NBD
qemu-img: Fix qemu-img convert -n
qemu-iotests: Add 093 for IO throttling
qemu-iotests: Allow caller to disable underscore convertion for qmp
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block')
-rw-r--r-- | block/block-backend.c | 224 | ||||
-rw-r--r-- | block/nbd-client.c | 126 | ||||
-rw-r--r-- | block/nbd-client.h | 34 | ||||
-rw-r--r-- | block/nbd.c | 37 | ||||
-rw-r--r-- | block/qcow2.c | 6 | ||||
-rw-r--r-- | block/raw-posix.c | 2 | ||||
-rw-r--r-- | block/raw-win32.c | 2 | ||||
-rw-r--r-- | block/sheepdog.c | 4 | ||||
-rw-r--r-- | block/vmdk.c | 3 |
9 files changed, 325 insertions, 113 deletions
diff --git a/block/block-backend.c b/block/block-backend.c index c28e2402c7..aabe569642 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -31,6 +31,16 @@ struct BlockBackend { void *dev_opaque; }; +typedef struct BlockBackendAIOCB { + BlockAIOCB common; + QEMUBH *bh; + int ret; +} BlockBackendAIOCB; + +static const AIOCBInfo block_backend_aiocb_info = { + .aiocb_size = sizeof(BlockBackendAIOCB), +}; + static void drive_info_del(DriveInfo *dinfo); /* All the BlockBackends (except for hidden ones) */ @@ -91,6 +101,40 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp) return blk; } +/* + * Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState. + * + * Just as with bdrv_open(), after having called this function the reference to + * @options belongs to the block layer (even on failure). + * + * TODO: Remove @filename and @flags; it should be possible to specify a whole + * BDS tree just by specifying the @options QDict (or @reference, + * alternatively). At the time of adding this function, this is not possible, + * though, so callers of this function have to be able to specify @filename and + * @flags. + */ +BlockBackend *blk_new_open(const char *name, const char *filename, + const char *reference, QDict *options, int flags, + Error **errp) +{ + BlockBackend *blk; + int ret; + + blk = blk_new_with_bs(name, errp); + if (!blk) { + QDECREF(options); + return NULL; + } + + ret = bdrv_open(&blk->bs, filename, reference, options, flags, NULL, errp); + if (ret < 0) { + blk_unref(blk); + return NULL; + } + + return blk; +} + static void blk_delete(BlockBackend *blk) { assert(!blk->refcnt); @@ -394,39 +438,137 @@ void blk_iostatus_enable(BlockBackend *blk) bdrv_iostatus_enable(blk->bs); } +static int blk_check_byte_request(BlockBackend *blk, int64_t offset, + size_t size) +{ + int64_t len; + + if (size > INT_MAX) { + return -EIO; + } + + if (!blk_is_inserted(blk)) { + return -ENOMEDIUM; + } + + len = blk_getlength(blk); + if (len < 0) { + return len; + } + + if (offset < 0) { + return -EIO; + } + + if (offset > len || len - offset < size) { + return -EIO; + } + + return 0; +} + +static int blk_check_request(BlockBackend *blk, int64_t sector_num, + int nb_sectors) +{ + if (sector_num < 0 || sector_num > INT64_MAX / BDRV_SECTOR_SIZE) { + return -EIO; + } + + if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) { + return -EIO; + } + + return blk_check_byte_request(blk, sector_num * BDRV_SECTOR_SIZE, + nb_sectors * BDRV_SECTOR_SIZE); +} + int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf, int nb_sectors) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + return bdrv_read(blk->bs, sector_num, buf, nb_sectors); } int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf, int nb_sectors) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + return bdrv_read_unthrottled(blk->bs, sector_num, buf, nb_sectors); } int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf, int nb_sectors) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + return bdrv_write(blk->bs, sector_num, buf, nb_sectors); } +static void error_callback_bh(void *opaque) +{ + struct BlockBackendAIOCB *acb = opaque; + qemu_bh_delete(acb->bh); + acb->common.cb(acb->common.opaque, acb->ret); + qemu_aio_unref(acb); +} + +static BlockAIOCB *abort_aio_request(BlockBackend *blk, BlockCompletionFunc *cb, + void *opaque, int ret) +{ + struct BlockBackendAIOCB *acb; + QEMUBH *bh; + + acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque); + acb->ret = ret; + + bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb); + acb->bh = bh; + qemu_bh_schedule(bh); + + return &acb->common; +} + BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return abort_aio_request(blk, cb, opaque, ret); + } + return bdrv_aio_write_zeroes(blk->bs, sector_num, nb_sectors, flags, cb, opaque); } int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count) { + int ret = blk_check_byte_request(blk, offset, count); + if (ret < 0) { + return ret; + } + return bdrv_pread(blk->bs, offset, buf, count); } int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count) { + int ret = blk_check_byte_request(blk, offset, count); + if (ret < 0) { + return ret; + } + return bdrv_pwrite(blk->bs, offset, buf, count); } @@ -440,10 +582,20 @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) bdrv_get_geometry(blk->bs, nb_sectors_ptr); } +int64_t blk_nb_sectors(BlockBackend *blk) +{ + return bdrv_nb_sectors(blk->bs); +} + BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockCompletionFunc *cb, void *opaque) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return abort_aio_request(blk, cb, opaque, ret); + } + return bdrv_aio_readv(blk->bs, sector_num, iov, nb_sectors, cb, opaque); } @@ -451,6 +603,11 @@ BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockCompletionFunc *cb, void *opaque) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return abort_aio_request(blk, cb, opaque, ret); + } + return bdrv_aio_writev(blk->bs, sector_num, iov, nb_sectors, cb, opaque); } @@ -464,6 +621,11 @@ BlockAIOCB *blk_aio_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors, BlockCompletionFunc *cb, void *opaque) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return abort_aio_request(blk, cb, opaque, ret); + } + return bdrv_aio_discard(blk->bs, sector_num, nb_sectors, cb, opaque); } @@ -479,6 +641,15 @@ void blk_aio_cancel_async(BlockAIOCB *acb) int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs) { + int i, ret; + + for (i = 0; i < num_reqs; i++) { + ret = blk_check_request(blk, reqs[i].sector, reqs[i].nb_sectors); + if (ret < 0) { + return ret; + } + } + return bdrv_aio_multiwrite(blk->bs, reqs, num_reqs); } @@ -495,6 +666,11 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) { + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + return bdrv_co_discard(blk->bs, sector_num, nb_sectors); } @@ -668,3 +844,51 @@ void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, { return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque); } + +int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num, + int nb_sectors, BdrvRequestFlags flags) +{ + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + + return bdrv_co_write_zeroes(blk->bs, sector_num, nb_sectors, flags); +} + +int blk_write_compressed(BlockBackend *blk, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + + return bdrv_write_compressed(blk->bs, sector_num, buf, nb_sectors); +} + +int blk_truncate(BlockBackend *blk, int64_t offset) +{ + return bdrv_truncate(blk->bs, offset); +} + +int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) +{ + int ret = blk_check_request(blk, sector_num, nb_sectors); + if (ret < 0) { + return ret; + } + + return bdrv_discard(blk->bs, sector_num, nb_sectors); +} + +int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, + int64_t pos, int size) +{ + return bdrv_save_vmstate(blk->bs, buf, pos, size); +} + +int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size) +{ + return bdrv_load_vmstate(blk->bs, buf, pos, size); +} diff --git a/block/nbd-client.c b/block/nbd-client.c index 28bfb62bed..259f5a3cb6 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -43,20 +43,23 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s) } } -static void nbd_teardown_connection(NbdClientSession *client) +static void nbd_teardown_connection(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); + /* finish any pending coroutines */ shutdown(client->sock, 2); nbd_recv_coroutines_enter_all(client); - nbd_client_session_detach_aio_context(client); + nbd_client_detach_aio_context(bs); closesocket(client->sock); client->sock = -1; } static void nbd_reply_ready(void *opaque) { - NbdClientSession *s = opaque; + BlockDriverState *bs = opaque; + NbdClientSession *s = nbd_get_client_session(bs); uint64_t i; int ret; @@ -89,28 +92,40 @@ static void nbd_reply_ready(void *opaque) } fail: - nbd_teardown_connection(s); + nbd_teardown_connection(bs); } static void nbd_restart_write(void *opaque) { - NbdClientSession *s = opaque; + BlockDriverState *bs = opaque; - qemu_coroutine_enter(s->send_coroutine, NULL); + qemu_coroutine_enter(nbd_get_client_session(bs)->send_coroutine, NULL); } -static int nbd_co_send_request(NbdClientSession *s, - struct nbd_request *request, - QEMUIOVector *qiov, int offset) +static int nbd_co_send_request(BlockDriverState *bs, + struct nbd_request *request, + QEMUIOVector *qiov, int offset) { + NbdClientSession *s = nbd_get_client_session(bs); AioContext *aio_context; - int rc, ret; + int rc, ret, i; qemu_co_mutex_lock(&s->send_mutex); + + for (i = 0; i < MAX_NBD_REQUESTS; i++) { + if (s->recv_coroutine[i] == NULL) { + s->recv_coroutine[i] = qemu_coroutine_self(); + break; + } + } + + assert(i < MAX_NBD_REQUESTS); + request->handle = INDEX_TO_HANDLE(s, i); s->send_coroutine = qemu_coroutine_self(); - aio_context = bdrv_get_aio_context(s->bs); + aio_context = bdrv_get_aio_context(bs); + aio_set_fd_handler(aio_context, s->sock, - nbd_reply_ready, nbd_restart_write, s); + nbd_reply_ready, nbd_restart_write, bs); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); @@ -129,7 +144,7 @@ static int nbd_co_send_request(NbdClientSession *s, } else { rc = nbd_send_request(s->sock, request); } - aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, s); + aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, bs); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; @@ -164,8 +179,6 @@ static void nbd_co_receive_reply(NbdClientSession *s, static void nbd_coroutine_start(NbdClientSession *s, struct nbd_request *request) { - int i; - /* 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 - 1) { @@ -174,15 +187,7 @@ static void nbd_coroutine_start(NbdClientSession *s, } s->in_flight++; - for (i = 0; i < MAX_NBD_REQUESTS; i++) { - if (s->recv_coroutine[i] == NULL) { - s->recv_coroutine[i] = qemu_coroutine_self(); - break; - } - } - - assert(i < MAX_NBD_REQUESTS); - request->handle = INDEX_TO_HANDLE(s, i); + /* s->recv_coroutine[i] is set as soon as we get the send_lock. */ } static void nbd_coroutine_end(NbdClientSession *s, @@ -195,10 +200,11 @@ static void nbd_coroutine_end(NbdClientSession *s, } } -static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, +static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_READ }; struct nbd_reply reply; ssize_t ret; @@ -207,7 +213,7 @@ static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -218,15 +224,16 @@ static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, } -static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, +static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_WRITE }; struct nbd_reply reply; ssize_t ret; - if (!bdrv_enable_write_cache(client->bs) && + if (!bdrv_enable_write_cache(bs) && (client->nbdflags & NBD_FLAG_SEND_FUA)) { request.type |= NBD_CMD_FLAG_FUA; } @@ -235,7 +242,7 @@ static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, qiov, offset); + ret = nbd_co_send_request(bs, &request, qiov, offset); if (ret < 0) { reply.error = -ret; } else { @@ -249,14 +256,13 @@ static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, * remain aligned to 4K. */ #define NBD_MAX_SECTORS 2040 -int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) +int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { int offset = 0; int ret; while (nb_sectors > NBD_MAX_SECTORS) { - ret = nbd_co_readv_1(client, sector_num, - NBD_MAX_SECTORS, qiov, offset); + ret = nbd_co_readv_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset); if (ret < 0) { return ret; } @@ -264,17 +270,16 @@ int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, sector_num += NBD_MAX_SECTORS; nb_sectors -= NBD_MAX_SECTORS; } - return nbd_co_readv_1(client, sector_num, nb_sectors, qiov, offset); + return nbd_co_readv_1(bs, sector_num, nb_sectors, qiov, offset); } -int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) +int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { int offset = 0; int ret; while (nb_sectors > NBD_MAX_SECTORS) { - ret = nbd_co_writev_1(client, sector_num, - NBD_MAX_SECTORS, qiov, offset); + ret = nbd_co_writev_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset); if (ret < 0) { return ret; } @@ -282,11 +287,12 @@ int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, sector_num += NBD_MAX_SECTORS; nb_sectors -= NBD_MAX_SECTORS; } - return nbd_co_writev_1(client, sector_num, nb_sectors, qiov, offset); + return nbd_co_writev_1(bs, sector_num, nb_sectors, qiov, offset); } -int nbd_client_session_co_flush(NbdClientSession *client) +int nbd_client_co_flush(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_FLUSH }; struct nbd_reply reply; ssize_t ret; @@ -303,7 +309,7 @@ int nbd_client_session_co_flush(NbdClientSession *client) request.len = 0; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -313,9 +319,10 @@ int nbd_client_session_co_flush(NbdClientSession *client) return -reply.error; } -int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, - int nb_sectors) +int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, + int nb_sectors) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_TRIM }; struct nbd_reply reply; ssize_t ret; @@ -327,7 +334,7 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -338,43 +345,41 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, } -void nbd_client_session_detach_aio_context(NbdClientSession *client) +void nbd_client_detach_aio_context(BlockDriverState *bs) { - aio_set_fd_handler(bdrv_get_aio_context(client->bs), client->sock, - NULL, NULL, NULL); + aio_set_fd_handler(bdrv_get_aio_context(bs), + nbd_get_client_session(bs)->sock, NULL, NULL, NULL); } -void nbd_client_session_attach_aio_context(NbdClientSession *client, - AioContext *new_context) +void nbd_client_attach_aio_context(BlockDriverState *bs, + AioContext *new_context) { - aio_set_fd_handler(new_context, client->sock, - nbd_reply_ready, NULL, client); + aio_set_fd_handler(new_context, nbd_get_client_session(bs)->sock, + nbd_reply_ready, NULL, bs); } -void nbd_client_session_close(NbdClientSession *client) +void nbd_client_close(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; - if (!client->bs) { - return; - } if (client->sock == -1) { return; } nbd_send_request(client->sock, &request); - nbd_teardown_connection(client); - client->bs = NULL; + nbd_teardown_connection(bs); } -int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, - int sock, const char *export, Error **errp) +int nbd_client_init(BlockDriverState *bs, int sock, const char *export, + Error **errp) { + NbdClientSession *client = nbd_get_client_session(bs); int ret; /* NBD handshake */ @@ -391,13 +396,12 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); - client->bs = bs; client->sock = sock; /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); - nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs)); + nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; diff --git a/block/nbd-client.h b/block/nbd-client.h index cfeecc2775..fa4ff42d22 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -31,24 +31,24 @@ typedef struct NbdClientSession { struct nbd_reply reply; bool is_unix; - - BlockDriverState *bs; } NbdClientSession; -int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, - int sock, const char *export_name, Error **errp); -void nbd_client_session_close(NbdClientSession *client); - -int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, - int nb_sectors); -int nbd_client_session_co_flush(NbdClientSession *client); -int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov); -int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov); - -void nbd_client_session_detach_aio_context(NbdClientSession *client); -void nbd_client_session_attach_aio_context(NbdClientSession *client, - AioContext *new_context); +NbdClientSession *nbd_get_client_session(BlockDriverState *bs); + +int nbd_client_init(BlockDriverState *bs, int sock, const char *export_name, + Error **errp); +void nbd_client_close(BlockDriverState *bs); + +int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, + int nb_sectors); +int nbd_client_co_flush(BlockDriverState *bs); +int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); +int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); + +void nbd_client_detach_aio_context(BlockDriverState *bs); +void nbd_client_attach_aio_context(BlockDriverState *bs, + AioContext *new_context); #endif /* NBD_CLIENT_H */ diff --git a/block/nbd.c b/block/nbd.c index b05d1d0407..2f3b9adf72 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -224,6 +224,12 @@ static void nbd_config(BDRVNBDState *s, QDict *options, char **export, } } +NbdClientSession *nbd_get_client_session(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + return &s->client; +} + static int nbd_establish_connection(BlockDriverState *bs, Error **errp) { BDRVNBDState *s = bs->opaque; @@ -271,7 +277,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, } /* NBD handshake */ - result = nbd_client_session_init(&s->client, bs, sock, export, errp); + result = nbd_client_init(bs, sock, export, errp); g_free(export); return result; } @@ -279,26 +285,18 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_readv(&s->client, sector_num, - nb_sectors, qiov); + return nbd_client_co_readv(bs, sector_num, nb_sectors, qiov); } static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_writev(&s->client, sector_num, - nb_sectors, qiov); + return nbd_client_co_writev(bs, sector_num, nb_sectors, qiov); } static int nbd_co_flush(BlockDriverState *bs) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_flush(&s->client); + return nbd_client_co_flush(bs); } static void nbd_refresh_limits(BlockDriverState *bs, Error **errp) @@ -310,10 +308,7 @@ static void nbd_refresh_limits(BlockDriverState *bs, Error **errp) static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_discard(&s->client, sector_num, - nb_sectors); + return nbd_client_co_discard(bs, sector_num, nb_sectors); } static void nbd_close(BlockDriverState *bs) @@ -321,7 +316,7 @@ static void nbd_close(BlockDriverState *bs) BDRVNBDState *s = bs->opaque; qemu_opts_del(s->socket_opts); - nbd_client_session_close(&s->client); + nbd_client_close(bs); } static int64_t nbd_getlength(BlockDriverState *bs) @@ -333,17 +328,13 @@ static int64_t nbd_getlength(BlockDriverState *bs) static void nbd_detach_aio_context(BlockDriverState *bs) { - BDRVNBDState *s = bs->opaque; - - nbd_client_session_detach_aio_context(&s->client); + nbd_client_detach_aio_context(bs); } static void nbd_attach_aio_context(BlockDriverState *bs, AioContext *new_context) { - BDRVNBDState *s = bs->opaque; - - nbd_client_session_attach_aio_context(&s->client, new_context); + nbd_client_attach_aio_context(bs, new_context); } static void nbd_refresh_filename(BlockDriverState *bs) diff --git a/block/qcow2.c b/block/qcow2.c index 7e614d76a4..2ed8d95b1f 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2521,15 +2521,12 @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, { BDRVQcowState *s = bs->opaque; int64_t total_sectors = bs->total_sectors; - int growable = bs->growable; bool zero_beyond_eof = bs->zero_beyond_eof; int ret; BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE); - bs->growable = 1; bs->zero_beyond_eof = false; ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov); - bs->growable = growable; bs->zero_beyond_eof = zero_beyond_eof; /* bdrv_co_do_writev will have increased the total_sectors value to include @@ -2544,15 +2541,12 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size) { BDRVQcowState *s = bs->opaque; - int growable = bs->growable; bool zero_beyond_eof = bs->zero_beyond_eof; int ret; BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD); - bs->growable = 1; bs->zero_beyond_eof = false; ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size); - bs->growable = growable; bs->zero_beyond_eof = zero_beyond_eof; return ret; diff --git a/block/raw-posix.c b/block/raw-posix.c index e474c17974..b5f077a8f1 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1047,7 +1047,7 @@ static int aio_worker(void *arg) switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { case QEMU_AIO_READ: ret = handle_aiocb_rw(aiocb); - if (ret >= 0 && ret < aiocb->aio_nbytes && aiocb->bs->growable) { + if (ret >= 0 && ret < aiocb->aio_nbytes) { iov_memset(aiocb->aio_iov, aiocb->aio_niov, ret, 0, aiocb->aio_nbytes - ret); diff --git a/block/raw-win32.c b/block/raw-win32.c index 06243d76df..dae5d2fee9 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -101,7 +101,7 @@ static int aio_worker(void *arg) switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { case QEMU_AIO_READ: count = handle_aiocb_rw(aiocb); - if (count < aiocb->aio_nbytes && aiocb->bs->growable) { + if (count < aiocb->aio_nbytes) { /* A short read means that we have reached EOF. Pad the buffer * with zeros for bytes after EOF. */ iov_memset(aiocb->aio_iov, aiocb->aio_niov, count, diff --git a/block/sheepdog.c b/block/sheepdog.c index be3176fcb4..b320871e9c 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1730,7 +1730,7 @@ static int sd_create(const char *filename, QemuOpts *opts, BlockDriver *drv; /* Currently, only Sheepdog backing image is supported. */ - drv = bdrv_find_protocol(backing_file, true); + drv = bdrv_find_protocol(backing_file, true, NULL); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_setg(errp, "backing_file must be a sheepdog image"); ret = -EINVAL; @@ -2117,7 +2117,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num, int64_t offset = (sector_num + nb_sectors) * BDRV_SECTOR_SIZE; BDRVSheepdogState *s = bs->opaque; - if (bs->growable && offset > s->inode.vdi_size) { + if (offset > s->inode.vdi_size) { ret = sd_truncate(bs, offset); if (ret < 0) { return ret; diff --git a/block/vmdk.c b/block/vmdk.c index 7d079adc4a..8410a158a2 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -843,8 +843,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, } extent_path = g_malloc0(PATH_MAX); - path_combine(extent_path, sizeof(extent_path), - desc_file_path, fname); + path_combine(extent_path, PATH_MAX, desc_file_path, fname); extent_file = NULL; ret = bdrv_open(&extent_file, extent_path, NULL, NULL, bs->open_flags | BDRV_O_PROTOCOL, NULL, errp); |