cleanup: move generic squashfs code to library

Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
This commit is contained in:
David Oberhollenzer 2019-04-22 20:19:27 +02:00
parent 5f0ee09c83
commit 7a70868fcd
10 changed files with 175 additions and 146 deletions

View File

@ -2,6 +2,9 @@
#ifndef SQUASHFS_H
#define SQUASHFS_H
#include "comp/compressor.h"
#include "pkg/pkgformat.h"
#include <stdint.h>
#define SQFS_MAGIC 0x73717368
@ -160,4 +163,36 @@ typedef enum {
SQFS_INODE_EXT_SOCKET = 14,
} E_SQFS_INODE_TYPE;
typedef struct {
uint8_t data[SQFS_META_BLOCK_SIZE + 2];
uint8_t scratch[SQFS_META_BLOCK_SIZE];
size_t offset;
size_t written;
int outfd;
compressor_stream_t *strm;
} meta_writer_t;
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
uint32_t blocksize, E_SQFS_COMPRESSOR comp);
int sqfs_super_write(const sqfs_super_t *super, int outfd);
compressor_stream_t *sqfs_get_compressor(sqfs_super_t *s);
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm);
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);
int sqfs_write_ids(int outfd, sqfs_super_t *super,
uint32_t *id_tbl, size_t count,
compressor_stream_t *strm);
int sqfs_write_fragment_table(int outfd, sqfs_super_t *super,
sqfs_fragment_t *fragments, size_t count,
compressor_stream_t *strm);
#endif /* SQUASHFS_H */

View File

@ -33,4 +33,7 @@ libpkg_a_SOURCES += include/pkg/pkgio.h include/pkg/pkgwriter.h
libpkg_a_SOURCES += lib/pkg/pkgreader.c lib/pkg/pkgwriter.c
libpkg_a_SOURCES += lib/pkg/pkg_unpack.c lib/pkg/pkgio_rd_image_entry.c
noinst_LIBRARIES += libutil.a libfilelist.a libcomp.a libpkg.a
libsqfs_a_SOURCES = include/sqfs/squashfs.h lib/sqfs/super.c
libsqfs_a_SOURCES += lib/sqfs/meta_writer.c lib/sqfs/table.c
noinst_LIBRARIES += libutil.a libfilelist.a libcomp.a libpkg.a libsqfs.a

View File

