git: 84a3e29c7203 - main - mkimg: Add image_buffer_region

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Sat, 03 Oct 2026 15:42:41 UTC
The branch main has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=84a3e29c72030dab16b4dc82d601d0af5da6a18c

commit 84a3e29c72030dab16b4dc82d601d0af5da6a18c
Author:     ChrisKom04 <komis.christo@gmail.com>
AuthorDate: 2025-07-13 15:46:46 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2026-10-03 15:41:28 +0000

    mkimg: Add image_buffer_region
    
    This is like image_copyout_region, but copies into a buffer rather than
    writing out to a file; it will be used by future support for compressed
    images (and potentially other circumstances where image data must be
    manipulated before being written out to disk).
    
    Reviewed by:    jrm
    No objection from:      Christos Komis (author)
    MFC after:      2 weeks
    Sponsored by:   Google LLC (GSoC 2025)
    Differential Revision:  https://reviews.freebsd.org/D60149
---
 usr.bin/mkimg/image.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 usr.bin/mkimg/image.h |  1 +
 2 files changed, 69 insertions(+)

diff --git a/usr.bin/mkimg/image.c b/usr.bin/mkimg/image.c
index 84d66af97a60..1c8b1c6c1826 100644
--- a/usr.bin/mkimg/image.c
+++ b/usr.bin/mkimg/image.c
@@ -600,6 +600,32 @@ image_copyout_file(int fd, size_t size, int ifd, off_t iofs)
 	return (0);
 }
 
+static int
+image_buffer_file(char *buffer, size_t size, int ifd, off_t iofs)
+{
+	void *mp;
+	char *buf, *p;
+	size_t iosz, sz;
+	off_t iof;
+
+	iosz = secsz * image_swap_pgsz;
+	p = buffer;
+
+	while (size > 0) {
+		sz = (size > iosz) ? iosz : size;
+		buf = mp = image_file_map(ifd, iofs, sz, &iof);
+		if (buf == NULL)
+			return (errno);
+		buf += iof;
+		memcpy(p, buf, sz);
+		image_file_unmap(mp, sz, iof);
+		size -= sz;
+		iofs += sz;
+		p += sz;
+	}
+	return (0);
+}
+
 int
 image_copyout_region(int fd, lba_t blk, lba_t size)
 {
@@ -639,6 +665,48 @@ image_copyout_region(int fd, lba_t blk, lba_t size)
 	return (error);
 }
 
+int
+image_buffer_region(char *buf, lba_t blk, lba_t size)
+{
+	char *p;
+	struct chunk *ch;
+	size_t ofs, sz;
+	int error;
+
+	size *= secsz;
+
+	p = buf;
+	error = 0;
+	while (!error && size > 0) {
+		ch = image_chunk_find(blk);
+		if (ch == NULL) {
+			error = EINVAL;
+			break;
+		}
+		ofs = (blk - ch->ch_block) * secsz;
+		sz = ch->ch_size - ofs;
+		sz = ((lba_t)sz < size) ? sz : (size_t)size;
+		switch (ch->ch_type) {
+		case CH_TYPE_ZEROES:
+			memset(p, 0, sz);
+			break;
+		case CH_TYPE_FILE:
+			error = image_buffer_file(p, sz, ch->ch_u.file.fd,
+			    ch->ch_u.file.ofs + ofs);
+			break;
+		case CH_TYPE_MEMORY:
+			memcpy(p, ch->ch_u.mem.ptr, sz);
+			break;
+		default:
+			assert(0);
+		}
+		size -= sz;
+		blk += sz / secsz;
+		p += sz;
+	}
+	return (error);
+}
+
 int
 image_data(lba_t blk, lba_t size)
 {
diff --git a/usr.bin/mkimg/image.h b/usr.bin/mkimg/image.h
index 956fe3f27556..13bbc5109673 100644
--- a/usr.bin/mkimg/image.h
+++ b/usr.bin/mkimg/image.h
@@ -37,6 +37,7 @@ int image_copyin(lba_t blk, int fd, uint64_t *sizep);
 int image_copyout(int fd);
 int image_copyout_done(int fd);
 int image_copyout_region(int fd, lba_t blk, lba_t size);
+int image_buffer_region(char *buffer, lba_t blk, lba_t size);
 int image_copyout_zeroes(int fd, size_t count);
 int image_data(lba_t blk, lba_t size);
 lba_t image_get_size(void);