diff options
Diffstat (limited to 'mkfs')
| -rw-r--r-- | mkfs/Makemodule.am | 3 | ||||
| -rw-r--r-- | mkfs/meta_writer.c | 92 | ||||
| -rw-r--r-- | mkfs/meta_writer.h | 24 | ||||
| -rw-r--r-- | mkfs/options.c | 3 | 
4 files changed, 120 insertions, 2 deletions
| diff --git a/mkfs/Makemodule.am b/mkfs/Makemodule.am index ad3f166..7b0b353 100644 --- a/mkfs/Makemodule.am +++ b/mkfs/Makemodule.am @@ -1,6 +1,7 @@  mksquashfs_SOURCES = mkfs/mksquashfs.c mkfs/options.c mkfs/options.h +mksquashfs_SOURCES += mkfs/meta_writer.c mkfs/meta_writer.h  mksquashfs_SOURCES += include/squashfs.h -mksquashfs_LDADD = libfstree.a libcompress.a +mksquashfs_LDADD = libutil.a libfstree.a libcompress.a  if WITH_LZMA  mksquashfs_LDADD += $(XZ_LIBS) diff --git a/mkfs/meta_writer.c b/mkfs/meta_writer.c new file mode 100644 index 0000000..97db1c1 --- /dev/null +++ b/mkfs/meta_writer.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include "meta_writer.h" +#include "util.h" + +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> + +meta_writer_t *meta_writer_create(int fd, compressor_t *cmp) +{ +	meta_writer_t *m = calloc(1, sizeof(*m)); + +	if (m == NULL) { +		perror("creating meta data writer"); +		return NULL; +	} + +	m->cmp = cmp; +	m->outfd = fd; +	return m; +} + +void meta_writer_destroy(meta_writer_t *m) +{ +	free(m); +} + +int meta_writer_flush(meta_writer_t *m) +{ +	ssize_t ret, count; + +	if (m->offset == 0) +		return 0; + +	ret = m->cmp->do_block(m->cmp, m->data + 2, m->offset); +	if (ret < 0) +		return -1; + +	if (ret > 0) { +		((uint16_t *)m->data)[0] = htole16(ret); +		count = ret + 2; +	} else { +		((uint16_t *)m->data)[0] = htole16(m->offset | 0x8000); +		count = m->offset + 2; +	} + +	ret = write_retry(m->outfd, m->data, count); + +	if (ret < 0) { +		perror("writing meta data"); +		return -1; +	} + +	if (ret < count) { +		fputs("meta data written to file was truncated\n", stderr); +		return -1; +	} + +	memset(m->data, 0, sizeof(m->data)); +	m->offset = 0; +	m->block_offset += count; +	return 0; +} + +int meta_writer_append(meta_writer_t *m, const void *data, size_t size) +{ +	size_t diff; + +	while (size != 0) { +		diff = sizeof(m->data) - 2 - m->offset; + +		if (diff == 0) { +			if (meta_writer_flush(m)) +				return -1; +			diff = sizeof(m->data) - 2; +		} + +		if (diff > size) +			diff = size; + +		memcpy(m->data + 2 + m->offset, data, diff); +		m->offset += diff; +		size -= diff; +		data = (const char *)data + diff; +	} + +	if (m->offset == (sizeof(m->data) - 2)) +		return meta_writer_flush(m); + +	return 0; +} diff --git a/mkfs/meta_writer.h b/mkfs/meta_writer.h new file mode 100644 index 0000000..bfa4160 --- /dev/null +++ b/mkfs/meta_writer.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#ifndef META_WRITER_H +#define META_WRITER_H + +#include "squashfs.h" +#include "compress.h" + +typedef struct { +	uint8_t data[SQFS_META_BLOCK_SIZE + 2]; +	size_t offset; +	size_t block_offset; +	int outfd; +	compressor_t *cmp; +} meta_writer_t; + +meta_writer_t *meta_writer_create(int fd, compressor_t *cmp); + +void meta_writer_destroy(meta_writer_t *m); + +int meta_writer_flush(meta_writer_t *m); + +int meta_writer_append(meta_writer_t *m, const void *data, size_t size); + +#endif /* META_WRITER_H */ diff --git a/mkfs/options.c b/mkfs/options.c index e3371aa..fedf404 100644 --- a/mkfs/options.c +++ b/mkfs/options.c @@ -263,7 +263,8 @@ void process_command_line(options_t *opt, int argc, char **argv)  			break;  		case 'b':  			opt->blksz = read_number("Block size", optarg, -						 1024, 0xFFFFFFFF); +						 SQFS_META_BLOCK_SIZE, +						 0xFFFFFFFF);  			break;  		case 'B':  			opt->devblksz = read_number("Device block size", optarg, | 
