File Remove-references-to-diskdump-private-data-from-flat.patch of Package libkdumpfile.36085

From: Petr Tesarik <petr@tesarici.cz>
Date: Thu, 26 Sep 2024 11:17:33 +0200
Subject: Remove references to diskdump private data from flatmap handling
References: bsc#1223399
Upstream: merged
Git-commit: b1f95a8e4cd596eafc5fc8d2553bb0f677d18103

Move all necessary data into struct flattened_map to remove all
dependencies on struct disk_dump_priv from the implementation. That way,
the functions can support flattened files in other formats than diskdump.

Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
 src/kdumpfile/diskdump.c |  137 +++++++++++++++++++++++++++++++----------------
 1 file changed, 92 insertions(+), 45 deletions(-)

--- a/src/kdumpfile/diskdump.c
+++ b/src/kdumpfile/diskdump.c
@@ -179,6 +179,15 @@ struct flattened_file_map {
 	off_t *offs;
 };
 
+/** Offset mappings for a set of flattened files. */
+struct flattened_map {
+	/** File cache. */
+	struct fcache *fcache;
+
+	/** Mappings for individual files. */
+	struct flattened_file_map fmap;
+};
+
 /** PFN region mapping. */
 struct pfn_rgn {
 	kdump_pfn_t pfn;	/**< Starting PFN. */
@@ -196,7 +205,7 @@ struct disk_dump_priv {
 	size_t pfn_rgn_num;	 /**< Number of elements in the map. */
 
 	/** File offset mappings for flattened files. */
-	struct flattened_file_map *flatmap;
+	struct flattened_map *flatmap;
 };
 
 struct setup_data {
@@ -220,7 +229,7 @@ struct setup_data {
 static void diskdump_cleanup(struct kdump_shared *shared);
 
 /** Read buffer from a flattened dump file.
- * @param ctx   Dump file object.
+ * @param map   Flattened format mapping to be initialized.
  * @param buf   Target I/O buffer.
  * @param len   Length of data.
  * @param pos   File position.
@@ -230,14 +239,14 @@ static void diskdump_cleanup(struct kdum
  * at position @p pos after rearrangement.
  */
 static kdump_status
-flattened_pread(kdump_ctx_t *ctx, void *buf, size_t len, off_t pos)
+flatmap_pread(struct flattened_map *map, void *buf, size_t len, off_t pos)
 {
-	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
+	struct flattened_file_map *fmap = &map->fmap;
 	const addrxlat_range_t *range, *end;
 	off_t off;
 
-	range = addrxlat_map_ranges(ddp->flatmap->map);
-	end = range + addrxlat_map_len(ddp->flatmap->map);
+	range = addrxlat_map_ranges(fmap->map);
+	end = range + addrxlat_map_len(fmap->map);
 	for (off = pos; range < end && off > range->endoff; ++range)
 		off -= range->endoff + 1;
 	while (range < end && len) {
@@ -248,11 +257,11 @@ flattened_pread(kdump_ctx_t *ctx, void *
 			seglen = len;
 
 		if (range->meth != ADDRXLAT_SYS_METH_NONE) {
-			off_t *flatoffs = ddp->flatmap->offs;
+			off_t *flatoffs = fmap->offs;
 			unsigned segidx = range->meth;
 			kdump_status ret;
 
-			ret = fcache_pread(ctx->shared->fcache, buf, seglen,
+			ret = fcache_pread(map->fcache, buf, seglen,
 					   pos + flatoffs[segidx]);
 			if (ret != KDUMP_OK)
 				return ret;
@@ -287,12 +296,12 @@ diskdump_pread(kdump_ctx_t *ctx, void *b
 	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
 
 	return ddp->flatmap
-		? flattened_pread(ctx, buf, len, pos)
+		? flatmap_pread(ddp->flatmap, buf, len, pos)
 		: fcache_pread(ctx->shared->fcache, buf, len, pos);
 }
 
 /** Get a contiguous data chunk from a flattened dump file.
- * @param ctx   Dump file object.
+ * @param map   Flattened format mapping to be initialized.
  * @param fch   File cache chunk, updated on success.
  * @param len   Length of data.
  * @param pos   File position.
@@ -301,27 +310,27 @@ diskdump_pread(kdump_ctx_t *ctx, void *b
  * Get a contiguous data chunk from a flattened dump file.
  */
 static inline kdump_status
-flattened_get_chunk(kdump_ctx_t *ctx, struct fcache_chunk *fch,
-		    size_t len, off_t pos)
+flatmap_get_chunk(struct flattened_map *map, struct fcache_chunk *fch,
+		  size_t len, off_t pos)
 {
-	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
+	struct flattened_file_map *fmap = &map->fmap;
 	const addrxlat_range_t *range, *end;
 	off_t off;
 
-	range = addrxlat_map_ranges(ddp->flatmap->map);
-	end = range + addrxlat_map_len(ddp->flatmap->map);
+	range = addrxlat_map_ranges(fmap->map);
+	end = range + addrxlat_map_len(fmap->map);
 	for (off = pos; range < end && off > range->endoff; ++range)
 		off -= range->endoff + 1;
 	if (len <= range->endoff + 1 - off) {
-		pos += ddp->flatmap->offs[range->meth];
-		return fcache_get_chunk(ctx->shared->fcache, fch, len, pos);
+		pos += fmap->offs[range->meth];
+		return fcache_get_chunk(map->fcache, fch, len, pos);
 	}
 
 	fch->data = malloc(len);
 	if (!fch->data)
 		return KDUMP_ERR_SYSTEM;
 	fch->nent = 0;
-	return flattened_pread(ctx, fch->data, len, pos);
+	return flatmap_pread(map, fch->data, len, pos);
 }
 
 /** Get a contiguous data chunk from a diskdump file.
@@ -341,7 +350,7 @@ diskdump_get_chunk(kdump_ctx_t *ctx, str
 	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
 
 	return ddp->flatmap
-		? flattened_get_chunk(ctx, fch, len, pos)
+		? flatmap_get_chunk(ddp->flatmap, fch, len, pos)
 		: fcache_get_chunk(ctx->shared->fcache, fch, len, pos);
 }
 
@@ -1066,16 +1075,22 @@ open_common(kdump_ctx_t *ctx, void *hdr)
 #define FLATOFFS_ALLOC_INC	32
 
 /** Initialize flattened dump maps for one file.
+ * @param fmap  Flattened format mapping to be initialized.
  * @param ctx   Dump file object.
  * @returns     Error status.
  *
  * Read all flattened segment headers and initialize
- * @p flatmap and @p flatoffs.
+ * @p fmap.
+ *
+ * Note that the mapping may be already partially initialized when this
+ * function fails with an error status, so you should always release the
+ * associated resources with @ref flatmap_file_cleanup(). As a consequence,
+ * the mapping must be initialized to all zeroes prior to calling
+ * flatmap_file_init().
  */
 static kdump_status
-init_flattened_file(kdump_ctx_t *ctx)
+flatmap_file_init(struct flattened_file_map *fmap, kdump_ctx_t *ctx)
 {
-	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
 	struct makedumpfile_data_header hdr;
 	addrxlat_range_t range;
 	int64_t pos, size;
@@ -1083,8 +1098,8 @@ init_flattened_file(kdump_ctx_t *ctx)
 	off_t flatpos;
 	kdump_status status;
 
-	ddp->flatmap->map = addrxlat_map_new();
-	if (!ddp->flatmap->map)
+	fmap->map = addrxlat_map_new();
+	if (!fmap->map)
 		return set_error(ctx, KDUMP_ERR_SYSTEM,
 				 "Cannot allocate %s", "flattened map");
 
@@ -1116,20 +1131,20 @@ init_flattened_file(kdump_ctx_t *ctx)
 			unsigned newlen = segidx + FLATOFFS_ALLOC_INC;
 			off_t *newbuf;
 
-			newbuf = realloc(ddp->flatmap->offs,
-					 sizeof(*ddp->flatmap->offs) * newlen);
+			newbuf = realloc(fmap->offs,
+					 sizeof(*fmap->offs) * newlen);
 			if (!newbuf)
 				return set_error(ctx, KDUMP_ERR_SYSTEM,
 						 "Cannot allocate %s",
 						 "flattened offset array");
-			ddp->flatmap->offs = newbuf;
+			fmap->offs = newbuf;
 		}
 		flatpos += sizeof(hdr);
-		ddp->flatmap->offs[segidx] = flatpos - pos;
+		fmap->offs[segidx] = flatpos - pos;
 
 		range.endoff = size - 1;
 		range.meth = segidx;
-		if (addrxlat_map_set(ddp->flatmap->map, pos, &range) != ADDRXLAT_OK)
+		if (addrxlat_map_set(fmap->map, pos, &range) != ADDRXLAT_OK)
 			return set_error(ctx, KDUMP_ERR_SYSTEM,
 					 "Cannot allocate %s",
 					 "flattened map entry");
@@ -1140,24 +1155,43 @@ init_flattened_file(kdump_ctx_t *ctx)
 	return KDUMP_OK;
 }
 
+static void
+flatmap_file_cleanup(struct flattened_file_map *fmap)
+{
+	if (fmap->map)
+		addrxlat_map_decref(fmap->map);
+	if (fmap->offs)
+		free(fmap->offs);
+}
+
+/** Allocate a flattened dump map.
+ * @returns       Flattened offset map, or @c NULL on error.
+ */
+static struct flattened_map*
+flatmap_alloc(void)
+{
+	struct flattened_map *map;
+
+	map = calloc(1, sizeof(*map));
+	return map;
+}
+
 /** Initialize flattened dump maps for all files.
+ * @param map  Flattened offset map.
  * @param ctx  Dump file object.
  * @returns    Error status.
  *
  * Initialize flattened dump maps for all files.
  */
 static kdump_status
-init_flattened_maps(kdump_ctx_t *ctx)
+flatmap_init(struct flattened_map *map, kdump_ctx_t *ctx)
 {
-	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
 	kdump_status status;
 
-	ddp->flatmap = calloc(1, sizeof(*ddp->flatmap));
-	if (!ddp->flatmap)
-		return set_error(ctx, KDUMP_ERR_SYSTEM,
-				 "Cannot allocate %s", "flatmap array");
+	map->fcache = ctx->shared->fcache;
+	fcache_incref(map->fcache);
 
-	status = init_flattened_file(ctx);
+	status = flatmap_file_init(&map->fmap, ctx);
 	if (status != KDUMP_OK)
 		return set_error(ctx, status,
 				 "Cannot rearrange file");
@@ -1165,6 +1199,17 @@ init_flattened_maps(kdump_ctx_t *ctx)
 	return KDUMP_OK;
 }
 
+static void
+flatmap_free(struct flattened_map *map)
+{
+	if (!map)
+		return;
+	flatmap_file_cleanup(&map->fmap);
+	if (map->fcache)
+		fcache_decref(map->fcache);
+	free(map);
+}
+
 static kdump_status
 diskdump_probe(kdump_ctx_t *ctx)
 {
@@ -1185,6 +1230,7 @@ diskdump_probe(kdump_ctx_t *ctx)
 	if (!memcmp(hdr, magic_flattened, sizeof magic_flattened)) {
 		struct makedumpfile_header *flathdr =
 			(struct makedumpfile_header*) hdr;
+		struct disk_dump_priv *ddp;
 
 		if (be64toh(flathdr->type) != MDF_TYPE_FLAT_HEADER)
 			return set_error(ctx, KDUMP_ERR_NOTIMPL,
@@ -1199,11 +1245,18 @@ diskdump_probe(kdump_ctx_t *ctx)
 		if (status != KDUMP_OK)
 			return status;
 
-		status = init_flattened_maps(ctx);
+		ddp = ctx->shared->fmtdata;
+		ddp->flatmap = flatmap_alloc();
+		if (!ddp->flatmap)
+			return set_error(ctx, KDUMP_ERR_SYSTEM,
+					 "Cannot allocate %s",
+					 "flattened dump maps");
+
+		status = flatmap_init(ddp->flatmap, ctx);
 		if (status != KDUMP_OK)
 			return status;
 
-		status = flattened_pread(ctx, &hdr, sizeof hdr, 0);
+		status = flatmap_pread(ddp->flatmap, &hdr, sizeof hdr, 0);
 		if (status != KDUMP_OK)
 			return set_error(ctx, status, "Cannot read dump header");
 		strcpy(desc, "Flattened ");
@@ -1244,13 +1297,7 @@ diskdump_cleanup(struct kdump_shared *sh
 	if (ddp) {
 		if (ddp->pfn_rgn)
 			free(ddp->pfn_rgn);
-		if (ddp->flatmap) {
-			if (ddp->flatmap->map)
-				addrxlat_map_decref(ddp->flatmap->map);
-			if (ddp->flatmap->offs)
-				free(ddp->flatmap->offs);
-			free(ddp->flatmap);
-		}
+		flatmap_free(ddp->flatmap);
 		free(ddp);
 		shared->fmtdata = NULL;
 	}
openSUSE Build Service is sponsored by