From: Peter Krempa <[email protected]>

Extract the logic to probe the image format header to a separate caller
which will not touch the virStorageSource.

Note that this does no longer update 'encryption->payload_offset' of the
source when called from 'virStorageSourceUpdateCapacity', but that value
is not actually used elsewhere.

Signed-off-by: Peter Krempa <[email protected]>
---
 src/libvirt_private.syms          |  1 +
 src/storage_file/storage_source.c | 52 ++++++++++++++++++++++++-------
 src/storage_file/storage_source.h |  7 +++++
 3 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a7ce33b428..8d5b4fb875 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1933,6 +1933,7 @@ virStorageSourceInitAs;
 virStorageSourceNewFromBacking;
 virStorageSourceNewFromBackingAbsolute;
 virStorageSourceParseRBDColonString;
+virStorageSourceProbeCapacityFromBuf;
 virStorageSourceRead;
 virStorageSourceReportBrokenChain;
 virStorageSourceStat;
diff --git a/src/storage_file/storage_source.c 
b/src/storage_file/storage_source.c
index 651822eb65..1108865b03 100644
--- a/src/storage_file/storage_source.c
+++ b/src/storage_file/storage_source.c
@@ -731,7 +731,6 @@ virStorageSourceUpdateCapacity(virStorageSource *src,
                                ssize_t len)
 {
     int format = src->format;
-    g_autoptr(virStorageSource) meta = NULL;

     /* Raw files: capacity is physical size.  For all other files: if
      * the metadata has a capacity, use that, otherwise fall back to
@@ -743,19 +742,48 @@ virStorageSourceUpdateCapacity(virStorageSource *src,
         return -1;
     }

-    if (format == VIR_STORAGE_FILE_RAW && !src->encryption) {
-        src->capacity = src->physical;
-    } else if ((meta = virStorageSourceGetMetadataFromBuf(src->path, buf,
-                                                          len, format))) {
-        src->capacity = meta->capacity ? meta->capacity : src->physical;
-        if (src->encryption && meta->encryption)
-            src->encryption->payload_offset = meta->encryption->payload_offset;
-    } else {
+    src->capacity = src->physical;
+
+    if (src->format == VIR_STORAGE_FILE_RAW && !src->encryption)
+        return 0;
+
+    if (virStorageSourceProbeCapacityFromBuf(format, buf, len, &src->capacity))
         return -1;
-    }

-    if (src->encryption && src->encryption->payload_offset != -1)
-        src->capacity -= src->encryption->payload_offset * 512;
+    return 0;
+}
+
+
+/**
+ * virStorageSourceProbeCapacityFromBuf:
+ * @format: format of the image to probe
+ * @buf: buffer containing the header of the image
+ * @buflen: length of @buf
+ * @capacity: filled with the probed capacity; caller must pre-fill it with
+ *            physical size of the image in case when the image header doesn't
+ *            contain lenght
+ *
+ * Probes the image header in @buf for capacity recorded in the header and 
fills
+ * it into @capacity. Calers must pre-fill @capacity with the physical size
+ * of the backing storage as some formats don't contain capacity information
+ * in the header. It doesn't make sense to call this for 'raw' files.
+ */
+int
+virStorageSourceProbeCapacityFromBuf(virStorageFileFormat format,
+                                     char *buf,
+                                     ssize_t buflen,
+                                     unsigned long long *capacity)
+{
+    g_autoptr(virStorageSource) meta = virStorageSourceMetadataNew(NULL, 
format);
+
+    if (virStorageFileProbeGetMetadata(meta, buf, buflen) < 0)
+        return -1;
+
+    if (meta->capacity > 0)
+        *capacity = meta->capacity;
+
+    if (meta->encryption && meta->encryption->payload_offset != -1)
+        *capacity -= meta->encryption->payload_offset * 512;

     return 0;
 }
diff --git a/src/storage_file/storage_source.h 
b/src/storage_file/storage_source.h
index 774dcbffee..c8cd244ca1 100644
--- a/src/storage_file/storage_source.h
+++ b/src/storage_file/storage_source.h
@@ -71,6 +71,13 @@ virStorageSourceUpdateCapacity(virStorageSource *src,
                                char *buf,
                                ssize_t len);

+int
+virStorageSourceProbeCapacityFromBuf(virStorageFileFormat format,
+                                     char *buf,
+                                     ssize_t buflen,
+                                     unsigned long long *capacity)
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
+
 int
 virStorageSourceNewFromBacking(virStorageSource *parent,
                                virStorageSource **backing);
-- 
2.54.0

Reply via email to