From: Matthias Gatto <matthias.gatto@xxxxxxxxxxxx> Convert the storage source backingStore pointer into an array of virStorageSourcePtr. This patch will rename src->backingStore to src->backingStores, add an nbackingStores, and adjust the code Get and Set functions to handle the the array. virStorageSourceSetBackingStore can expand the size of src->backingStores. Signed-off-by: Matthias Gatto <matthias.gatto@xxxxxxxxxxxx> Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/util/virstoragefile.c | 61 ++++++++++++++++++++++++++++++----------------- src/util/virstoragefile.h | 3 ++- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 1d96d7a..b917eb6 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1813,11 +1813,10 @@ virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src) /** * virStorageSourceGetBackingStore: * @src: virStorageSourcePtr containing the backing stores - * @pos: presently unused + * @pos: position of the backing store to get * - * Return the @src backingStore pointer at @pos. For now, @pos is - * expected to be 0. A future patch will use @pos index into an array - * of storage backingStore pointers + * Return the @src backingStore pointer at @pos in the array of + * storage backingStores pointers * * Returns: * A pointer to the storage source backingStore @pos or @@ -1827,9 +1826,9 @@ virStorageSourcePtr virStorageSourceGetBackingStore(const virStorageSource *src, size_t pos) { - if (!src || pos > 0) + if (!src || !src->backingStores || pos >= src->nBackingStores) return NULL; - return src->backingStore; + return src->backingStores[pos]; } @@ -1837,11 +1836,12 @@ virStorageSourceGetBackingStore(const virStorageSource *src, * virStorageSourceSetBackingStore: * @src: virStorageSourcePtr to hold @backingStore * @backingStore - Pointer to the backingStore to store - * @pos - presently unused + * @pos: position of the backing store to store * - * Set @backingStore in @src at @pos in src->backingStore. For now, pos - * is expected to be 0. A future patch will use pos as the position in - * the array of storage backingStore pointers + * Set @backingStore in @src at @pos in src->backingStores. If the + * backingStores array does not have the space to contain @backingStore, + * expand src->backingStores. If the entry at @pos already exists, then + * free it first before replacing with the new @backingStore. * * Returns: * 0 on success, -1 on failure @@ -1851,10 +1851,18 @@ virStorageSourceSetBackingStore(virStorageSourcePtr src, virStorageSourcePtr backingStore, size_t pos) { - if (pos > 0) + if (!src) return -1; - src->backingStore = backingStore; + if (pos >= src->nBackingStores) { + int nbr = pos - src->nBackingStores + 1; + if (VIR_EXPAND_N(src->backingStores, src->nBackingStores, nbr) < 0) + return -1; + } + + if (src->backingStores[pos]) + virStorageSourceFree(src->backingStores[pos]); + src->backingStores[pos] = backingStore; return 0; } @@ -1873,6 +1881,7 @@ virStorageSourceCopy(const virStorageSource *src, bool backingChain) { virStorageSourcePtr ret = NULL; + size_t i; if (VIR_ALLOC(ret) < 0) return NULL; @@ -1885,6 +1894,7 @@ virStorageSourceCopy(const virStorageSource *src, ret->physical = src->physical; ret->readonly = src->readonly; ret->shared = src->shared; + ret->nBackingStores = src->nBackingStores; /* storage driver metadata are not copied */ ret->drv = NULL; @@ -1933,15 +1943,17 @@ virStorageSourceCopy(const virStorageSource *src, !(ret->auth = virStorageAuthDefCopy(src->auth))) goto error; - if (backingChain) { - virStorageSourcePtr backingStore = - virStorageSourceGetBackingStore(src, 0); - virStorageSourcePtr backingStoreCopy = - virStorageSourceCopy(backingStore, true); + for (i = 0; i < src->nBackingStores; i++) { + if (backingChain) { + virStorageSourcePtr backingStore = + virStorageSourceGetBackingStore(src, i); + virStorageSourcePtr backingStoreCopy = + virStorageSourceCopy(backingStore, true); - if (!backingStoreCopy || - virStorageSourceSetBackingStore(ret, backingStoreCopy, 0) < 0) - goto error; + if (!backingStoreCopy || + virStorageSourceSetBackingStore(ret, backingStoreCopy, i) < 0) + goto error; + } } return ret; @@ -2073,6 +2085,8 @@ virStorageSourceIsEmpty(virStorageSourcePtr src) void virStorageSourceBackingStoreClear(virStorageSourcePtr def) { + size_t i; + if (!def) return; @@ -2080,8 +2094,11 @@ virStorageSourceBackingStoreClear(virStorageSourcePtr def) VIR_FREE(def->backingStoreRaw); /* recursively free backing chain */ - virStorageSourceFree(virStorageSourceGetBackingStore(def, 0)); - ignore_value(virStorageSourceSetBackingStore(def, NULL, 0)); + for (i = 0; i < def->nBackingStores; i++) + virStorageSourceFree(virStorageSourceGetBackingStore(def, i)); + if (def->nBackingStores > 0) + VIR_FREE(def->backingStores); + def->nBackingStores = 0; } diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index ce1cb5d..290c20f 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -270,7 +270,8 @@ struct _virStorageSource { bool shared; /* backing chain of the storage source */ - virStorageSourcePtr backingStore; + virStorageSourcePtr *backingStores; + size_t nBackingStores; /* metadata for storage driver access to remote and local volumes */ virStorageDriverDataPtr drv; -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list