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
