[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 4/9] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
From: |
Kevin Wolf |
Subject: |
[PATCH v5 4/9] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate |
Date: |
Wed, 22 Apr 2020 17:21:24 +0200 |
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
undo any previous preallocation, but just adds the zero flag to all
relevant L2 entries. If an external data file is in use, a write_zeroes
request to the data file is made instead.
Signed-off-by: Kevin Wolf <address@hidden>
---
block/qcow2.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c
index 9cfbdfc939..bd632405d1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1726,6 +1726,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState
*bs, QDict *options,
bs->supported_zero_flags = header.version >= 3 ?
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
/* Repair image if dirty */
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
@@ -4214,6 +4215,35 @@ static int coroutine_fn
qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
g_assert_not_reached();
}
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
+ uint64_t zero_end = QEMU_ALIGN_UP(offset, s->cluster_size);
+
+ /* Use zero clusters as much as we can */
+ ret = qcow2_cluster_zeroize(bs, zero_start, zero_end - zero_start, 0);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
+ goto fail;
+ }
+
+ /* Write explicit zeros for the unaligned head */
+ if (zero_start > old_length) {
+ uint8_t *buf = qemu_blockalign0(bs, s->cluster_size);
+ QEMUIOVector qiov;
+ qemu_iovec_init_buf(&qiov, buf, zero_start - old_length);
+
+ qemu_co_mutex_unlock(&s->lock);
+ ret = qcow2_co_pwritev_part(bs, old_length, qiov.size, &qiov, 0,
0);
+ qemu_co_mutex_lock(&s->lock);
+
+ qemu_vfree(buf);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to zero out the new
area");
+ goto fail;
+ }
+ }
+ }
+
if (prealloc != PREALLOC_MODE_OFF) {
/* Flush metadata before actually changing the image size */
ret = qcow2_write_caches(bs);
--
2.25.3
- [PATCH v5 0/9] block: Fix resize (extending) of short overlays, Kevin Wolf, 2020/04/22
- [PATCH v5 1/9] block: Add flags to BlockDriver.bdrv_co_truncate(), Kevin Wolf, 2020/04/22
- [PATCH v5 3/9] block-backend: Add flags to blk_truncate(), Kevin Wolf, 2020/04/22
- [PATCH v5 4/9] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate,
Kevin Wolf <=
- Re: [PATCH v5 4/9] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate, Eric Blake, 2020/04/22
- fdatasync semantics and block device backup, Bryan S Rosenburg, 2020/04/27
- Re: fdatasync semantics and block device backup, Kevin Wolf, 2020/04/28
- RE: fdatasync semantics and block device backup, Bryan S Rosenburg, 2020/04/28
- Re: fdatasync semantics and block device backup, Kevin Wolf, 2020/04/28
Re: [PATCH v5 4/9] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate, Max Reitz, 2020/04/23