Skip to content

Commit

Permalink
image-android-sparse: add option to fill holes with zeros
Browse files Browse the repository at this point in the history
By default 'holes' are converted into "don't care" areas. This adds an
option to fill the area with zeros instead.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
  • Loading branch information
michaelolbrich committed Jan 21, 2025
1 parent b0395bb commit d795d93
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 5 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ EXTRA_DIST += \
test/rauc.config \
test/sharness.sh \
test/sparse.config \
test/sparse-fill.config \
test/squashfs.config \
test/tar.config \
test/test.raucb.info.1 \
Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ Options:
:block-size: The granularity that the sparse image uses to
find "don't care" or "fill" blocks. The supported
block sizes depend on the user. The default is 4k.
:fill-holes: If enabled, 'holes' are filled with zero instead of
"don't care". Disabled by default.

cpio
****
Expand Down
2 changes: 2 additions & 0 deletions genimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ struct extent {
};

int open_file(struct image *image, const char *filename, int extra_flags);
int whole_file_exent(size_t size, struct extent **extents,
size_t *extent_count);
int map_file_extents(struct image *image, const char *filename, int fd,
size_t size, struct extent **extents, size_t *extent_count);
int is_block_device(const char *filename);
Expand Down
13 changes: 10 additions & 3 deletions image-android-sparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

struct sparse {
uint32_t block_size;
cfg_bool_t fill_holes;
};

struct sparse_header {
Expand Down Expand Up @@ -147,9 +148,13 @@ static int android_sparse_generate(struct image *image)
block_count = (s.st_size - 1 + sparse->block_size) / sparse->block_size;
header.output_blocks = block_count;

ret = map_file_extents(inimage, infile, in_fd, s.st_size, &extents, &extent_count);
if (ret < 0)
goto out;
if (sparse->fill_holes)
whole_file_exent(s.st_size, &extents, &extent_count);
else {
ret = map_file_extents(inimage, infile, in_fd, s.st_size, &extents, &extent_count);
if (ret < 0)
goto out;
}

/* The extents may have a different granularity than the chosen block size.
So all start and end of all extents must be aligned accordingly. The
Expand Down Expand Up @@ -391,6 +396,7 @@ static int android_sparse_setup(struct image *image, cfg_t *cfg)
sparse->block_size);
return -EINVAL;
}
sparse->fill_holes = cfg_getbool(cfg, "fill-holes");

image->handler_priv = sparse;
return 0;
Expand All @@ -399,6 +405,7 @@ static int android_sparse_setup(struct image *image, cfg_t *cfg)
static cfg_opt_t android_sparse_opts[] = {
CFG_STR("image", NULL, CFGF_NONE),
CFG_STR("block-size", "4k", CFGF_NONE),
CFG_BOOL("fill-holes", cfg_false, CFGF_NONE),
CFG_END()
};

Expand Down
11 changes: 11 additions & 0 deletions test/misc.test
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ test_expect_success simg2img "android-sparse" "
simg2img images/test.sparse images/test.hdimage &&
simg2img images/interleaved.sparse input/interleaved &&
simg2img images/not-aligned.sparse input/not-aligned &&
md5sum -c md5sum &&
run_genimage sparse-fill.config &&
# simg2img will expand the partial block
truncate --size=12k input/not-aligned
md5sum images/test.hdimage input/interleaved input/not-aligned > md5sum &&
rm images/test.hdimage input/interleaved input/not-aligned &&
check_size_range images/interleaved.sparse 9732464 9732636 &&
simg2img images/test.sparse images/test.hdimage &&
simg2img images/interleaved.sparse input/interleaved &&
simg2img images/not-aligned.sparse input/not-aligned &&
md5sum -c md5sum
"

Expand Down
42 changes: 42 additions & 0 deletions test/sparse-fill.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
image test.hdimage {
hdimage {
align = 1M
partition-table-type = "gpt"
disk-uuid = "afcfea87-e41a-40e0-85ae-295c60773c7a"
}
partition part1 {
image = "part1.img"
size = 10M
partition-uuid = "92762261-e854-45c1-b4c9-fc5e752034ab"
}
partition part2 {
image = "part2.img"
size = 10M
partition-type-uuid = "L"
partition-uuid = "41061242-1d5a-4657-892d-fcc1fdb11a6c"
}
size = 22M
}

image test.sparse {
android-sparse {
image = test.hdimage
fill-holes = true
}
}

image interleaved.sparse {
android-sparse {
image = interleaved
block-size = 32k
fill-holes = true
}
}

image not-aligned.sparse {
android-sparse {
image = not-aligned
block-size = 4k
fill-holes = true
}
}
4 changes: 2 additions & 2 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ int open_file(struct image *image, const char *filename, int extra_flags)
}

/* Build a file extent covering the whole file */
static int whole_file_exent(size_t size, struct extent **extents,
size_t *extent_count)
int whole_file_exent(size_t size, struct extent **extents,
size_t *extent_count)
{
*extents = xzalloc(sizeof(struct extent));
(*extents)[0].start = 0;
Expand Down

0 comments on commit d795d93

Please sign in to comment.