diff options
Diffstat (limited to 'block')
-rwxr-xr-x | block/blkreplay.c | 8 | ||||
-rw-r--r-- | block/dmg.c | 1 | ||||
-rw-r--r-- | block/gluster.c | 14 | ||||
-rw-r--r-- | block/io.c | 181 | ||||
-rw-r--r-- | block/iscsi.c | 72 | ||||
-rw-r--r-- | block/parallels.c | 6 | ||||
-rw-r--r-- | block/qcow.c | 4 | ||||
-rw-r--r-- | block/qcow2-cache.c | 11 | ||||
-rw-r--r-- | block/qcow2-cluster.c | 7 | ||||
-rw-r--r-- | block/qcow2-refcount.c | 6 | ||||
-rw-r--r-- | block/qcow2.c | 91 | ||||
-rw-r--r-- | block/qcow2.h | 1 | ||||
-rw-r--r-- | block/qed-check.c | 3 | ||||
-rw-r--r-- | block/qed.c | 38 | ||||
-rw-r--r-- | block/raw-posix.c | 58 | ||||
-rw-r--r-- | block/raw_bsd.c | 10 | ||||
-rw-r--r-- | block/snapshot.c | 3 | ||||
-rw-r--r-- | block/vhdx.c | 1 | ||||
-rw-r--r-- | block/vmdk.c | 19 | ||||
-rw-r--r-- | block/vvfat.c | 3 |
20 files changed, 287 insertions, 250 deletions
diff --git a/block/blkreplay.c b/block/blkreplay.c index 42f1813af1..525c2d54e0 100755 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -103,11 +103,11 @@ static int coroutine_fn blkreplay_co_writev(BlockDriverState *bs, return ret; } -static int coroutine_fn blkreplay_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { uint64_t reqid = request_id++; - int ret = bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags); + int ret = bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); block_request_create(reqid, bs, qemu_coroutine_self()); qemu_coroutine_yield(); @@ -147,7 +147,7 @@ static BlockDriver bdrv_blkreplay = { .bdrv_co_readv = blkreplay_co_readv, .bdrv_co_writev = blkreplay_co_writev, - .bdrv_co_write_zeroes = blkreplay_co_write_zeroes, + .bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes, .bdrv_co_discard = blkreplay_co_discard, .bdrv_co_flush = blkreplay_co_flush, }; diff --git a/block/dmg.c b/block/dmg.c index 1ea5f22d82..06eb5138f3 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -32,7 +32,6 @@ #ifdef CONFIG_BZIP2 #include <bzlib.h> #endif -#include <glib.h> enum { /* Limit chunk sizes to prevent unreasonable amounts of memory being used diff --git a/block/gluster.c b/block/gluster.c index a8aaacf645..d361d8e847 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -454,14 +454,12 @@ static void qemu_gluster_reopen_abort(BDRVReopenState *state) } #ifdef CONFIG_GLUSTERFS_ZEROFILL -static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int size, BdrvRequestFlags flags) { int ret; GlusterAIOCB acb; BDRVGlusterState *s = bs->opaque; - off_t size = nb_sectors * BDRV_SECTOR_SIZE; - off_t offset = sector_num * BDRV_SECTOR_SIZE; acb.size = size; acb.ret = 0; @@ -769,7 +767,7 @@ static BlockDriver bdrv_gluster = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -796,7 +794,7 @@ static BlockDriver bdrv_gluster_tcp = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -823,7 +821,7 @@ static BlockDriver bdrv_gluster_unix = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -850,7 +848,7 @@ static BlockDriver bdrv_gluster_rdma = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; diff --git a/block/io.c b/block/io.c index 2d832aa532..fb99a7151c 100644 --- a/block/io.c +++ b/block/io.c @@ -42,8 +42,8 @@ static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, void *opaque, bool is_write); static void coroutine_fn bdrv_co_do_rw(void *opaque); -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); +static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags); static void bdrv_parent_drained_begin(BlockDriverState *bs) { @@ -620,18 +620,25 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true, 0); } -int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { - return bdrv_rw_co(bs, sector_num, NULL, nb_sectors, true, - BDRV_REQ_ZERO_WRITE | flags); + QEMUIOVector qiov; + struct iovec iov = { + .iov_base = NULL, + .iov_len = count, + }; + + qemu_iovec_init_external(&qiov, &iov, 1); + return bdrv_prwv_co(bs, offset, &qiov, true, + BDRV_REQ_ZERO_WRITE | flags); } /* - * Completely zero out a block device with the help of bdrv_write_zeroes. + * Completely zero out a block device with the help of bdrv_pwrite_zeroes. * The operation is sped up by checking the block status and only writing * zeroes to the device if they currently do not return zeroes. Optional - * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP, + * flags are passed through to bdrv_pwrite_zeroes (e.g. BDRV_REQ_MAY_UNMAP, * BDRV_REQ_FUA). * * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). @@ -662,7 +669,8 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) sector_num += n; continue; } - ret = bdrv_write_zeroes(bs, sector_num, n, flags); + ret = bdrv_pwrite_zeroes(bs, sector_num << BDRV_SECTOR_BITS, + n << BDRV_SECTOR_BITS, flags); if (ret < 0) { error_report("error writing zeroes at sector %" PRId64 ": %s", sector_num, strerror(-ret)); @@ -808,7 +816,9 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, int ret; if (drv->bdrv_co_pwritev) { - ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags); + ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, + flags & bs->supported_write_flags); + flags &= ~bs->supported_write_flags; goto emulate_flags; } @@ -893,10 +903,12 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, goto err; } - if (drv->bdrv_co_write_zeroes && + if (drv->bdrv_co_pwrite_zeroes && buffer_is_zero(bounce_buffer, iov.iov_len)) { - ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num, - cluster_nb_sectors, 0); + ret = bdrv_co_do_pwrite_zeroes(bs, + cluster_sector_num * BDRV_SECTOR_SIZE, + cluster_nb_sectors * BDRV_SECTOR_SIZE, + 0); } else { /* This does not change the data on the disk, it is not necessary * to flush even in cache=writethrough mode. @@ -1110,36 +1122,40 @@ int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, #define MAX_WRITE_ZEROES_BOUNCE_BUFFER 32768 -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { BlockDriver *drv = bs->drv; QEMUIOVector qiov; struct iovec iov = {0}; int ret = 0; bool need_flush = false; + int head = 0; + int tail = 0; - int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes, - BDRV_REQUEST_MAX_SECTORS); + int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX); + int alignment = MAX(bs->bl.pwrite_zeroes_alignment ?: 1, + bs->request_alignment); - while (nb_sectors > 0 && !ret) { - int num = nb_sectors; + assert(is_power_of_2(alignment)); + head = offset & (alignment - 1); + tail = (offset + count) & (alignment - 1); + max_write_zeroes &= ~(alignment - 1); + + while (count > 0 && !ret) { + int num = count; /* Align request. Block drivers can expect the "bulk" of the request - * to be aligned. + * to be aligned, and that unaligned requests do not cross cluster + * boundaries. */ - if (bs->bl.write_zeroes_alignment - && num > bs->bl.write_zeroes_alignment) { - if (sector_num % bs->bl.write_zeroes_alignment != 0) { - /* Make a small request up to the first aligned sector. */ - num = bs->bl.write_zeroes_alignment; - num -= sector_num % bs->bl.write_zeroes_alignment; - } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) { - /* Shorten the request to the last aligned sector. num cannot - * underflow because num > bs->bl.write_zeroes_alignment. - */ - num -= (sector_num + num) % bs->bl.write_zeroes_alignment; - } + if (head) { + /* Make a small request up to the first aligned sector. */ + num = MIN(count, alignment - head); + head = 0; + } else if (tail && num > alignment) { + /* Shorten the request to the last aligned sector. */ + num -= tail; } /* limit request size */ @@ -1149,9 +1165,9 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, ret = -ENOTSUP; /* First try the efficient write zeroes operation */ - if (drv->bdrv_co_write_zeroes) { - ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, - flags & bs->supported_zero_flags); + if (drv->bdrv_co_pwrite_zeroes) { + ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num, + flags & bs->supported_zero_flags); if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) && !(bs->supported_zero_flags & BDRV_REQ_FUA)) { need_flush = true; @@ -1173,33 +1189,31 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, write_flags &= ~BDRV_REQ_FUA; need_flush = true; } - num = MIN(num, max_xfer_len); - iov.iov_len = num * BDRV_SECTOR_SIZE; + num = MIN(num, max_xfer_len << BDRV_SECTOR_BITS); + iov.iov_len = num; if (iov.iov_base == NULL) { - iov.iov_base = qemu_try_blockalign(bs, num * BDRV_SECTOR_SIZE); + iov.iov_base = qemu_try_blockalign(bs, num); if (iov.iov_base == NULL) { ret = -ENOMEM; goto fail; } - memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE); + memset(iov.iov_base, 0, num); } qemu_iovec_init_external(&qiov, &iov, 1); - ret = bdrv_driver_pwritev(bs, sector_num * BDRV_SECTOR_SIZE, - num * BDRV_SECTOR_SIZE, &qiov, - write_flags); + ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags); /* Keep bounce buffer around if it is big enough for all * all future requests. */ - if (num < max_xfer_len) { + if (num < max_xfer_len << BDRV_SECTOR_BITS) { qemu_vfree(iov.iov_base); iov.iov_base = NULL; } } - sector_num += num; - nb_sectors -= num; + offset += num; + count -= num; } fail: @@ -1237,7 +1251,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs, ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req); if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF && - !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_write_zeroes && + !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes && qemu_iovec_is_zero(qiov)) { flags |= BDRV_REQ_ZERO_WRITE; if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) { @@ -1249,7 +1263,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs, /* Do nothing, write notifier decided to fail this request */ } else if (flags & BDRV_REQ_ZERO_WRITE) { bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); - ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags); + ret = bdrv_co_do_pwrite_zeroes(bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, flags); } else { bdrv_debug_event(bs, BLKDBG_PWRITEV); ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, flags); @@ -1427,6 +1442,14 @@ int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, bytes += offset & (align - 1); offset = offset & ~(align - 1); + + /* We have read the tail already if the request is smaller + * than one aligned block. + */ + if (bytes < align) { + qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes); + bytes = align; + } } if ((offset + bytes) & (align - 1)) { @@ -1502,18 +1525,18 @@ int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov, 0); } -int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BdrvRequestFlags flags) +int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, + BdrvRequestFlags flags) { - trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags); + trace_bdrv_co_pwrite_zeroes(bs, offset, count, flags); if (!(bs->open_flags & BDRV_O_UNMAP)) { flags &= ~BDRV_REQ_MAY_UNMAP; } - return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL, - BDRV_REQ_ZERO_WRITE | flags); + return bdrv_co_pwritev(bs, offset, count, NULL, + BDRV_REQ_ZERO_WRITE | flags); } typedef struct BdrvCoGetBlockStatusData { @@ -1865,17 +1888,6 @@ BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, cb, opaque, true); } -BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags, - BlockCompletionFunc *cb, void *opaque) -{ - trace_bdrv_aio_write_zeroes(bs, sector_num, nb_sectors, flags, opaque); - - return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors, - BDRV_REQ_ZERO_WRITE | flags, - cb, opaque, true); -} - void bdrv_aio_cancel(BlockAIOCB *acb) { qemu_aio_ref(acb); @@ -1905,6 +1917,27 @@ void bdrv_aio_cancel_async(BlockAIOCB *acb) /**************************************************************/ /* async block device emulation */ +typedef struct BlockRequest { + union { + /* Used during read, write, trim */ + struct { + int64_t sector; + int nb_sectors; + int flags; + QEMUIOVector *qiov; + }; + /* Used during ioctl */ + struct { + int req; + void *buf; + }; + }; + BlockCompletionFunc *cb; + void *opaque; + + int error; +} BlockRequest; + typedef struct BlockAIOCBCoroutine { BlockAIOCB common; BlockRequest req; @@ -2309,19 +2342,6 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) return rwco.ret; } -typedef struct { - CoroutineIOCompletion *co; - QEMUBH *bh; -} BdrvIoctlCompletionData; - -static void bdrv_ioctl_bh_cb(void *opaque) -{ - BdrvIoctlCompletionData *data = opaque; - - bdrv_co_io_em_complete(data->co, -ENOTSUP); - qemu_bh_delete(data->bh); -} - static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf) { BlockDriver *drv = bs->drv; @@ -2339,11 +2359,8 @@ static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf) acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co); if (!acb) { - BdrvIoctlCompletionData *data = g_new(BdrvIoctlCompletionData, 1); - data->bh = aio_bh_new(bdrv_get_aio_context(bs), - bdrv_ioctl_bh_cb, data); - data->co = &co; - qemu_bh_schedule(data->bh); + co.ret = -ENOTSUP; + goto out; } qemu_coroutine_yield(); out: diff --git a/block/iscsi.c b/block/iscsi.c index e7d5f7b0c3..7e78adea15 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -401,18 +401,26 @@ static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun) return sector * BDRV_SECTOR_SIZE / iscsilun->block_size; } -static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors, - IscsiLun *iscsilun) +static bool is_byte_request_lun_aligned(int64_t offset, int count, + IscsiLun *iscsilun) { - if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size || - (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) { - error_report("iSCSI misaligned request: " - "iscsilun->block_size %u, sector_num %" PRIi64 - ", nb_sectors %d", - iscsilun->block_size, sector_num, nb_sectors); - return 0; - } - return 1; + if (offset % iscsilun->block_size || count % iscsilun->block_size) { + error_report("iSCSI misaligned request: " + "iscsilun->block_size %u, offset %" PRIi64 + ", count %d", + iscsilun->block_size, offset, count); + return false; + } + return true; +} + +static bool is_sector_request_lun_aligned(int64_t sector_num, int nb_sectors, + IscsiLun *iscsilun) +{ + assert(nb_sectors < BDRV_REQUEST_MAX_SECTORS); + return is_byte_request_lun_aligned(sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, + iscsilun); } static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun) @@ -461,7 +469,7 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors, if (fua) { assert(iscsilun->dpofua); } - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -541,7 +549,7 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs, iscsi_co_init_iscsitask(iscsilun, &iTask); - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { ret = -EINVAL; goto out; } @@ -638,7 +646,7 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs, uint64_t lba; uint32_t num_sectors; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -926,7 +934,7 @@ coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num, struct IscsiTask iTask; struct unmap_list list; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -977,8 +985,8 @@ retry: } static int -coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { IscsiLun *iscsilun = bs->opaque; struct IscsiTask iTask; @@ -986,8 +994,8 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, uint32_t nb_blocks; bool use_16_for_ws = iscsilun->use_16_for_rw; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { - return -EINVAL; + if (!is_byte_request_lun_aligned(offset, count, iscsilun)) { + return -ENOTSUP; } if (flags & BDRV_REQ_MAY_UNMAP) { @@ -1008,8 +1016,8 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, return -ENOTSUP; } - lba = sector_qemu2lun(sector_num, iscsilun); - nb_blocks = sector_qemu2lun(nb_sectors, iscsilun); + lba = offset / iscsilun->block_size; + nb_blocks = count / iscsilun->block_size; if (iscsilun->zeroblock == NULL) { iscsilun->zeroblock = g_try_malloc0(iscsilun->block_size); @@ -1065,9 +1073,11 @@ retry: } if (flags & BDRV_REQ_MAY_UNMAP) { - iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors); + iscsi_allocationmap_clear(iscsilun, offset >> BDRV_SECTOR_BITS, + count >> BDRV_SECTOR_BITS); } else { - iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors); + iscsi_allocationmap_set(iscsilun, offset >> BDRV_SECTOR_BITS, + count >> BDRV_SECTOR_BITS); } return 0; @@ -1711,15 +1721,19 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp) } bs->bl.discard_alignment = sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); + } else { + bs->bl.discard_alignment = iscsilun->block_size >> BDRV_SECTOR_BITS; } - if (iscsilun->bl.max_ws_len < 0xffffffff) { - bs->bl.max_write_zeroes = - sector_limits_lun2qemu(iscsilun->bl.max_ws_len, iscsilun); + if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) { + bs->bl.max_pwrite_zeroes = + iscsilun->bl.max_ws_len * iscsilun->block_size; } if (iscsilun->lbp.lbpws) { - bs->bl.write_zeroes_alignment = - sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); + bs->bl.pwrite_zeroes_alignment = + iscsilun->bl.opt_unmap_gran * iscsilun->block_size; + } else { + bs->bl.pwrite_zeroes_alignment = iscsilun->block_size; } bs->bl.opt_transfer_length = sector_limits_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun); @@ -1852,7 +1866,7 @@ static BlockDriver bdrv_iscsi = { .bdrv_co_get_block_status = iscsi_co_get_block_status, .bdrv_co_discard = iscsi_co_discard, - .bdrv_co_write_zeroes = iscsi_co_write_zeroes, + .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes, .bdrv_co_readv = iscsi_co_readv, .bdrv_co_writev_flags = iscsi_co_writev_flags, .bdrv_co_flush_to_disk = iscsi_co_flush, diff --git a/block/parallels.c b/block/parallels.c index 99fc0f77ef..d6a1a616b6 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -204,13 +204,15 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, return -EINVAL; } - to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx; + to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx; space = to_allocate * s->tracks; if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) { int ret; space += s->prealloc_size; if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_write_zeroes(bs->file->bs, s->data_end, space, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, + s->data_end << BDRV_SECTOR_BITS, + space << BDRV_SECTOR_BITS, 0); } else { ret = bdrv_truncate(bs->file->bs, (s->data_end + space) << BDRV_SECTOR_BITS); diff --git a/block/qcow.c b/block/qcow.c index cb4bf0299f..c5cf813469 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -868,8 +868,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) } tmp = g_malloc0(BDRV_SECTOR_SIZE); - for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/ - BDRV_SECTOR_SIZE); i++) { + for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE); + i++) { ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, tmp, BDRV_SECTOR_SIZE, 0); if (ret != BDRV_SECTOR_SIZE) { diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 0fe8edae41..208a060421 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -226,7 +226,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) return 0; } -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) +int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c) { BDRVQcow2State *s = bs->opaque; int result = 0; @@ -242,8 +242,15 @@ int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) } } + return result; +} + +int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) +{ + int result = qcow2_cache_write(bs, c); + if (result == 0) { - ret = bdrv_flush(bs->file->bs); + int ret = bdrv_flush(bs->file->bs); if (ret < 0) { result = ret; } diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 892e0fbfbf..b04bfafd65 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1765,8 +1765,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, goto fail; } - ret = bdrv_write_zeroes(bs->file->bs, offset / BDRV_SECTOR_SIZE, - s->cluster_sectors, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, offset, s->cluster_size, 0); if (ret < 0) { if (!preallocated) { qcow2_free_clusters(bs, offset, s->cluster_size, @@ -1868,8 +1867,8 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs, } for (i = 0; i < s->nb_snapshots; i++) { - int l1_sectors = (s->snapshots[i].l1_size * sizeof(uint64_t) + - BDRV_SECTOR_SIZE - 1) / BDRV_SECTOR_SIZE; + int l1_sectors = DIV_ROUND_UP(s->snapshots[i].l1_size * + sizeof(uint64_t), BDRV_SECTOR_SIZE); l1_table = g_realloc(l1_table, l1_sectors * BDRV_SECTOR_SIZE); diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 7fa972a383..66f187a74b 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -490,14 +490,12 @@ static int alloc_refcount_block(BlockDriverState *bs, uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); blocks_clusters = 1 + - ((table_clusters + s->refcount_block_size - 1) - / s->refcount_block_size); + DIV_ROUND_UP(table_clusters, s->refcount_block_size); uint64_t meta_clusters = table_clusters + blocks_clusters; last_table_size = table_size; table_size = next_refcount_table_size(s, blocks_used + - ((meta_clusters + s->refcount_block_size - 1) - / s->refcount_block_size)); + DIV_ROUND_UP(meta_clusters, s->refcount_block_size)); } while (last_table_size != table_size); diff --git a/block/qcow2.c b/block/qcow2.c index c9306a78c1..6f5fb810e4 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1193,7 +1193,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQcow2State *s = bs->opaque; - bs->bl.write_zeroes_alignment = s->cluster_sectors; + bs->bl.pwrite_zeroes_alignment = s->cluster_size; } static int qcow2_set_key(BlockDriverState *bs, const char *key) @@ -2406,65 +2406,55 @@ finish: } -static bool is_zero_cluster(BlockDriverState *bs, int64_t start) +static bool is_zero_sectors(BlockDriverState *bs, int64_t start, + uint32_t count) { - BDRVQcow2State *s = bs->opaque; int nr; BlockDriverState *file; - int64_t res = bdrv_get_block_status_above(bs, NULL, start, - s->cluster_sectors, &nr, &file); - return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == s->cluster_sectors; -} - -static bool is_zero_cluster_top_locked(BlockDriverState *bs, int64_t start) -{ - BDRVQcow2State *s = bs->opaque; - int nr = s->cluster_sectors; - uint64_t off; - int ret; + int64_t res; - ret = qcow2_get_cluster_offset(bs, start << BDRV_SECTOR_BITS, &nr, &off); - assert(nr == s->cluster_sectors); - return ret == QCOW2_CLUSTER_UNALLOCATED || ret == QCOW2_CLUSTER_ZERO; + if (!count) { + return true; + } + res = bdrv_get_block_status_above(bs, NULL, start, count, + &nr, &file); + return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count; } -static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { int ret; BDRVQcow2State *s = bs->opaque; - int head = sector_num % s->cluster_sectors; - int tail = (sector_num + nb_sectors) % s->cluster_sectors; + uint32_t head = offset % s->cluster_size; + uint32_t tail = (offset + count) % s->cluster_size; - if (head != 0 || tail != 0) { - int64_t cl_end = -1; + trace_qcow2_pwrite_zeroes_start_req(qemu_coroutine_self(), offset, count); - sector_num -= head; - nb_sectors += head; + if (head || tail) { + int64_t cl_start = (offset - head) >> BDRV_SECTOR_BITS; + uint64_t off; + int nr; - if (tail != 0) { - nb_sectors += s->cluster_sectors - tail; - } + assert(head + count <= s->cluster_size); - if (!is_zero_cluster(bs, sector_num)) { + /* check whether remainder of cluster already reads as zero */ + if (!(is_zero_sectors(bs, cl_start, + DIV_ROUND_UP(head, BDRV_SECTOR_SIZE)) && + is_zero_sectors(bs, (offset + count) >> BDRV_SECTOR_BITS, + DIV_ROUND_UP(-tail & (s->cluster_size - 1), + BDRV_SECTOR_SIZE)))) { return -ENOTSUP; } - if (nb_sectors > s->cluster_sectors) { - /* Technically the request can cover 2 clusters, f.e. 4k write - at s->cluster_sectors - 2k offset. One of these cluster can - be zeroed, one unallocated */ - cl_end = sector_num + nb_sectors - s->cluster_sectors; - if (!is_zero_cluster(bs, cl_end)) { - return -ENOTSUP; - } - } - qemu_co_mutex_lock(&s->lock); /* We can have new write after previous check */ - if (!is_zero_cluster_top_locked(bs, sector_num) || - (cl_end > 0 && !is_zero_cluster_top_locked(bs, cl_end))) { + offset = cl_start << BDRV_SECTOR_BITS; + count = s->cluster_size; + nr = s->cluster_sectors; + ret = qcow2_get_cluster_offset(bs, offset, &nr, &off); + if (ret != QCOW2_CLUSTER_UNALLOCATED && ret != QCOW2_CLUSTER_ZERO) { qemu_co_mutex_unlock(&s->lock); return -ENOTSUP; } @@ -2472,8 +2462,10 @@ static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, qemu_co_mutex_lock(&s->lock); } + trace_qcow2_pwrite_zeroes(qemu_coroutine_self(), offset, count); + /* Whatever is left can use real zero clusters */ - ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS, nb_sectors); + ret = qcow2_zero_clusters(bs, offset, count >> BDRV_SECTOR_BITS); qemu_co_mutex_unlock(&s->lock); return ret; @@ -2664,8 +2656,8 @@ static int make_completely_empty(BlockDriverState *bs) /* After this call, neither the in-memory nor the on-disk refcount * information accurately describe the actual references */ - ret = bdrv_write_zeroes(bs->file->bs, s->l1_table_offset / BDRV_SECTOR_SIZE, - l1_clusters * s->cluster_sectors, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, s->l1_table_offset, + l1_clusters * s->cluster_size, 0); if (ret < 0) { goto fail_broken_refcounts; } @@ -2678,9 +2670,8 @@ static int make_completely_empty(BlockDriverState *bs) * overwrite parts of the existing refcount and L1 table, which is not * an issue because the dirty flag is set, complete data loss is in fact * desired and partial data loss is consequently fine as well */ - ret = bdrv_write_zeroes(bs->file->bs, s->cluster_size / BDRV_SECTOR_SIZE, - (2 + l1_clusters) * s->cluster_size / - BDRV_SECTOR_SIZE, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, s->cluster_size, + (2 + l1_clusters) * s->cluster_size, 0); /* This call (even if it failed overall) may have overwritten on-disk * refcount structures; in that case, the in-memory refcount information * will probably differ from the on-disk information which makes the BDS @@ -2822,14 +2813,14 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) int ret; qemu_co_mutex_lock(&s->lock); - ret = qcow2_cache_flush(bs, s->l2_table_cache); + ret = qcow2_cache_write(bs, s->l2_table_cache); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; } if (qcow2_need_accurate_refcounts(s)) { - ret = qcow2_cache_flush(bs, s->refcount_block_cache); + ret = qcow2_cache_write(bs, s->refcount_block_cache); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; @@ -3381,7 +3372,7 @@ BlockDriver bdrv_qcow2 = { .bdrv_co_writev = qcow2_co_writev, .bdrv_co_flush_to_os = qcow2_co_flush_to_os, - .bdrv_co_write_zeroes = qcow2_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qcow2_co_pwrite_zeroes, .bdrv_co_discard = qcow2_co_discard, .bdrv_truncate = qcow2_truncate, .bdrv_write_compressed = qcow2_write_compressed, diff --git a/block/qcow2.h b/block/qcow2.h index a063a3c1a1..7db9795d44 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -583,6 +583,7 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c); void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c, void *table); int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); +int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c); int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, Qcow2Cache *dependency); void qcow2_cache_depends_on_flush(Qcow2Cache *c); diff --git a/block/qed-check.c b/block/qed-check.c index 622f308976..dcd4f036b8 100644 --- a/block/qed-check.c +++ b/block/qed-check.c @@ -234,8 +234,7 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) } check.result->bfi.total_clusters = - (s->header.image_size + s->header.cluster_size - 1) / - s->header.cluster_size; + DIV_ROUND_UP(s->header.image_size, s->header.cluster_size); ret = qed_check_l1_table(&check, s->l1_table); if (ret == 0) { /* Only check for leaks if entire image was scanned successfully */ diff --git a/block/qed.c b/block/qed.c index b591d4a3fc..12068061ac 100644 --- a/block/qed.c +++ b/block/qed.c @@ -143,8 +143,7 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb, * them, and write back. */ - int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) / - BDRV_SECTOR_SIZE; + int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE); size_t len = nsectors * BDRV_SECTOR_SIZE; QEDWriteHeaderCB *write_header_cb = gencb_alloc(sizeof(*write_header_cb), cb, opaque); @@ -518,7 +517,7 @@ static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQEDState *s = bs->opaque; - bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS; + bs->bl.pwrite_zeroes_alignment = s->header.cluster_size; } /* We have nothing to do for QED reopen, stubs just return @@ -1419,7 +1418,7 @@ typedef struct { bool done; } QEDWriteZeroesCB; -static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) +static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret) { QEDWriteZeroesCB *cb = opaque; @@ -1430,10 +1429,10 @@ static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) } } -static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, + int count, + BdrvRequestFlags flags) { BlockAIOCB *blockacb; BDRVQEDState *s = bs->opaque; @@ -1441,25 +1440,22 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, QEMUIOVector qiov; struct iovec iov; - /* Refuse if there are untouched backing file sectors */ - if (bs->backing) { - if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } - if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } + /* Fall back if the request is not aligned */ + if (qed_offset_into_cluster(s, offset) || + qed_offset_into_cluster(s, count)) { + return -ENOTSUP; } /* Zero writes start without an I/O buffer. If a buffer becomes necessary * then it will be allocated during request processing. */ - iov.iov_base = NULL, - iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE, + iov.iov_base = NULL; + iov.iov_len = count; qemu_iovec_init_external(&qiov, &iov, 1); - blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors, - qed_co_write_zeroes_cb, &cb, + blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov, + count >> BDRV_SECTOR_BITS, + qed_co_pwrite_zeroes_cb, &cb, QED_AIOCB_WRITE | QED_AIOCB_ZERO); if (!blockacb) { return -EIO; @@ -1664,7 +1660,7 @@ static BlockDriver bdrv_qed = { .bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_aio_readv = bdrv_qed_aio_readv, .bdrv_aio_writev = bdrv_qed_aio_writev, - .bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes, + .bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes, .bdrv_truncate = bdrv_qed_truncate, .bdrv_getlength = bdrv_qed_getlength, .bdrv_get_info = bdrv_qed_get_info, diff --git a/block/raw-posix.c b/block/raw-posix.c index a4f5a1ba5f..ce2e20f203 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -729,9 +729,33 @@ static void raw_reopen_abort(BDRVReopenState *state) state->opaque = NULL; } +static int hdev_get_max_transfer_length(int fd) +{ +#ifdef BLKSECTGET + int max_sectors = 0; + if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) { + return max_sectors; + } else { + return -errno; + } +#else + return -ENOSYS; +#endif +} + static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; + struct stat st; + + if (!fstat(s->fd, &st)) { + if (S_ISBLK(st.st_mode)) { + int ret = hdev_get_max_transfer_length(s->fd); + if (ret >= 0) { + bs->bl.max_transfer_length = ret; + } + } + } raw_probe_alignment(bs, s->fd, errp); bs->bl.min_mem_alignment = s->buf_align; @@ -1252,8 +1276,8 @@ static int aio_worker(void *arg) } static int paio_submit_co(BlockDriverState *bs, int fd, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - int type) + int64_t offset, QEMUIOVector *qiov, + int count, int type) { RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); ThreadPool *pool; @@ -1262,16 +1286,16 @@ static int paio_submit_co(BlockDriverState *bs, int fd, acb->aio_type = type; acb->aio_fildes = fd; - acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; - acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; + acb->aio_nbytes = count; + acb->aio_offset = offset; if (qiov) { acb->aio_iov = qiov->iov; acb->aio_niov = qiov->niov; - assert(qiov->size == acb->aio_nbytes); + assert(qiov->size == count); } - trace_paio_submit_co(sector_num, nb_sectors, type); + trace_paio_submit_co(offset, count, type); pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); return thread_pool_submit_co(pool, aio_worker, acb); } @@ -1868,17 +1892,17 @@ static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs, cb, opaque, QEMU_AIO_DISCARD); } -static int coroutine_fn raw_co_write_zeroes( - BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn raw_co_pwrite_zeroes( + BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { BDRVRawState *s = bs->opaque; if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_WRITE_ZEROES); } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_DISCARD); } return -ENOTSUP; @@ -1931,7 +1955,7 @@ BlockDriver bdrv_file = { .bdrv_create = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = raw_co_get_block_status, - .bdrv_co_write_zeroes = raw_co_write_zeroes, + .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, @@ -2293,8 +2317,8 @@ static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs, cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); } -static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { BDRVRawState *s = bs->opaque; int rc; @@ -2304,10 +2328,10 @@ static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, return rc; } if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV); } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); } return -ENOTSUP; @@ -2379,7 +2403,7 @@ static BlockDriver bdrv_host_device = { .bdrv_reopen_abort = raw_reopen_abort, .bdrv_create = hdev_create, .create_opts = &raw_create_opts, - .bdrv_co_write_zeroes = hdev_co_write_zeroes, + .bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 3385ed448d..b1d5237135 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -127,11 +127,11 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, (sector_num << BDRV_SECTOR_BITS); } -static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, + BdrvRequestFlags flags) { - return bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags); + return bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); } static int coroutine_fn raw_co_discard(BlockDriverState *bs, @@ -252,7 +252,7 @@ BlockDriver bdrv_raw = { .bdrv_create = &raw_create, .bdrv_co_readv = &raw_co_readv, .bdrv_co_writev_flags = &raw_co_writev_flags, - .bdrv_co_write_zeroes = &raw_co_write_zeroes, + .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes, .bdrv_co_discard = &raw_co_discard, .bdrv_co_get_block_status = &raw_co_get_block_status, .bdrv_truncate = &raw_truncate, diff --git a/block/snapshot.c b/block/snapshot.c index 6e6e34fcf4..da89d2b085 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -409,9 +409,6 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs, if (bdrv_can_snapshot(bs) && bdrv_snapshot_find(bs, snapshot, name) >= 0) { ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err); - if (ret < 0) { - goto fail; - } } aio_context_release(ctx); if (ret < 0) { diff --git a/block/vhdx.c b/block/vhdx.c index c0d24a24ee..f5605a2ff4 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -27,7 +27,6 @@ #include "migration/migration.h" #include <uuid/uuid.h> -#include <glib.h> /* Options for VHDX creation */ diff --git a/block/vmdk.c b/block/vmdk.c index 372e5edc15..ee09423b46 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -34,7 +34,6 @@ #include "migration/migration.h" #include "qemu/cutils.h" #include <zlib.h> -#include <glib.h> #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V') @@ -998,9 +997,9 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) for (i = 0; i < s->num_extents; i++) { if (!s->extents[i].flat) { - bs->bl.write_zeroes_alignment = - MAX(bs->bl.write_zeroes_alignment, - s->extents[i].cluster_sectors); + bs->bl.pwrite_zeroes_alignment = + MAX(bs->bl.pwrite_zeroes_alignment, + s->extents[i].cluster_sectors << BDRV_SECTOR_BITS); } } } @@ -1704,15 +1703,13 @@ static int vmdk_write_compressed(BlockDriverState *bs, } } -static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, + int bytes, + BdrvRequestFlags flags) { int ret; BDRVVmdkState *s = bs->opaque; - uint64_t offset = sector_num * BDRV_SECTOR_SIZE; - uint64_t bytes = nb_sectors * BDRV_SECTOR_SIZE; qemu_co_mutex_lock(&s->lock); /* write zeroes could fail if sectors not aligned to cluster, test it with @@ -2403,7 +2400,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_co_preadv = vmdk_co_preadv, .bdrv_co_pwritev = vmdk_co_pwritev, .bdrv_write_compressed = vmdk_write_compressed, - .bdrv_co_write_zeroes = vmdk_co_write_zeroes, + .bdrv_co_pwrite_zeroes = vmdk_co_pwrite_zeroes, .bdrv_close = vmdk_close, .bdrv_create = vmdk_create, .bdrv_co_flush_to_disk = vmdk_co_flush, diff --git a/block/vvfat.c b/block/vvfat.c index a39dbe67e2..6d2e21ce11 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1960,8 +1960,7 @@ DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i)) /* check file size with FAT */ cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2); if (cluster_count != - (le32_to_cpu(direntries[i].size) + s->cluster_size - - 1) / s->cluster_size) { + DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) { DLOG(fprintf(stderr, "Cluster count mismatch\n")); goto fail; } |