@ -1,5 +1,10 @@
/* SPDX-License-Identifier: ISC */
#include "pkg2sqfs.h"
#include "sqfs/squashfs.h"
#include "util/util.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm)
{

View File

@ -1,10 +1,11 @@
/* SPDX-License-Identifier: ISC */
#include <endian.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "sqfs/squashfs.h"
#include "util/util.h"
#include "pkg2sqfs.h"
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
uint32_t blocksize, E_SQFS_COMPRESSOR comp)
@ -50,47 +51,47 @@ int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
return 0;
}
int sqfs_super_write(sqfs_info_t *info)
int sqfs_super_write(const sqfs_super_t *super, int outfd)
{
sqfs_super_t copy;
ssize_t ret;
off_t off;
copy.magic = htole32(info->super.magic);
copy.inode_count = htole32(info->super.inode_count);
copy.modification_time = htole32(info->super.modification_time);
copy.block_size = htole32(info->super.block_size);
copy.fragment_entry_count = htole32(info->super.fragment_entry_count);
copy.compression_id = htole16(info->super.compression_id);
copy.block_log = htole16(info->super.block_log);
copy.flags = htole16(info->super.flags);
copy.id_count = htole16(info->super.id_count);
copy.version_major = htole16(info->super.version_major);
copy.version_minor = htole16(info->super.version_minor);
copy.root_inode_ref = htole64(info->super.root_inode_ref);
copy.bytes_used = htole64(info->super.bytes_used);
copy.id_table_start = htole64(info->super.id_table_start);
copy.xattr_id_table_start = htole64(info->super.xattr_id_table_start);
copy.inode_table_start = htole64(info->super.inode_table_start);
copy.directory_table_start = htole64(info->super.directory_table_start);
copy.fragment_table_start = htole64(info->super.fragment_table_start);
copy.export_table_start = htole64(info->super.export_table_start);
copy.magic = htole32(super->magic);
copy.inode_count = htole32(super->inode_count);
copy.modification_time = htole32(super->modification_time);
copy.block_size = htole32(super->block_size);
copy.fragment_entry_count = htole32(super->fragment_entry_count);
copy.compression_id = htole16(super->compression_id);
copy.block_log = htole16(super->block_log);
copy.flags = htole16(super->flags);
copy.id_count = htole16(super->id_count);
copy.version_major = htole16(super->version_major);
copy.version_minor = htole16(super->version_minor);
copy.root_inode_ref = htole64(super->root_inode_ref);
copy.bytes_used = htole64(super->bytes_used);
copy.id_table_start = htole64(super->id_table_start);
copy.xattr_id_table_start = htole64(super->xattr_id_table_start);
copy.inode_table_start = htole64(super->inode_table_start);
copy.directory_table_start = htole64(super->directory_table_start);
copy.fragment_table_start = htole64(super->fragment_table_start);
copy.export_table_start = htole64(super->export_table_start);
off = lseek(info->outfd, 0, SEEK_SET);
off = lseek(outfd, 0, SEEK_SET);
if (off == (off_t)-1) {
perror("seek on output file");
perror("squashfs writing super block: seek on output file");
return -1;
}
ret = write_retry(info->outfd, &copy, sizeof(copy));
ret = write_retry(outfd, &copy, sizeof(copy));
if (ret < 0) {
perror("Error writing squashfs super block");
perror("squashfs writing super block");
return -1;
}
if (ret == 0) {
fputs("Truncated write trying to write squashfs super block\n",
fputs("squashfs writing super block: truncated write\n",
stderr);
return -1;
}

92
lib/sqfs/table.c Normal file
View File

@ -0,0 +1,92 @@
/* SPDX-License-Identifier: ISC */
#include "sqfs/squashfs.h"
#include "util/util.h"
#include <endian.h>
#include <stdio.h>
static int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data,
size_t entsize, size_t count, uint64_t *startblock,
compressor_stream_t *strm)
{
size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize;
uint64_t blocks[count / ent_per_blocks + 1];
size_t i, blkidx = 0, tblsize;
meta_writer_t *m;
ssize_t ret;
/* Write actual data. Whenever we cross a block boundary, remember
the block start offset */
m = meta_writer_create(outfd, strm);
if (m == NULL)
return -1;
for (i = 0; i < count; ++i) {
if (blkidx == 0 || m->written > blocks[blkidx - 1])
blocks[blkidx++] = m->written;
if (meta_writer_append(m, data, entsize))
goto fail;
data = (const char *)data + entsize;
}
if (meta_writer_flush(m))
goto fail;
for (i = 0; i < blkidx; ++i)
blocks[i] = htole64(blocks[i] + super->bytes_used);
super->bytes_used += m->written;
meta_writer_destroy(m);
/* write new index table */
*startblock = super->bytes_used;
tblsize = sizeof(blocks[0]) * blkidx;
ret = write_retry(outfd, blocks, tblsize);
if (ret < 0) {
perror("writing index table");
return -1;
}
if ((size_t)ret < tblsize) {
fputs("index table truncated\n", stderr);
return -1;
}
super->bytes_used += tblsize;
return 0;
fail:
meta_writer_destroy(m);
return -1;
}
int sqfs_write_fragment_table(int outfd, sqfs_super_t *super,
sqfs_fragment_t *fragments, size_t count,
compressor_stream_t *strm)
{
super->fragment_entry_count = count;
return sqfs_write_table(outfd, super, fragments, sizeof(fragments[0]),
count, &super->fragment_table_start, strm);
}
int sqfs_write_ids(int outfd, sqfs_super_t *super,
uint32_t *id_tbl, size_t count,
compressor_stream_t *strm)
{
size_t i;
int ret;
for (i = 0; i < count; ++i)
id_tbl[i] = htole32(id_tbl[i]);
ret = sqfs_write_table(outfd, super, id_tbl, sizeof(id_tbl[0]),
count, &super->id_table_start, strm);
for (i = 0; i < count; ++i)
id_tbl[i] = htole32(id_tbl[i]);
return ret;
}

View File

@ -1,9 +1,9 @@
pkg2sqfs_SOURCES = sqfs/squashfs.h sqfs/super.c sqfs/pkg2sqfs.c
pkg2sqfs_SOURCES = sqfs/pkg2sqfs.c
pkg2sqfs_SOURCES += sqfs/vfs.c sqfs/pkg2sqfs.h sqfs/block.c
pkg2sqfs_SOURCES += sqfs/meta.c sqfs/meta_writer.c sqfs/table.c
pkg2sqfs_SOURCES += sqfs/meta.c
pkg2sqfs_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/sqfs
pkg2sqfs_CFLAGS = $(AM_CFLAGS)
pkg2sqfs_LDADD = libpkg.a libutil.a libfilelist.a libcomp.a
pkg2sqfs_LDADD = libsqfs.a libpkg.a libutil.a libfilelist.a libcomp.a
if WITH_LZMA
pkg2sqfs_LDADD += $(XZ_LIBS)

View File

@ -269,7 +269,7 @@ int main(int argc, char **argv)
if (create_vfs_tree(&info))
goto out_buffer;
if (sqfs_super_write(&info))
if (sqfs_super_write(&info.super, info.outfd))
goto out_tree;
if (pkg_data_to_sqfs(&info, cmp))
@ -281,13 +281,16 @@ int main(int argc, char **argv)
if (sqfs_write_inodes(&info, cmp))
goto out_fragments;
if (sqfs_write_fragment_table(&info, cmp))
if (sqfs_write_fragment_table(info.outfd, &info.super,
info.fragments, info.num_fragments,
cmp))
goto out_fragments;
if (sqfs_write_ids(&info, cmp))
if (sqfs_write_ids(info.outfd, &info.super,
info.fs.id_tbl, info.fs.num_ids, cmp))
goto out_fragments;
if (sqfs_super_write(&info))
if (sqfs_super_write(&info.super, info.outfd))
goto out_fragments;
if (sqfs_padd_file(&info))

View File

@ -23,20 +23,11 @@
#include "filelist/image_entry.h"
#include "comp/compressor.h"
#include "pkg/pkgreader.h"
#include "sqfs/squashfs.h"
#include "pkg/pkgio.h"
#include "squashfs.h"
#include "config.h"
typedef struct {
uint8_t data[SQFS_META_BLOCK_SIZE + 2];
uint8_t scratch[SQFS_META_BLOCK_SIZE];
size_t offset;
size_t written;
int outfd;
compressor_stream_t *strm;
} meta_writer_t;
typedef struct file_info_t {
struct file_info_t *frag_next;
uint64_t size;
@ -112,11 +103,6 @@ typedef struct {
int pkg_data_to_sqfs(sqfs_info_t *info, compressor_stream_t *strm);
int sqfs_super_init(sqfs_super_t *s, int64_t timestamp,
uint32_t blocksize, E_SQFS_COMPRESSOR comp);
int sqfs_super_write(sqfs_info_t *info);
int create_vfs_tree(sqfs_info_t *info);
void destroy_vfs_tree(vfs_t *fs);
@ -125,18 +111,4 @@ node_t *vfs_node_from_file_id(vfs_t *fs, uint32_t id);
int sqfs_write_inodes(sqfs_info_t *info, compressor_stream_t *strm);
int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm);
int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm);
meta_writer_t *meta_writer_create(int fd, compressor_stream_t *strm);
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);
compressor_stream_t *sqfs_get_compressor(sqfs_super_t *s);
#endif /* PKG2SQFS_H */

