From 3a851dfe87c88ac1d4dddc2a26cc48b037f852f9 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 8 Sep 2019 14:53:30 +0200 Subject: Replace direct file I/O with abstraction layer This should make it easier to use libsquashfs with custom setups that embedd a squashfs image inside something else. Also, it should make it easier to port to non unix-like platforms. Signed-off-by: David Oberhollenzer --- lib/sqfshelper/data_reader.c | 12 +++++++----- lib/sqfshelper/data_writer.c | 39 +++++++++++++------------------------ lib/sqfshelper/deserialize_fstree.c | 10 +++++----- lib/sqfshelper/serialize_fstree.c | 6 +++--- lib/sqfshelper/sqfs_reader.c | 18 ++++++++--------- lib/sqfshelper/write_export_table.c | 4 ++-- lib/sqfshelper/write_xattr.c | 13 ++++++++----- 7 files changed, 47 insertions(+), 55 deletions(-) (limited to 'lib/sqfshelper') diff --git a/lib/sqfshelper/data_reader.c b/lib/sqfshelper/data_reader.c index fc92e28..d1a9cce 100644 --- a/lib/sqfshelper/data_reader.c +++ b/lib/sqfshelper/data_reader.c @@ -25,7 +25,7 @@ struct data_reader_t { sqfs_compressor_t *cmp; size_t block_size; - int sqfsfd; + sqfs_file_t *file; void *block; void *scratch; @@ -44,8 +44,10 @@ static ssize_t read_block(data_reader_t *data, off_t offset, uint32_t size, if (size > data->block_size) goto fail_bs; - if (read_data_at("reading block", offset, data->sqfsfd, ptr, size)) + if (data->file->read_at(data->file, offset, ptr, size)) { + fputs("error reading data block from input file\n", stderr); return -1; + } if (compressed) { ret = data->cmp->do_block(data->cmp, data->scratch, size, @@ -104,7 +106,7 @@ static int precache_fragment_block(data_reader_t *data, size_t idx) return 0; } -data_reader_t *data_reader_create(int fd, sqfs_super_t *super, +data_reader_t *data_reader_create(sqfs_file_t *file, sqfs_super_t *super, sqfs_compressor_t *cmp) { data_reader_t *data = alloc_flex(sizeof(*data), super->block_size, 3); @@ -123,7 +125,7 @@ data_reader_t *data_reader_create(int fd, sqfs_super_t *super, data->scratch = (char *)data->block + super->block_size; data->frag_block = (char *)data->scratch + super->block_size; data->current_block = -1; - data->sqfsfd = fd; + data->file = file; data->block_size = super->block_size; data->cmp = cmp; @@ -144,7 +146,7 @@ data_reader_t *data_reader_create(int fd, sqfs_super_t *super, return NULL; } - ret = sqfs_read_table(fd, cmp, size, super->fragment_table_start, + ret = sqfs_read_table(file, cmp, size, super->fragment_table_start, super->directory_table_start, super->fragment_table_start, &raw_frag); diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c index 62e3e2a..b94bdb6 100644 --- a/lib/sqfshelper/data_writer.c +++ b/lib/sqfshelper/data_writer.c @@ -32,7 +32,7 @@ struct data_writer_t { sqfs_compressor_t *cmp; file_info_t *list; sqfs_super_t *super; - int outfd; + sqfs_file_t *file; }; enum { @@ -45,32 +45,19 @@ enum { static int save_position(data_writer_t *data) { data->bytes_written = data->super->bytes_used; - data->start = lseek(data->outfd, 0, SEEK_CUR); - - if (data->start == (off_t)-1) { - perror("querying current position on squashfs image"); - return -1; - } - + data->start = data->file->get_size(data->file); return 0; } static int restore_position(data_writer_t *data) { - if (lseek(data->outfd, data->start, SEEK_SET) == (off_t)-1) - goto fail_seek; - - if (ftruncate(data->outfd, data->start)) - goto fail_truncate; + if (data->file->truncate(data->file, data->start)) { + perror("truncating squashfs image after file deduplication"); + return -1; + } data->super->bytes_used = data->bytes_written; return 0; -fail_seek: - perror("seeking on squashfs image after file deduplication"); - return -1; -fail_truncate: - perror("truncating squashfs image after file deduplication"); - return -1; } static int allign_file(data_writer_t *data) @@ -80,7 +67,7 @@ static int allign_file(data_writer_t *data) if (diff == 0) return 0; - if (padd_file(data->outfd, data->super->bytes_used, data->devblksz)) + if (padd_sqfs(data->file, data->super->bytes_used, data->devblksz)) return -1; data->super->bytes_used += data->devblksz - diff; @@ -122,8 +109,10 @@ static int block_callback(void *user, sqfs_block_t *blk) fi->blocks[blk->index].size = htole32(out); } - if (write_data("writing data block", data->outfd, - blk->data, blk->size)) { + offset = data->file->get_size(data->file); + + if (data->file->write_at(data->file, offset, + blk->data, blk->size)) { return -1; } @@ -489,7 +478,7 @@ int write_data_from_fd_condensed(data_writer_t *data, file_info_t *fi, } data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp, - int outfd, size_t devblksize, + sqfs_file_t *file, size_t devblksize, unsigned int num_jobs) { data_writer_t *data = calloc(1, sizeof(*data)); @@ -504,7 +493,7 @@ data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp, block_callback); data->cmp = cmp; data->super = super; - data->outfd = outfd; + data->file = file; data->devblksz = devblksize; return data; } @@ -529,7 +518,7 @@ int data_writer_write_fragment_table(data_writer_t *data) } size = sizeof(data->fragments[0]) * data->num_fragments; - ret = sqfs_write_table(data->outfd, data->super, data->cmp, + ret = sqfs_write_table(data->file, data->super, data->cmp, data->fragments, size, &start); if (ret) return -1; diff --git a/lib/sqfshelper/deserialize_fstree.c b/lib/sqfshelper/deserialize_fstree.c index 1953f9b..37861e6 100644 --- a/lib/sqfshelper/deserialize_fstree.c +++ b/lib/sqfshelper/deserialize_fstree.c @@ -203,7 +203,7 @@ static int fill_dir(sqfs_meta_reader_t *ir, sqfs_meta_reader_t *dr, } int deserialize_fstree(fstree_t *out, sqfs_super_t *super, - sqfs_compressor_t *cmp, int fd, int flags) + sqfs_compressor_t *cmp, sqfs_file_t *file, int flags) { uint64_t block_start, limit; sqfs_meta_reader_t *ir, *dr; @@ -213,7 +213,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, int status = -1; size_t offset; - ir = sqfs_meta_reader_create(fd, cmp, super->inode_table_start, + ir = sqfs_meta_reader_create(file, cmp, super->inode_table_start, super->directory_table_start); if (ir == NULL) return -1; @@ -224,7 +224,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, if (super->fragment_table_start < limit) limit = super->fragment_table_start; - dr = sqfs_meta_reader_create(fd, cmp, super->directory_table_start, + dr = sqfs_meta_reader_create(file, cmp, super->directory_table_start, limit); if (dr == NULL) goto out_ir; @@ -233,10 +233,10 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, if (idtbl == NULL) goto out_dr; - if (sqfs_id_table_read(idtbl, fd, super, cmp)) + if (sqfs_id_table_read(idtbl, file, super, cmp)) goto out_id; - xr = sqfs_xattr_reader_create(fd, super, cmp); + xr = sqfs_xattr_reader_create(file, super, cmp); if (xr == NULL) goto out_id; diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c index dfadedd..ea3d479 100644 --- a/lib/sqfshelper/serialize_fstree.c +++ b/lib/sqfshelper/serialize_fstree.c @@ -41,7 +41,7 @@ static int write_dir_entries(sqfs_dir_writer_t *dirw, tree_node_t *node) return 0; } -int sqfs_serialize_fstree(int outfd, sqfs_super_t *super, fstree_t *fs, +int sqfs_serialize_fstree(sqfs_file_t *file, sqfs_super_t *super, fstree_t *fs, sqfs_compressor_t *cmp, sqfs_id_table_t *idtbl) { sqfs_inode_generic_t *inode; @@ -52,11 +52,11 @@ int sqfs_serialize_fstree(int outfd, sqfs_super_t *super, fstree_t *fs, int ret = -1; size_t i; - im = sqfs_meta_writer_create(outfd, cmp, false); + im = sqfs_meta_writer_create(file, cmp, false); if (im == NULL) return -1; - dm = sqfs_meta_writer_create(outfd, cmp, true); + dm = sqfs_meta_writer_create(file, cmp, true); if (dm == NULL) goto out_im; diff --git a/lib/sqfshelper/sqfs_reader.c b/lib/sqfshelper/sqfs_reader.c index 598b3c4..e9c9c33 100644 --- a/lib/sqfshelper/sqfs_reader.c +++ b/lib/sqfshelper/sqfs_reader.c @@ -18,13 +18,11 @@ int sqfs_reader_open(sqfs_reader_t *rd, const char *filename, int rdtree_flags) memset(rd, 0, sizeof(*rd)); - rd->sqfsfd = open(filename, O_RDONLY); - if (rd->sqfsfd < 0) { - perror(filename); + rd->file = sqfs_open_file(filename, SQFS_FILE_OPEN_READ_ONLY); + if (rd->file == NULL) return -1; - } - if (sqfs_super_read(&rd->super, rd->sqfsfd)) + if (sqfs_super_read(&rd->super, rd->file)) goto fail_fd; if (!sqfs_compressor_exists(rd->super.compression_id)) { @@ -41,21 +39,21 @@ int sqfs_reader_open(sqfs_reader_t *rd, const char *filename, int rdtree_flags) goto fail_fd; if (rd->super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) { - if (rd->cmp->read_options(rd->cmp, rd->sqfsfd)) + if (rd->cmp->read_options(rd->cmp, rd->file)) goto fail_cmp; } if (rd->super.flags & SQFS_FLAG_NO_XATTRS) rdtree_flags &= ~RDTREE_READ_XATTR; - if (deserialize_fstree(&rd->fs, &rd->super, rd->cmp, rd->sqfsfd, + if (deserialize_fstree(&rd->fs, &rd->super, rd->cmp, rd->file, rdtree_flags)) { goto fail_cmp; } fstree_gen_file_list(&rd->fs); - rd->data = data_reader_create(rd->sqfsfd, &rd->super, rd->cmp); + rd->data = data_reader_create(rd->file, &rd->super, rd->cmp); if (rd->data == NULL) goto fail_fs; @@ -65,7 +63,7 @@ fail_fs: fail_cmp: rd->cmp->destroy(rd->cmp); fail_fd: - close(rd->sqfsfd); + rd->file->destroy(rd->file); memset(rd, 0, sizeof(*rd)); return -1; } @@ -75,6 +73,6 @@ void sqfs_reader_close(sqfs_reader_t *rd) data_reader_destroy(rd->data); fstree_cleanup(&rd->fs); rd->cmp->destroy(rd->cmp); - close(rd->sqfsfd); + rd->file->destroy(rd->file); memset(rd, 0, sizeof(*rd)); } diff --git a/lib/sqfshelper/write_export_table.c b/lib/sqfshelper/write_export_table.c index b0ad4ce..f4c6658 100644 --- a/lib/sqfshelper/write_export_table.c +++ b/lib/sqfshelper/write_export_table.c @@ -12,7 +12,7 @@ #include #include -int write_export_table(int outfd, fstree_t *fs, sqfs_super_t *super, +int write_export_table(sqfs_file_t *file, fstree_t *fs, sqfs_super_t *super, sqfs_compressor_t *cmp) { uint64_t *table, start; @@ -38,7 +38,7 @@ int write_export_table(int outfd, fstree_t *fs, sqfs_super_t *super, } size = sizeof(uint64_t) * (fs->inode_tbl_size - 1); - ret = sqfs_write_table(outfd, super, cmp, table, size, &start); + ret = sqfs_write_table(file, super, cmp, table, size, &start); super->export_table_start = start; super->flags |= SQFS_FLAG_EXPORTABLE; diff --git a/lib/sqfshelper/write_xattr.c b/lib/sqfshelper/write_xattr.c index 6f71eeb..c4fb86e 100644 --- a/lib/sqfshelper/write_xattr.c +++ b/lib/sqfshelper/write_xattr.c @@ -167,7 +167,7 @@ static uint64_t *create_ool_locations_table(fstree_t *fs) return table; } -int write_xattr(int outfd, fstree_t *fs, sqfs_super_t *super, +int write_xattr(sqfs_file_t *file, fstree_t *fs, sqfs_super_t *super, sqfs_compressor_t *cmp) { uint64_t kv_start, id_start, block, *tbl, *ool_locations; @@ -185,7 +185,7 @@ int write_xattr(int outfd, fstree_t *fs, sqfs_super_t *super, if (ool_locations == NULL) return -1; - mw = sqfs_meta_writer_create(outfd, cmp, false); + mw = sqfs_meta_writer_create(file, cmp, false); if (mw == NULL) goto fail_ool; @@ -254,11 +254,14 @@ int write_xattr(int outfd, fstree_t *fs, sqfs_super_t *super, idtbl.xattr_ids = htole32(count); idtbl.unused = 0; - if (write_data("writing xattr ID table", outfd, &idtbl, sizeof(idtbl))) + if (file->write_at(file, file->get_size(file), &idtbl, sizeof(idtbl))) { + perror("writing xattr ID table"); goto fail_tbl; + } - if (write_data("writing xattr ID table", - outfd, tbl, sizeof(tbl[0]) * blocks)) { + if (file->write_at(file, file->get_size(file), + tbl, sizeof(tbl[0]) * blocks)) { + perror("writing xattr ID table"); goto fail_tbl; } -- cgit v1.2.3