With PREALLOC_MODE_OFF, we currently always resize the data file to the
right length.  This is definitely not necessary if it already has the
correct length, and if @exact is false, we also don't need to shrink it.

This is what other preallocation modes already do: preallocate_co() only
increases the data file size if it is too small, but never shrinks it.
(And note that for raw data files, PREALLOC_MODE_OFF is silently turned
into PREALLOC_MODE_METADATA, so this commit only changes behavior for
non-raw external data files.)

For the next commits, having all preallocation modes behave the same
will make it easier to decide when we can skip taking the RESIZE
permission on the data-file child.

Signed-off-by: Hanna Czenczek <[email protected]>
---
 block/qcow2.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index e29810d86a..69d621e9bf 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -4515,15 +4515,22 @@ qcow2_co_truncate(BlockDriverState *bs, int64_t offset, 
bool exact,
     switch (prealloc) {
     case PREALLOC_MODE_OFF:
         if (has_data_file(bs)) {
+            int64_t data_file_length = bdrv_co_getlength(s->data_file->bs);
+
             /*
              * If the caller wants an exact resize, the external data
              * file should be resized to the exact target size, too,
              * so we pass @exact here.
+             * Without @exact, we leave it as-is if it is already big enough.
+             * Implicitly handle bdrv_co_getlength() errors by resizing.
              */
-            ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
-                                   errp);
-            if (ret < 0) {
-                goto fail;
+            if (data_file_length < offset ||
+                (exact && data_file_length != offset)) {
+                ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 
0,
+                                       errp);
+                if (ret < 0) {
+                    goto fail;
+                }
             }
         }
         break;
-- 
2.52.0


Reply via email to