All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking
@ 2017-09-29 12:16 Pavel Butsykin
  2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 1/2] qcow2: fix return error code in qcow2_truncate() Pavel Butsykin
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pavel Butsykin @ 2017-09-29 12:16 UTC (permalink / raw)
  To: qemu-block, qemu-devel; +Cc: pbutsykin, kwolf, mreitz, eblake, jsnow, den

Now after shrinking the qcow2 image, at the end of the image file, there might
be a tail that probably will never be used. Although it will not bring any
tangible benefit, we can cut the tail if it is. Yes, it will not free up disk
space, but if the blocks were be allocated sequentially and the image is not
heavily fragmented then the virtual size of the image file will be commensurate
with the real size. It also doesn't look like a great plus.. Well, at least we
can discuss it.

Changes from v1:
- rewrite qcow2_get_last_cluster() function according to Max's comments. (2)

Changes from v2:
- report a warning if truncation of the tail of the image file failed. (2)

Pavel Butsykin (2):
  qcow2: fix return error code in qcow2_truncate()
  qcow2: truncate the tail of the image file after shrinking the image

 block/qcow2-refcount.c | 22 ++++++++++++++++++++++
 block/qcow2.c          | 27 +++++++++++++++++++++++++--
 block/qcow2.h          |  1 +
 3 files changed, 48 insertions(+), 2 deletions(-)

-- 
2.14.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH v4 1/2] qcow2: fix return error code in qcow2_truncate()
  2017-09-29 12:16 [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Pavel Butsykin
@ 2017-09-29 12:16 ` Pavel Butsykin
  2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 2/2] qcow2: truncate the tail of the image file after shrinking the image Pavel Butsykin
  2017-09-29 13:00 ` [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Max Reitz
  2 siblings, 0 replies; 4+ messages in thread
From: Pavel Butsykin @ 2017-09-29 12:16 UTC (permalink / raw)
  To: qemu-block, qemu-devel; +Cc: pbutsykin, kwolf, mreitz, eblake, jsnow, den

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 block/qcow2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 2174a84d1f..8a4311d338 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3166,7 +3166,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
         if (old_file_size < 0) {
             error_setg_errno(errp, -old_file_size,
                              "Failed to inquire current file length");
-            return ret;
+            return old_file_size;
         }
 
         nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
@@ -3195,7 +3195,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
         if (allocation_start < 0) {
             error_setg_errno(errp, -allocation_start,
                              "Failed to resize refcount structures");
-            return -allocation_start;
+            return allocation_start;
         }
 
         clusters_allocated = qcow2_alloc_clusters_at(bs, allocation_start,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH v4 2/2] qcow2: truncate the tail of the image file after shrinking the image
  2017-09-29 12:16 [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Pavel Butsykin
  2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 1/2] qcow2: fix return error code in qcow2_truncate() Pavel Butsykin
@ 2017-09-29 12:16 ` Pavel Butsykin
  2017-09-29 13:00 ` [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Max Reitz
  2 siblings, 0 replies; 4+ messages in thread
From: Pavel Butsykin @ 2017-09-29 12:16 UTC (permalink / raw)
  To: qemu-block, qemu-devel; +Cc: pbutsykin, kwolf, mreitz, eblake, jsnow, den

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 <pbutsykin@virtuozzo.com>
Reviewed-by: John Snow <jsnow@redhat.com>
---
 block/qcow2-refcount.c | 22 ++++++++++++++++++++++
 block/qcow2.c          | 23 +++++++++++++++++++++++
 block/qcow2.h          |  1 +
 3 files changed, 46 insertions(+)

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 8a4311d338..d9e0a132f9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3106,6 +3106,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");
@@ -3134,6 +3135,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) {
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,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking
  2017-09-29 12:16 [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Pavel Butsykin
  2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 1/2] qcow2: fix return error code in qcow2_truncate() Pavel Butsykin
  2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 2/2] qcow2: truncate the tail of the image file after shrinking the image Pavel Butsykin
@ 2017-09-29 13:00 ` Max Reitz
  2 siblings, 0 replies; 4+ messages in thread
From: Max Reitz @ 2017-09-29 13:00 UTC (permalink / raw)
  To: Pavel Butsykin, qemu-block, qemu-devel; +Cc: kwolf, eblake, jsnow, den

[-- Attachment #1: Type: text/plain, Size: 1214 bytes --]

On 2017-09-29 14:16, Pavel Butsykin wrote:
> Now after shrinking the qcow2 image, at the end of the image file, there might
> be a tail that probably will never be used. Although it will not bring any
> tangible benefit, we can cut the tail if it is. Yes, it will not free up disk
> space, but if the blocks were be allocated sequentially and the image is not
> heavily fragmented then the virtual size of the image file will be commensurate
> with the real size. It also doesn't look like a great plus.. Well, at least we
> can discuss it.
> 
> Changes from v1:
> - rewrite qcow2_get_last_cluster() function according to Max's comments. (2)
> 
> Changes from v2:
> - report a warning if truncation of the tail of the image file failed. (2)
> 
> Pavel Butsykin (2):
>   qcow2: fix return error code in qcow2_truncate()
>   qcow2: truncate the tail of the image file after shrinking the image
> 
>  block/qcow2-refcount.c | 22 ++++++++++++++++++++++
>  block/qcow2.c          | 27 +++++++++++++++++++++++++--
>  block/qcow2.h          |  1 +
>  3 files changed, 48 insertions(+), 2 deletions(-)

Thanks, applied to my block branch:

https://github.com/XanClic/qemu/commits/block

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-09-29 13:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-29 12:16 [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Pavel Butsykin
2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 1/2] qcow2: fix return error code in qcow2_truncate() Pavel Butsykin
2017-09-29 12:16 ` [Qemu-devel] [PATCH v4 2/2] qcow2: truncate the tail of the image file after shrinking the image Pavel Butsykin
2017-09-29 13:00 ` [Qemu-devel] [PATCH v4 0/2] Truncate the tail of the image file in qcow2 shrinking Max Reitz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.