View File

@ -1,77 +0,0 @@
/* SPDX-License-Identifier: ISC */
#include "pkg2sqfs.h"
static int sqfs_write_table(sqfs_info_t *info, const void *data,
size_t entsize, size_t count, uint64_t *startblock,
compressor_stream_t *strm)
{
size_t ent_per_blocks = SQFS_META_BLOCK_SIZE / entsize;
uint64_t blocks[count / ent_per_blocks + 1];
size_t i, blkidx = 0, tblsize;
meta_writer_t *m;
ssize_t ret;
/* Write actual data. Whenever we cross a block boundary, remember
the block start offset */
m = meta_writer_create(info->outfd, strm);
if (m == NULL)
return -1;
for (i = 0; i < count; ++i) {
if (blkidx == 0 || m->written > blocks[blkidx - 1])
blocks[blkidx++] = m->written;
if (meta_writer_append(m, data, entsize))
goto fail;
data = (const char *)data + entsize;
}
if (meta_writer_flush(m))
goto fail;
for (i = 0; i < blkidx; ++i)
blocks[i] = htole64(blocks[i] + info->super.bytes_used);
info->super.bytes_used += m->written;
meta_writer_destroy(m);
/* write new index table */
*startblock = info->super.bytes_used;
tblsize = sizeof(blocks[0]) * blkidx;
ret = write_retry(info->outfd, blocks, tblsize);
if (ret < 0) {
perror("writing index table");
return -1;
}
if ((size_t)ret < tblsize) {
fputs("index table truncated\n", stderr);
return -1;
}
info->super.bytes_used += tblsize;
return 0;
fail:
meta_writer_destroy(m);
return -1;
}
int sqfs_write_fragment_table(sqfs_info_t *info, compressor_stream_t *strm)
{
info->super.fragment_entry_count = info->num_fragments;
return sqfs_write_table(info, info->fragments,
sizeof(info->fragments[0]),
info->num_fragments,
&info->super.fragment_table_start, strm);
}
int sqfs_write_ids(sqfs_info_t *info, compressor_stream_t *strm)
{
return sqfs_write_table(info, info->fs.id_tbl,
sizeof(info->fs.id_tbl[0]),
info->fs.num_ids,
&info->super.id_table_start, strm);
}

View File

@ -316,7 +316,6 @@ int create_vfs_tree(sqfs_info_t *info)
uint32_t counter = 2;
vfs_t *fs = &info->fs;
node_t *n;
size_t i;
if (image_entry_list_from_package(info->rd, &list))
return -1;
@ -351,10 +350,6 @@ int create_vfs_tree(sqfs_info_t *info)
info->super.id_count = fs->num_ids;
image_entry_free_list(list);
for (i = 0; i < fs->num_ids; ++i)
fs->id_tbl[i] = htole32(fs->id_tbl[i]);
return 0;
fail_oom:
fputs("out of memory\n", stderr);