aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mkfs/Makemodule.am3
-rw-r--r--mkfs/meta_writer.c92
-rw-r--r--mkfs/meta_writer.h24
-rw-r--r--mkfs/options.c3
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,