File diskdump-Map-compressed-data-directly-from-file-cach.patch of Package libkdumpfile.36085

From: Petr Tesarik <petr@tesarici.cz>
Date: Mon, 6 Nov 2023 20:12:09 +0100
Subject: diskdump: Map compressed data directly from file cache
References: bsc#1223399
Upstream: merged
Git-commit: e403ac1d95132282c6b9763cf4ad7cd5fc8414ec

Do not copy around compressed page data. Most of the time, this data is
contiguous in the file cache, so it can be simply mapped and decompressed.

Remove the (now unused) per-context buffer for compressed data.

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

--- a/src/kdumpfile/diskdump.c
+++ b/src/kdumpfile/diskdump.c
@@ -188,7 +188,6 @@ struct disk_dump_priv {
 
 	/** Overridden methods for arch.page_size attribute. */
 	struct attr_override page_size_override;
-	int cbuf_slot;		/**< Compressed data per-context slot. */
 
 	/** File offset mapping for flattened files. */
 	addrxlat_map_t *flatmap;
@@ -504,9 +503,9 @@ diskdump_read_page(kdump_ctx_t *ctx, str
 {
 	struct disk_dump_priv *ddp = ctx->shared->fmtdata;
 	kdump_pfn_t pfn;
+	struct fcache_chunk fch;
 	struct page_desc pd;
 	off_t pd_pos;
-	void *buf;
 	kdump_status ret;
 
 	pfn = pio->addr.addr >> get_page_shift(ctx);
@@ -535,40 +534,44 @@ diskdump_read_page(kdump_ctx_t *ctx, str
 	pd.flags = dump32toh(ctx, pd.flags);
 	pd.page_flags = dump64toh(ctx, pd.page_flags);
 
+	/* read page data */
 	if (pd.flags & DUMP_DH_COMPRESSED) {
 		if (pd.size > MAX_PAGE_SIZE)
 			return set_error(ctx, KDUMP_ERR_CORRUPT,
 					 "Wrong compressed size: %lu",
 					 (unsigned long)pd.size);
-		buf = ctx->data[ddp->cbuf_slot];
+		mutex_lock(&ctx->shared->cache_lock);
+		ret = diskdump_get_chunk(ctx, &fch, pd.size, pd.offset);
+		mutex_unlock(&ctx->shared->cache_lock);
 	} else {
 		if (pd.size != get_page_size(ctx))
 			return set_error(ctx, KDUMP_ERR_CORRUPT,
 					 "Wrong page size: %lu",
 					 (unsigned long)pd.size);
-		buf = pio->chunk.data;
+		mutex_lock(&ctx->shared->cache_lock);
+		ret = diskdump_pread(ctx, pio->chunk.data, pd.size, pd.offset);
+		mutex_unlock(&ctx->shared->cache_lock);
 	}
 
-	/* read page data */
-	mutex_lock(&ctx->shared->cache_lock);
-	ret = diskdump_pread(ctx, buf, pd.size, pd.offset);
-	mutex_unlock(&ctx->shared->cache_lock);
 	if (ret != KDUMP_OK)
 		return set_error(ctx, ret,
 				 "Cannot read page data at %llu",
 				 (unsigned long long) pd.offset);
 
 	if (pd.flags & DUMP_DH_COMPRESSED_ZLIB) {
-		ret = uncompress_page_gzip(ctx, pio->chunk.data, buf, pd.size);
+		ret = uncompress_page_gzip(ctx, pio->chunk.data,
+					   fch.data, pd.size);
+		fcache_put_chunk(&fch);
 		if (ret != KDUMP_OK)
 			return ret;
 	} else if (pd.flags & DUMP_DH_COMPRESSED_LZO) {
 #if USE_LZO
 		lzo_uint retlen = get_page_size(ctx);
-		int ret = lzo1x_decompress_safe((lzo_bytep)buf, pd.size,
-						(lzo_bytep)pio->chunk.data,
+		int ret = lzo1x_decompress_safe(fch.data, pd.size,
+						pio->chunk.data,
 						&retlen,
 						LZO1X_MEM_DECOMPRESS);
+		fcache_put_chunk(&fch);
 		if (ret != LZO_E_OK)
 			return set_error(ctx, KDUMP_ERR_CORRUPT,
 					 "Decompression failed: %d", ret);
@@ -585,8 +588,9 @@ diskdump_read_page(kdump_ctx_t *ctx, str
 #if USE_SNAPPY
 		size_t retlen = get_page_size(ctx);
 		snappy_status ret;
-		ret = snappy_uncompress((char *)buf, pd.size,
-					(char *)pio->chunk.data, &retlen);
+		ret = snappy_uncompress(fch.data, pd.size,
+					pio->chunk.data, &retlen);
+		fcache_put_chunk(&fch);
 		if (ret != SNAPPY_OK)
 			return set_error(ctx, KDUMP_ERR_CORRUPT,
 					 "Decompression failed: %d",
@@ -625,17 +629,8 @@ diskdump_realloc_compressed(kdump_ctx_t
 {
 	const struct attr_ops *parent_ops;
 	struct disk_dump_priv *ddp;
-	int newslot;
-
-	newslot = per_ctx_alloc(ctx->shared, attr_value(attr)->number);
-	if (newslot < 0)
-		return set_error(ctx, KDUMP_ERR_SYSTEM,
-				 "Cannot allocate buffer for compressed data");
 
 	ddp = ctx->shared->fmtdata;
-	if (ddp->cbuf_slot >= 0)
-		per_ctx_free(ctx->shared, ddp->cbuf_slot);
-	ddp->cbuf_slot = newslot;
 
 	parent_ops = ddp->page_size_override.template.parent->ops;
 	return (parent_ops && parent_ops->post_set)
@@ -1019,7 +1014,6 @@ init_private(kdump_ctx_t *ctx)
 	attr_add_override(gattr(ctx, GKI_page_size),
 			  &ddp->page_size_override);
 	ddp->page_size_override.ops.post_set = diskdump_realloc_compressed;
-	ddp->cbuf_slot = -1;
 
 	ctx->shared->fmtdata = ddp;
 	return KDUMP_OK;
@@ -1258,8 +1252,6 @@ diskdump_cleanup(struct kdump_shared *sh
 	if (ddp) {
 		if (ddp->pfn_rgn)
 			free(ddp->pfn_rgn);
-		if (ddp->cbuf_slot >= 0)
-			per_ctx_free(shared, ddp->cbuf_slot);
 		if (ddp->flatmap)
 			addrxlat_map_decref(ddp->flatmap);
 		if (ddp->flatoffs)
openSUSE Build Service is sponsored by