[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 53/54] qcow2: truncate the tail of the image file aft
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 53/54] qcow2: truncate the tail of the image file after shrinking the image |
Date: |
Fri, 6 Oct 2017 17:54:21 +0200 |
From: Pavel Butsykin <address@hidden>
Now after shrinking the image, at the end of the image file, there might be a
tail that probably will never be used. So we can find the last used cluster and
cut the tail.
Signed-off-by: Pavel Butsykin <address@hidden>
Reviewed-by: John Snow <address@hidden>
Message-id: address@hidden
Signed-off-by: Max Reitz <address@hidden>
---
block/qcow2.h | 1 +
block/qcow2-refcount.c | 22 ++++++++++++++++++++++
block/qcow2.c | 23 +++++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git a/block/qcow2.h b/block/qcow2.h
index 5a289a81e2..782a206ecb 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -597,6 +597,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int
refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp);
int qcow2_shrink_reftable(BlockDriverState *bs);
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 88d5a3f1ad..aa3fd6cf17 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -3181,3 +3181,25 @@ out:
g_free(reftable_tmp);
return ret;
}
+
+int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
+{
+ BDRVQcow2State *s = bs->opaque;
+ int64_t i;
+
+ for (i = size_to_clusters(s, size) - 1; i >= 0; i--) {
+ uint64_t refcount;
+ int ret = qcow2_get_refcount(bs, i, &refcount);
+ if (ret < 0) {
+ fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
+ i, strerror(-ret));
+ return ret;
+ }
+ if (refcount > 0) {
+ return i;
+ }
+ }
+ qcow2_signal_corruption(bs, true, -1, -1,
+ "There are no references in the refcount table.");
+ return -EIO;
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index 960b3ab977..f63d1831f8 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3107,6 +3107,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t
offset,
new_l1_size = size_to_l1(s, offset);
if (offset < old_length) {
+ int64_t last_cluster, old_file_size;
if (prealloc != PREALLOC_MODE_OFF) {
error_setg(errp,
"Preallocation can't be used for shrinking an image");
@@ -3135,6 +3136,28 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t
offset,
"Failed to discard unused refblocks");
return ret;
}
+
+ old_file_size = bdrv_getlength(bs->file->bs);
+ if (old_file_size < 0) {
+ error_setg_errno(errp, -old_file_size,
+ "Failed to inquire current file length");
+ return old_file_size;
+ }
+ last_cluster = qcow2_get_last_cluster(bs, old_file_size);
+ if (last_cluster < 0) {
+ error_setg_errno(errp, -last_cluster,
+ "Failed to find the last cluster");
+ return last_cluster;
+ }
+ if ((last_cluster + 1) * s->cluster_size < old_file_size) {
+ ret = bdrv_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
+ PREALLOC_MODE_OFF, NULL);
+ if (ret < 0) {
+ warn_report("Failed to truncate the tail of the image: %s",
+ strerror(-ret));
+ ret = 0;
+ }
+ }
} else {
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
if (ret < 0) {
--
2.13.6
- [Qemu-block] [PULL 42/54] block: Perform copy-on-read in loop, (continued)
- [Qemu-block] [PULL 42/54] block: Perform copy-on-read in loop, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 36/54] qemu-iotests: Test commit block job where top has two parents, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 43/54] iotests: Add test 197 for covering copy-on-read, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 44/54] block: use 1 MB bounce buffers for crypto instead of 16KB, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 46/54] block: fix data type casting for crypto payload offset, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 45/54] crypto: expose encryption sector size in APIs, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 47/54] block: convert crypto driver to bdrv_co_preadv|pwritev, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 50/54] block/mirror: check backing in bdrv_mirror_top_refresh_filename, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 48/54] block: convert qcrypto_block_encrypt|decrypt to take bytes offset, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 49/54] block: support passthrough of BDRV_REQ_FUA in crypto driver, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 53/54] qcow2: truncate the tail of the image file after shrinking the image,
Kevin Wolf <=
- [Qemu-block] [PULL 54/54] block/mirror: check backing in bdrv_mirror_top_flush, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 51/54] iotests: Fix 195 if IMGFMT is part of TEST_DIR, Kevin Wolf, 2017/10/06
- [Qemu-block] [PULL 52/54] qcow2: fix return error code in qcow2_truncate(), Kevin Wolf, 2017/10/06
- Re: [Qemu-block] [Qemu-devel] [PULL 00/54] Block layer patches, Peter Maydell, 2017/10/06