From 47f24f2a8faf71395a1d054e9823beb000442cce Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 4 Dec 2022 01:33:45 +0100 Subject: Implement rudimentary reference counting for sqfs_object_t Implement grab/drop functions to increase/decrease reference count and destroy the object if the count drops to 0. Make sure that all objects that maintain internal references actually grab that reference, duplicate it in the copy function, drop it in the destroy handler. Signed-off-by: David Oberhollenzer --- bin/gensquashfs/filemap_xattr.c | 4 ++-- bin/gensquashfs/fstree_from_file.c | 2 +- bin/gensquashfs/mkfs.c | 4 ++-- bin/rdsquashfs/fill_files.c | 2 +- bin/rdsquashfs/rdsquashfs.c | 16 ++++++------- bin/sqfs2tar/sqfs2tar.c | 21 ++++++++++------- bin/sqfsdiff/extract.c | 4 ++-- bin/sqfsdiff/sqfsdiff.c | 20 ++++++++-------- bin/tar2sqfs/process_tarball.c | 2 +- bin/tar2sqfs/tar2sqfs.c | 9 +++++-- extras/browse.c | 10 ++++---- extras/extract_one.c | 12 +++++----- extras/list_files.c | 8 +++---- extras/mk42sqfs.c | 12 +++++----- extras/mknastyfs.c | 12 +++++----- include/sqfs/dir_reader.h | 3 +-- include/sqfs/predef.h | 34 +++++++++++++++++++++++--- lib/common/compress.c | 4 ++-- lib/common/writer/cleanup.c | 24 +++++++++---------- lib/common/writer/init.c | 25 ++++++++++---------- lib/io/compress/ostream_compressor.c | 4 ++-- lib/io/uncompress/istream_compressor.c | 4 ++-- lib/io/unix/ostream.c | 2 ++ lib/sqfs/block_processor/block_processor.c | 18 ++++++++------ lib/sqfs/block_writer.c | 4 +++- lib/sqfs/data_reader.c | 15 +++++++----- lib/sqfs/dir_reader/dir_reader.c | 24 +++++++++---------- lib/sqfs/dir_reader/internal.h | 2 +- lib/sqfs/dir_writer.c | 3 ++- lib/sqfs/meta_reader.c | 14 +++++++---- lib/sqfs/meta_writer.c | 6 +++-- lib/sqfs/read_table.c | 4 ++-- lib/sqfs/write_table.c | 2 +- lib/sqfs/xattr/xattr_reader.c | 38 +++++++++--------------------- lib/sqfs/xattr/xattr_writer_flush.c | 2 +- tests/libio/get_line.c | 2 +- tests/libio/uncompress.c | 2 +- tests/libsqfs/table.c | 6 ++--- tests/libsqfs/xattr_benchmark.c | 4 ++-- tests/libsqfs/xattr_writer.c | 6 ++--- tests/libtar/tar_big_file.c | 2 +- tests/libtar/tar_fuzz.c | 4 ++-- tests/libtar/tar_simple.c | 2 +- tests/libtar/tar_sparse.c | 2 +- tests/libtar/tar_sparse_gnu.c | 2 +- tests/libtar/tar_target_filled.c | 3 +-- tests/libtar/tar_xattr.c | 2 +- tests/libtar/tar_xattr_bin.c | 2 +- tests/libutil/str_table.c | 2 +- 49 files changed, 223 insertions(+), 188 deletions(-) diff --git a/bin/gensquashfs/filemap_xattr.c b/bin/gensquashfs/filemap_xattr.c index 9693a54..dd76b50 100644 --- a/bin/gensquashfs/filemap_xattr.c +++ b/bin/gensquashfs/filemap_xattr.c @@ -193,12 +193,12 @@ xattr_open_map_file(const char *path) { goto fail; } - sqfs_destroy(file); + sqfs_drop(file); return map; fail: xattr_close_map_file(map); fail_close: - sqfs_destroy(file); + sqfs_drop(file); return NULL; } diff --git a/bin/gensquashfs/fstree_from_file.c b/bin/gensquashfs/fstree_from_file.c index feacbbc..e26d4b1 100644 --- a/bin/gensquashfs/fstree_from_file.c +++ b/bin/gensquashfs/fstree_from_file.c @@ -586,6 +586,6 @@ int fstree_from_file(fstree_t *fs, const char *filename, const char *basepath) ret = fstree_from_file_stream(fs, fp, basepath); - sqfs_destroy(fp); + sqfs_drop(fp); return ret; } diff --git a/bin/gensquashfs/mkfs.c b/bin/gensquashfs/mkfs.c index 171a887..c773dd7 100644 --- a/bin/gensquashfs/mkfs.c +++ b/bin/gensquashfs/mkfs.c @@ -59,7 +59,7 @@ static int pack_files(sqfs_block_processor_t *data, fstree_t *fs, flags |= SQFS_BLK_DONT_FRAGMENT; ret = write_data_from_file(path, data, &fi->inode, file, flags); - sqfs_destroy(file); + sqfs_drop(file); free(node_path); if (ret) @@ -209,7 +209,7 @@ out: if (sehnd != NULL) selinux_close_context_file(sehnd); if (sortfile != NULL) - sqfs_destroy(sortfile); + sqfs_drop(sortfile); free(opt.packdir); return status; } diff --git a/bin/rdsquashfs/fill_files.c b/bin/rdsquashfs/fill_files.c index 923bc12..3104146 100644 --- a/bin/rdsquashfs/fill_files.c +++ b/bin/rdsquashfs/fill_files.c @@ -158,7 +158,7 @@ static int fill_files(sqfs_data_reader_t *data, int flags) if (ret == 0) ret = ostream_flush(fp); - sqfs_destroy(fp); + sqfs_drop(fp); if (ret) return -1; } diff --git a/bin/rdsquashfs/rdsquashfs.c b/bin/rdsquashfs/rdsquashfs.c index 206b754..a18ac7f 100644 --- a/bin/rdsquashfs/rdsquashfs.c +++ b/bin/rdsquashfs/rdsquashfs.c @@ -221,11 +221,11 @@ int main(int argc, char **argv) if (sqfs_data_reader_dump(opt.cmdpath, data, n->inode, fp, super.block_size)) { - sqfs_destroy(fp); + sqfs_drop(fp); goto out; } - sqfs_destroy(fp); + sqfs_drop(fp); break; } case OP_UNPACK: @@ -267,18 +267,18 @@ int main(int argc, char **argv) out: sqfs_dir_tree_destroy(n); out_data: - sqfs_destroy(data); + sqfs_drop(data); out_dr: - sqfs_destroy(dirrd); + sqfs_drop(dirrd); out_id: - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_xr: if (xattr != NULL) - sqfs_destroy(xattr); + sqfs_drop(xattr); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_file: - sqfs_destroy(file); + sqfs_drop(file); out_cmd: free(opt.cmdpath); return status; diff --git a/bin/sqfs2tar/sqfs2tar.c b/bin/sqfs2tar/sqfs2tar.c index 00d1e27..9dfa41e 100644 --- a/bin/sqfs2tar/sqfs2tar.c +++ b/bin/sqfs2tar/sqfs2tar.c @@ -124,7 +124,11 @@ int main(int argc, char **argv) } if (compressor > 0) { - out_file = ostream_compressor_create(out_file, compressor); + ostream_t *strm = ostream_compressor_create(out_file, + compressor); + sqfs_drop(out_file); + out_file = strm; + if (out_file == NULL) goto out_dirs; } @@ -251,20 +255,19 @@ out: if (root != NULL) sqfs_dir_tree_destroy(root); out_xr: - if (xr != NULL) - sqfs_destroy(xr); + sqfs_drop(xr); out_dr: - sqfs_destroy(dr); + sqfs_drop(dr); out_data: - sqfs_destroy(data); + sqfs_drop(data); out_id: - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_fd: - sqfs_destroy(file); + sqfs_drop(file); out_ostrm: - sqfs_destroy(out_file); + sqfs_drop(out_file); out_dirs: for (i = 0; i < num_subdirs; ++i) free(subdirs[i]); diff --git a/bin/sqfsdiff/extract.c b/bin/sqfsdiff/extract.c index 0c68918..f2072d4 100644 --- a/bin/sqfsdiff/extract.c +++ b/bin/sqfsdiff/extract.c @@ -29,12 +29,12 @@ static int extract(sqfs_data_reader_t *data, const sqfs_inode_generic_t *inode, } if (sqfs_data_reader_dump(path, data, inode, fp, block_size)) { - sqfs_destroy(fp); + sqfs_drop(fp); return -1; } ostream_flush(fp); - sqfs_destroy(fp); + sqfs_drop(fp); return 0; } diff --git a/bin/sqfsdiff/sqfsdiff.c b/bin/sqfsdiff/sqfsdiff.c index 0673f8d..9d29332 100644 --- a/bin/sqfsdiff/sqfsdiff.c +++ b/bin/sqfsdiff/sqfsdiff.c @@ -97,28 +97,28 @@ static int open_sfqs(sqfs_state_t *state, const char *path) return 0; fail_data: - sqfs_destroy(state->data); + sqfs_drop(state->data); fail_tree: sqfs_dir_tree_destroy(state->root); fail_dr: - sqfs_destroy(state->dr); + sqfs_drop(state->dr); fail_id: - sqfs_destroy(state->idtbl); + sqfs_drop(state->idtbl); fail_cmp: - sqfs_destroy(state->cmp); + sqfs_drop(state->cmp); fail_file: - sqfs_destroy(state->file); + sqfs_drop(state->file); return -1; } static void close_sfqs(sqfs_state_t *state) { - sqfs_destroy(state->data); + sqfs_drop(state->data); sqfs_dir_tree_destroy(state->root); - sqfs_destroy(state->dr); - sqfs_destroy(state->idtbl); - sqfs_destroy(state->cmp); - sqfs_destroy(state->file); + sqfs_drop(state->dr); + sqfs_drop(state->idtbl); + sqfs_drop(state->cmp); + sqfs_drop(state->file); } int main(int argc, char **argv) diff --git a/bin/tar2sqfs/process_tarball.c b/bin/tar2sqfs/process_tarball.c index c0ae5a3..6aaa24b 100644 --- a/bin/tar2sqfs/process_tarball.c +++ b/bin/tar2sqfs/process_tarball.c @@ -72,7 +72,7 @@ static int write_file(istream_t *input_file, sqfs_writer_t *sqfs, } ostream_flush(out); - sqfs_destroy(out); + sqfs_drop(out); if (ret) return -1; diff --git a/bin/tar2sqfs/tar2sqfs.c b/bin/tar2sqfs/tar2sqfs.c index 4e9ade9..572eb10 100644 --- a/bin/tar2sqfs/tar2sqfs.c +++ b/bin/tar2sqfs/tar2sqfs.c @@ -50,6 +50,8 @@ int main(int argc, char **argv) goto out_if; if (ret > 0) { + istream_t *strm; + if (!io_compressor_exists(ret)) { fprintf(stderr, "%s: %s compression is not supported.\n", @@ -58,7 +60,10 @@ int main(int argc, char **argv) goto out_if; } - input_file = istream_compressor_create(input_file, ret); + strm = istream_compressor_create(input_file, ret); + sqfs_drop(input_file); + input_file = strm; + if (input_file == NULL) return EXIT_FAILURE; } @@ -80,6 +85,6 @@ int main(int argc, char **argv) out: sqfs_writer_cleanup(&sqfs, status); out_if: - sqfs_destroy(input_file); + sqfs_drop(input_file); return status; } diff --git a/extras/browse.c b/extras/browse.c index cc31105..8bc6fc3 100644 --- a/extras/browse.c +++ b/extras/browse.c @@ -612,16 +612,16 @@ int main(int argc, char **argv) status = EXIT_SUCCESS; free(buffer); out: - sqfs_destroy(data); + sqfs_drop(data); out_dir: if (working_dir != NULL) free(working_dir); - sqfs_destroy(dr); + sqfs_drop(dr); out_id: - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_fd: - sqfs_destroy(file); + sqfs_drop(file); return status; } diff --git a/extras/extract_one.c b/extras/extract_one.c index fcd8124..63c83f9 100644 --- a/extras/extract_one.c +++ b/extras/extract_one.c @@ -165,12 +165,12 @@ int main(int argc, char **argv) status = EXIT_SUCCESS; out: sqfs_dir_tree_destroy(n); - sqfs_destroy(data); - sqfs_destroy(dirrd); - sqfs_destroy(idtbl); - sqfs_destroy(xattr); - sqfs_destroy(cmp); - sqfs_destroy(file); + sqfs_drop(data); + sqfs_drop(dirrd); + sqfs_drop(idtbl); + sqfs_drop(xattr); + sqfs_drop(cmp); + sqfs_drop(file); free(output); return status; diff --git a/extras/list_files.c b/extras/list_files.c index e368f2a..d1e0a64 100644 --- a/extras/list_files.c +++ b/extras/list_files.c @@ -129,12 +129,12 @@ int main(int argc, char **argv) out: if (root != NULL) sqfs_dir_tree_destroy(root); - sqfs_destroy(dr); + sqfs_drop(dr); out_id: - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_fd: - sqfs_destroy(file); + sqfs_drop(file); return status; } diff --git a/extras/mk42sqfs.c b/extras/mk42sqfs.c index e9b0823..87e1523 100644 --- a/extras/mk42sqfs.c +++ b/extras/mk42sqfs.c @@ -197,16 +197,16 @@ int main(int argc, char **argv) /* cleanup */ status = EXIT_SUCCESS; - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_dirwr: - sqfs_destroy(dirwr); + sqfs_drop(dirwr); out_dm: - sqfs_destroy(dir_m); + sqfs_drop(dir_m); out_im: - sqfs_destroy(inode_m); + sqfs_drop(inode_m); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_file: - sqfs_destroy(file); + sqfs_drop(file); return status; } diff --git a/extras/mknastyfs.c b/extras/mknastyfs.c index c65759c..c72bd7d 100644 --- a/extras/mknastyfs.c +++ b/extras/mknastyfs.c @@ -176,16 +176,16 @@ int main(int argc, char **argv) /* cleanup */ status = EXIT_SUCCESS; - sqfs_destroy(idtbl); + sqfs_drop(idtbl); out_dirwr: - sqfs_destroy(dirwr); + sqfs_drop(dirwr); out_dm: - sqfs_destroy(dir_m); + sqfs_drop(dir_m); out_im: - sqfs_destroy(inode_m); + sqfs_drop(inode_m); out_cmp: - sqfs_destroy(cmp); + sqfs_drop(cmp); out_file: - sqfs_destroy(file); + sqfs_drop(file); return status; } diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index e6b23f2..ace7bad 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -206,8 +206,7 @@ extern "C" { * version 1.2 introduced the @ref SQFS_DIR_READER_DOT_ENTRIES flag, * earlier versions require the flags field to be set to zero. * - * @param super A pointer to the super block. Kept internally an used for - * resolving table positions. + * @param super A pointer to the super block. * @param cmp A compressor to use for unpacking meta data blocks. * @param file The input file to read from. * @param flags A combination of @ref SQFS_DIR_READER_FLAGS diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h index 39da692..7a7eef8 100644 --- a/include/sqfs/predef.h +++ b/include/sqfs/predef.h @@ -124,22 +124,49 @@ typedef struct sqfs_xattr_id_table_t sqfs_xattr_id_table_t; * @brief Base interface for all libsquashfs in-memory data structures. */ typedef struct sqfs_object_t { + size_t refcount; + void (*destroy)(struct sqfs_object_t *instance); struct sqfs_object_t *(*copy)(const struct sqfs_object_t *orig); } sqfs_object_t; /** - * @brief Destroy an object and free all its memory + * @brief Grab a reference to an object * * @memberof sqfs_object_t * * @param obj A pointer to an object or NULL + * + * @return The original pointer passed into the function */ -static SQFS_INLINE void sqfs_destroy(void *obj) +static SQFS_INLINE void *sqfs_grab(void *obj) { if (obj) - ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj); + ((sqfs_object_t *)obj)->refcount += 1; + return obj; +} + +/** + * @brief Drop a reference to an object, release it if it was the last reference + * + * @memberof sqfs_object_t + * + * @param obj A pointer to an object or NULL + * + * @return A NULL pointer. + */ +static SQFS_INLINE void *sqfs_drop(void *obj) +{ + if (obj) { + if (((sqfs_object_t *)obj)->refcount <= 1) { + ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj); + } else { + ((sqfs_object_t *)obj)->refcount -= 1; + } + } + + return NULL; } /** @@ -174,6 +201,7 @@ void sqfs_object_init(void *obj, void (*destroy_fn)(sqfs_object_t *), sqfs_object_t *(*copy_fn)(const sqfs_object_t *)) { + ((sqfs_object_t *)obj)->refcount = 1; ((sqfs_object_t *)obj)->destroy = destroy_fn; ((sqfs_object_t *)obj)->copy = copy_fn; } diff --git a/lib/common/compress.c b/lib/common/compress.c index b11efbd..1e0ca06 100644 --- a/lib/common/compress.c +++ b/lib/common/compress.c @@ -32,7 +32,7 @@ SQFS_COMPRESSOR compressor_get_default(void) ret = sqfs_compressor_create(&cfg, &temp); if (ret == 0) { - sqfs_destroy(temp); + sqfs_drop(temp); return cmp_ids[i]; } } @@ -64,7 +64,7 @@ void compressor_print_available(void) have_compressor = false; if (ret == 0) { - sqfs_destroy(temp); + sqfs_drop(temp); have_compressor = true; } else { #ifdef WITH_LZO diff --git a/lib/common/writer/cleanup.c b/lib/common/writer/cleanup.c index 1af7a99..a3fd039 100644 --- a/lib/common/writer/cleanup.c +++ b/lib/common/writer/cleanup.c @@ -10,20 +10,18 @@ void sqfs_writer_cleanup(sqfs_writer_t *sqfs, int status) { - if (sqfs->xwr != NULL) - sqfs_destroy(sqfs->xwr); - - sqfs_destroy(sqfs->dirwr); - sqfs_destroy(sqfs->dm); - sqfs_destroy(sqfs->im); - sqfs_destroy(sqfs->idtbl); - sqfs_destroy(sqfs->data); - sqfs_destroy(sqfs->blkwr); - sqfs_destroy(sqfs->fragtbl); - sqfs_destroy(sqfs->cmp); - sqfs_destroy(sqfs->uncmp); + sqfs_drop(sqfs->xwr); + sqfs_drop(sqfs->dirwr); + sqfs_drop(sqfs->dm); + sqfs_drop(sqfs->im); + sqfs_drop(sqfs->idtbl); + sqfs_drop(sqfs->data); + sqfs_drop(sqfs->blkwr); + sqfs_drop(sqfs->fragtbl); + sqfs_drop(sqfs->cmp); + sqfs_drop(sqfs->uncmp); fstree_cleanup(&sqfs->fs); - sqfs_destroy(sqfs->outfile); + sqfs_drop(sqfs->outfile); if (status != EXIT_SUCCESS) { #if defined(_WIN32) || defined(__WINDOWS__) diff --git a/lib/common/writer/init.c b/lib/common/writer/init.c index 7940c3f..497fc6e 100644 --- a/lib/common/writer/init.c +++ b/lib/common/writer/init.c @@ -70,7 +70,7 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg) #ifdef WITH_LZO if (cfg.id == SQFS_COMP_LZO) { if (sqfs->cmp != NULL) - sqfs_destroy(sqfs->cmp); + sqfs_drop(sqfs->cmp); ret = lzo_compressor_create(&cfg, &sqfs->cmp); } @@ -87,7 +87,7 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg) #ifdef WITH_LZO if (cfg.id == SQFS_COMP_LZO) { if (ret == 0 && sqfs->uncmp != NULL) - sqfs_destroy(sqfs->uncmp); + sqfs_drop(sqfs->uncmp); ret = lzo_compressor_create(&cfg, &sqfs->uncmp); } @@ -193,27 +193,26 @@ int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg) return 0; fail_dm: - sqfs_destroy(sqfs->dm); + sqfs_drop(sqfs->dm); fail_im: - sqfs_destroy(sqfs->im); + sqfs_drop(sqfs->im); fail_xwr: - if (sqfs->xwr != NULL) - sqfs_destroy(sqfs->xwr); + sqfs_drop(sqfs->xwr); fail_id: - sqfs_destroy(sqfs->idtbl); + sqfs_drop(sqfs->idtbl); fail_data: - sqfs_destroy(sqfs->data); + sqfs_drop(sqfs->data); fail_fragtbl: - sqfs_destroy(sqfs->fragtbl); + sqfs_drop(sqfs->fragtbl); fail_blkwr: - sqfs_destroy(sqfs->blkwr); + sqfs_drop(sqfs->blkwr); fail_uncmp: - sqfs_destroy(sqfs->uncmp); + sqfs_drop(sqfs->uncmp); fail_cmp: - sqfs_destroy(sqfs->cmp); + sqfs_drop(sqfs->cmp); fail_fs: fstree_cleanup(&sqfs->fs); fail_file: - sqfs_destroy(sqfs->outfile); + sqfs_drop(sqfs->outfile); return -1; } diff --git a/lib/io/compress/ostream_compressor.c b/lib/io/compress/ostream_compressor.c index f63a3d2..a5f16d5 100644 --- a/lib/io/compress/ostream_compressor.c +++ b/lib/io/compress/ostream_compressor.c @@ -56,7 +56,7 @@ static void comp_destroy(sqfs_object_t *obj) ostream_comp_t *comp = (ostream_comp_t *)obj; comp->cleanup(comp); - sqfs_destroy(comp->wrapped); + sqfs_drop(comp->wrapped); free(comp); } @@ -95,7 +95,7 @@ ostream_t *ostream_compressor_create(ostream_t *strm, int comp_id) sqfs_object_init(comp, comp_destroy, NULL); - comp->wrapped = strm; + comp->wrapped = sqfs_grab(strm); comp->inbuf_used = 0; base = (ostream_t *)comp; diff --git a/lib/io/uncompress/istream_compressor.c b/lib/io/uncompress/istream_compressor.c index 1c73e3a..d4e1aea 100644 --- a/lib/io/uncompress/istream_compressor.c +++ b/lib/io/uncompress/istream_compressor.c @@ -18,7 +18,7 @@ static void comp_destroy(sqfs_object_t *obj) istream_comp_t *comp = (istream_comp_t *)obj; comp->cleanup(comp); - sqfs_destroy(comp->wrapped); + sqfs_drop(comp->wrapped); free(comp); } @@ -57,7 +57,7 @@ istream_t *istream_compressor_create(istream_t *strm, int comp_id) sqfs_object_init(comp, comp_destroy, NULL); - comp->wrapped = strm; + comp->wrapped = sqfs_grab(strm); base = (istream_t *)comp; base->get_filename = comp_get_filename; diff --git a/lib/io/unix/ostream.c b/lib/io/unix/ostream.c index 6ed18e6..5ef2af2 100644 --- a/lib/io/unix/ostream.c +++ b/lib/io/unix/ostream.c @@ -163,6 +163,8 @@ ostream_t *ostream_open_stdout(void) strm->append = file_append; strm->flush = file_flush; strm->get_filename = file_get_filename; + + sqfs_object_init(file, file_destroy, NULL); return strm; fail: perror("creating file wrapper for stdout"); diff --git a/lib/sqfs/block_processor/block_processor.c b/lib/sqfs/block_processor/block_processor.c index e223718..d607437 100644 --- a/lib/sqfs/block_processor/block_processor.c +++ b/lib/sqfs/block_processor/block_processor.c @@ -186,10 +186,14 @@ static void block_processor_destroy(sqfs_object_t *base) worker_data_t *worker = proc->workers; proc->workers = worker->next; - sqfs_destroy(worker->cmp); + sqfs_drop(worker->cmp); free(worker); } + sqfs_drop(proc->frag_tbl); + sqfs_drop(proc->wr); + sqfs_drop(proc->file); + sqfs_drop(proc->uncmp); free(proc); } @@ -272,10 +276,10 @@ int sqfs_block_processor_create_ex(const sqfs_block_processor_desc_t *desc, proc->max_backlog = desc->max_backlog; proc->max_block_size = desc->max_block_size; - proc->frag_tbl = desc->tbl; - proc->wr = desc->wr; - proc->file = desc->file; - proc->uncmp = desc->uncmp; + proc->frag_tbl = sqfs_grab(desc->tbl); + proc->wr = sqfs_grab(desc->wr); + proc->file = sqfs_grab(desc->file); + proc->uncmp = sqfs_grab(desc->uncmp); proc->stats.size = sizeof(proc->stats); /* we need at least one current data block + one fragment block */ @@ -285,8 +289,8 @@ int sqfs_block_processor_create_ex(const sqfs_block_processor_desc_t *desc, /* create the thread pool */ proc->pool = thread_pool_create(desc->num_workers, process_block); if (proc->pool == NULL) { - free(proc); - return SQFS_ERROR_INTERNAL; + ret = SQFS_ERROR_INTERNAL; + goto fail_pool; } /* create the worker compressors & scratch buffer */ diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c index 1612986..a5135bc 100644 --- a/lib/sqfs/block_writer.c +++ b/lib/sqfs/block_writer.c @@ -148,6 +148,7 @@ static int align_file(block_writer_default_t *wr, sqfs_u32 flags) static void block_writer_destroy(sqfs_object_t *wr) { + sqfs_drop(((block_writer_default_t *)wr)->file); array_cleanup(&(((block_writer_default_t *)wr)->blocks)); free(wr); } @@ -224,10 +225,11 @@ sqfs_block_writer_t *sqfs_block_writer_create(sqfs_file_t *file, ((sqfs_block_writer_t *)wr)->write_data_block = write_data_block; ((sqfs_block_writer_t *)wr)->get_block_count = get_block_count; wr->flags = flags; - wr->file = file; + wr->file = sqfs_grab(file); wr->devblksz = devblksz; if (array_init(&(wr->blocks), sizeof(blk_info_t), INIT_BLOCK_COUNT)) { + sqfs_drop(wr->file); free(wr); return NULL; } diff --git a/lib/sqfs/data_reader.c b/lib/sqfs/data_reader.c index c3fc1b9..3f0cd74 100644 --- a/lib/sqfs/data_reader.c +++ b/lib/sqfs/data_reader.c @@ -131,7 +131,9 @@ static void data_reader_destroy(sqfs_object_t *obj) { sqfs_data_reader_t *data = (sqfs_data_reader_t *)obj; - sqfs_destroy(data->frag_tbl); + sqfs_drop(data->cmp); + sqfs_drop(data->file); + sqfs_drop(data->frag_tbl); free(data->data_block); free(data->frag_block); free(data); @@ -170,13 +172,14 @@ static sqfs_object_t *data_reader_copy(const sqfs_object_t *obj) data->frag_blk_size); } - /* XXX: file and cmp aren't deep-copied becaues data - doesn't own them either. */ + /* duplicate references */ + copy->file = sqfs_grab(copy->file); + copy->cmp = sqfs_grab(copy->cmp); return (sqfs_object_t *)copy; fail_fblk: free(copy->data_block); fail_dblk: - sqfs_destroy(copy->frag_tbl); + sqfs_drop(copy->frag_tbl); fail_ftbl: free(copy); return NULL; @@ -204,9 +207,9 @@ sqfs_data_reader_t *sqfs_data_reader_create(sqfs_file_t *file, return NULL; } - data->file = file; + data->file = sqfs_grab(file); data->block_size = block_size; - data->cmp = cmp; + data->cmp = sqfs_grab(cmp); return data; } diff --git a/lib/sqfs/dir_reader/dir_reader.c b/lib/sqfs/dir_reader/dir_reader.c index 38700df..d70f729 100644 --- a/lib/sqfs/dir_reader/dir_reader.c +++ b/lib/sqfs/dir_reader/dir_reader.c @@ -67,8 +67,8 @@ static void dir_reader_destroy(sqfs_object_t *obj) if (rd->flags & SQFS_DIR_READER_DOT_ENTRIES) rbtree_cleanup(&rd->dcache); - sqfs_destroy(rd->meta_inode); - sqfs_destroy(rd->meta_dir); + sqfs_drop(rd->meta_inode); + sqfs_drop(rd->meta_dir); free(rd); } @@ -97,7 +97,7 @@ static sqfs_object_t *dir_reader_copy(const sqfs_object_t *obj) return (sqfs_object_t *)copy; fail_mdir: - sqfs_destroy(copy->meta_inode); + sqfs_drop(copy->meta_inode); fail_mino: if (copy->flags & SQFS_DIR_READER_DOT_ENTRIES) rbtree_cleanup(©->dcache); @@ -152,12 +152,12 @@ sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super, if (rd->meta_dir == NULL) goto fail_mdir; - rd->super = super; + rd->super = *super; rd->flags = flags; rd->state = DIR_STATE_NONE; return rd; fail_mdir: - sqfs_destroy(rd->meta_inode); + sqfs_drop(rd->meta_inode); fail_mino: if (flags & SQFS_DIR_READER_DOT_ENTRIES) rbtree_cleanup(&rd->dcache); @@ -176,7 +176,7 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, if (flags & (~SQFS_DIR_OPEN_ALL_FLAGS)) return SQFS_ERROR_UNSUPPORTED; - ret = sqfs_readdir_state_init(&rd->it, rd->super, inode); + ret = sqfs_readdir_state_init(&rd->it, &rd->super, inode); if (ret) return ret; @@ -191,7 +191,7 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, if (dcache_find(rd, inode->base.inode_number, &rd->cur_ref)) return SQFS_ERROR_NO_ENTRY; - if (rd->cur_ref == rd->super->root_inode_ref) { + if (rd->cur_ref == rd->super.root_inode_ref) { rd->parent_ref = rd->cur_ref; } else if (dcache_find(rd, parent, &rd->parent_ref)) { return SQFS_ERROR_NO_ENTRY; @@ -291,7 +291,7 @@ int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, { int ret; - ret = sqfs_meta_reader_read_inode(rd->meta_inode, rd->super, + ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super, rd->ent_ref >> 16, rd->ent_ref & 0x0FFFF, inode); if (ret != 0) @@ -303,16 +303,16 @@ int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, sqfs_inode_generic_t **inode) { - sqfs_u64 block_start = rd->super->root_inode_ref >> 16; - sqfs_u16 offset = rd->super->root_inode_ref & 0xFFFF; + sqfs_u64 block_start = rd->super.root_inode_ref >> 16; + sqfs_u16 offset = rd->super.root_inode_ref & 0xFFFF; int ret; - ret = sqfs_meta_reader_read_inode(rd->meta_inode, rd->super, + ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super, block_start, offset, inode); if (ret != 0) return ret; - return dcache_add(rd, *inode, rd->super->root_inode_ref); + return dcache_add(rd, *inode, rd->super.root_inode_ref); } int sqfs_dir_reader_find_by_path(sqfs_dir_reader_t *rd, diff --git a/lib/sqfs/dir_reader/internal.h b/lib/sqfs/dir_reader/internal.h index 7275cd2..471d197 100644 --- a/lib/sqfs/dir_reader/internal.h +++ b/lib/sqfs/dir_reader/internal.h @@ -35,7 +35,7 @@ struct sqfs_dir_reader_t { sqfs_meta_reader_t *meta_dir; sqfs_meta_reader_t *meta_inode; - const sqfs_super_t *super; + sqfs_super_t super; sqfs_readdir_state_t it; diff --git a/lib/sqfs/dir_writer.c b/lib/sqfs/dir_writer.c index f56e0a7..d2b72df 100644 --- a/lib/sqfs/dir_writer.c +++ b/lib/sqfs/dir_writer.c @@ -130,6 +130,7 @@ static void dir_writer_destroy(sqfs_object_t *obj) { sqfs_dir_writer_t *writer = (sqfs_dir_writer_t *)obj; + sqfs_drop(writer->dm); writer_reset(writer); array_cleanup(&writer->export_tbl); free(writer); @@ -159,7 +160,7 @@ sqfs_dir_writer_t *sqfs_dir_writer_create(sqfs_meta_writer_t *dm, writer->export_tbl.size * writer->export_tbl.count); } - writer->dm = dm; + writer->dm = sqfs_grab(dm); return writer; } diff --git a/lib/sqfs/meta_reader.c b/lib/sqfs/meta_reader.c index 1b48fb8..e431d40 100644 --- a/lib/sqfs/meta_reader.c +++ b/lib/sqfs/meta_reader.c @@ -48,6 +48,10 @@ struct sqfs_meta_reader_t { static void meta_reader_destroy(sqfs_object_t *m) { + sqfs_meta_reader_t *mr = (sqfs_meta_reader_t *)m; + + sqfs_drop(mr->file); + sqfs_drop(mr->cmp); free(m); } @@ -58,10 +62,12 @@ static sqfs_object_t *meta_reader_copy(const sqfs_object_t *obj) if (copy != NULL) { memcpy(copy, m, sizeof(*m)); + + /* duplicate references */ + copy->cmp = sqfs_grab(copy->cmp); + copy->file = sqfs_grab(copy->file); } - /* XXX: cmp and file aren't deep-copied because m - doesn't own them either. */ return (sqfs_object_t *)copy; } @@ -79,8 +85,8 @@ sqfs_meta_reader_t *sqfs_meta_reader_create(sqfs_file_t *file, m->block_offset = 0xFFFFFFFFFFFFFFFFUL; m->start = start; m->limit = limit; - m->file = file; - m->cmp = cmp; + m->file = sqfs_grab(file); + m->cmp = sqfs_grab(cmp); return m; } diff --git a/lib/sqfs/meta_writer.c b/lib/sqfs/meta_writer.c index 5b8898b..bf3f426 100644 --- a/lib/sqfs/meta_writer.c +++ b/lib/sqfs/meta_writer.c @@ -71,6 +71,8 @@ static void meta_writer_destroy(sqfs_object_t *obj) free(blk); } + sqfs_drop(m->file); + sqfs_drop(m->cmp); free(m); } @@ -89,8 +91,8 @@ sqfs_meta_writer_t *sqfs_meta_writer_create(sqfs_file_t *file, sqfs_object_init(m, meta_writer_destroy, NULL); - m->cmp = cmp; - m->file = file; + m->cmp = sqfs_grab(cmp); + m->file = sqfs_grab(file); m->flags = flags; return m; } diff --git a/lib/sqfs/read_table.c b/lib/sqfs/read_table.c index 8f9bddd..c6a9bbe 100644 --- a/lib/sqfs/read_table.c +++ b/lib/sqfs/read_table.c @@ -76,12 +76,12 @@ int sqfs_read_table(sqfs_file_t *file, sqfs_compressor_t *cmp, table_size -= diff; } - sqfs_destroy(m); + sqfs_drop(m); free(locations); *out = data; return 0; fail: - sqfs_destroy(m); + sqfs_drop(m); fail_idx: free(locations); fail_data: diff --git a/lib/sqfs/write_table.c b/lib/sqfs/write_table.c index 7f1b201..6f28a75 100644 --- a/lib/sqfs/write_table.c +++ b/lib/sqfs/write_table.c @@ -74,7 +74,7 @@ int sqfs_write_table(sqfs_file_t *file, sqfs_compressor_t *cmp, /* cleanup */ ret = 0; out: - sqfs_destroy(m); + sqfs_drop(m); out_idx: free(locations); return ret; diff --git a/lib/sqfs/xattr/xattr_reader.c b/lib/sqfs/xattr/xattr_reader.c index 313da88..9e3ea76 100644 --- a/lib/sqfs/xattr/xattr_reader.c +++ b/lib/sqfs/xattr/xattr_reader.c @@ -48,33 +48,29 @@ static sqfs_object_t *xattr_reader_copy(const sqfs_object_t *obj) if (xr->kvrd != NULL) { copy->kvrd = sqfs_copy(xr->kvrd); if (copy->kvrd == NULL) - goto fail_kvrd; + goto fail; } if (xr->idrd != NULL) { copy->idrd = sqfs_copy(xr->idrd); if (copy->idrd == NULL) - goto fail_idrd; + goto fail; } if (xr->id_block_starts != NULL) { copy->id_block_starts = alloc_array(sizeof(sqfs_u64), xr->num_id_blocks); if (copy->id_block_starts == NULL) - goto fail_idblk; + goto fail; memcpy(copy->id_block_starts, xr->id_block_starts, sizeof(sqfs_u64) * xr->num_id_blocks); } return (sqfs_object_t *)copy; -fail_idblk: - if (copy->idrd != NULL) - sqfs_destroy(copy->idrd); -fail_idrd: - if (copy->kvrd != NULL) - sqfs_destroy(copy->kvrd); -fail_kvrd: +fail: + sqfs_drop(copy->idrd); + sqfs_drop(copy->kvrd); free(copy); return NULL; } @@ -83,12 +79,8 @@ static void xattr_reader_destroy(sqfs_object_t *obj) { sqfs_xattr_reader_t *xr = (sqfs_xattr_reader_t *)obj; - if (xr->kvrd != NULL) - sqfs_destroy(xr->kvrd); - - if (xr->idrd != NULL) - sqfs_destroy(xr->idrd); - + sqfs_drop(xr->kvrd); + sqfs_drop(xr->idrd); free(xr->id_block_starts); free(xr); } @@ -111,15 +103,8 @@ int sqfs_xattr_reader_load(sqfs_xattr_reader_t *xr, const sqfs_super_t *super, return SQFS_ERROR_OUT_OF_BOUNDS; /* cleanup pre-existing data */ - if (xr->idrd != NULL) { - sqfs_destroy(xr->idrd); - xr->idrd = NULL; - } - - if (xr->kvrd != NULL) { - sqfs_destroy(xr->kvrd); - xr->kvrd = NULL; - } + xr->idrd = sqfs_drop(xr->idrd); + xr->kvrd = sqfs_drop(xr->kvrd); free(xr->id_block_starts); xr->id_block_starts = NULL; @@ -174,8 +159,7 @@ int sqfs_xattr_reader_load(sqfs_xattr_reader_t *xr, const sqfs_super_t *super, xr->xattr_end = super->bytes_used; return 0; fail_idrd: - sqfs_destroy(xr->idrd); - xr->idrd = NULL; + xr->idrd = sqfs_drop(xr->idrd); fail_blocks: free(xr->id_block_starts); xr->id_block_starts = NULL; diff --git a/lib/sqfs/xattr/xattr_writer_flush.c b/lib/sqfs/xattr/xattr_writer_flush.c index 98d2619..a06463f 100644 --- a/lib/sqfs/xattr/xattr_writer_flush.c +++ b/lib/sqfs/xattr/xattr_writer_flush.c @@ -342,6 +342,6 @@ int sqfs_xattr_writer_flush(const sqfs_xattr_writer_t *xwr, sqfs_file_t *file, locations, count); out: free(locations); - sqfs_destroy(mw); + sqfs_drop(mw); return err; } diff --git a/tests/libio/get_line.c b/tests/libio/get_line.c index eec53f4..2d0f9b7 100644 --- a/tests/libio/get_line.c +++ b/tests/libio/get_line.c @@ -47,7 +47,7 @@ static void run_test_case(const line_t *lines, size_t count, ret = istream_get_line(fp, &line, &line_num, flags); TEST_ASSERT(ret > 0); - sqfs_destroy(fp); + sqfs_drop(fp); } static const line_t lines_raw[] = { diff --git a/tests/libio/uncompress.c b/tests/libio/uncompress.c index 0b877d8..4ff20b5 100644 --- a/tests/libio/uncompress.c +++ b/tests/libio/uncompress.c @@ -427,6 +427,6 @@ int main(int argc, char **argv) TEST_EQUAL_I(ret, 0); /* cleanup */ - sqfs_destroy(xfrm); + sqfs_drop(xfrm); return EXIT_SUCCESS; } diff --git a/tests/libsqfs/table.c b/tests/libsqfs/table.c index ed373a7..3e44fa3 100644 --- a/tests/libsqfs/table.c +++ b/tests/libsqfs/table.c @@ -84,7 +84,7 @@ static sqfs_s32 dummy_uncompress(sqfs_compressor_t *cmp, const sqfs_u8 *in, } static sqfs_file_t dummy_file = { - { NULL, NULL }, + { 1, NULL, NULL }, dummy_read_at, dummy_write_at, dummy_get_size, @@ -92,7 +92,7 @@ static sqfs_file_t dummy_file = { }; static sqfs_compressor_t dummy_compressor = { - { NULL, NULL }, + { 1, NULL, NULL }, NULL, NULL, NULL, @@ -100,7 +100,7 @@ static sqfs_compressor_t dummy_compressor = { }; static sqfs_compressor_t dummy_uncompressor = { - { NULL, NULL }, + { 1, NULL, NULL }, NULL, NULL, NULL, diff --git a/tests/libsqfs/xattr_benchmark.c b/tests/libsqfs/xattr_benchmark.c index 918a636..072dd06 100644 --- a/tests/libsqfs/xattr_benchmark.c +++ b/tests/libsqfs/xattr_benchmark.c @@ -113,10 +113,10 @@ int main(int argc, char **argv) } /* cleanup */ - sqfs_destroy(xwr); + sqfs_drop(xwr); return EXIT_SUCCESS; fail: - sqfs_destroy(xwr); + sqfs_drop(xwr); return EXIT_FAILURE; fail_arg: fputs("Try `xattr_benchmark --help' for more information.\n", stderr); diff --git a/tests/libsqfs/xattr_writer.c b/tests/libsqfs/xattr_writer.c index dfc8966..f7d0734 100644 --- a/tests/libsqfs/xattr_writer.c +++ b/tests/libsqfs/xattr_writer.c @@ -54,7 +54,7 @@ static sqfs_s32 dummy_compress(sqfs_compressor_t *cmp, const sqfs_u8 *in, } static sqfs_file_t dummy_file = { - { NULL, NULL }, + { 1, NULL, NULL }, NULL, dummy_write_at, dummy_get_size, @@ -62,7 +62,7 @@ static sqfs_file_t dummy_file = { }; static sqfs_compressor_t dummy_compressor = { - { NULL, NULL }, + { 1, NULL, NULL }, NULL, NULL, NULL, @@ -318,6 +318,6 @@ int main(int argc, char **argv) TEST_EQUAL_UI(offset, file_used); /* cleanup */ - sqfs_destroy(xwr); + sqfs_drop(xwr); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_big_file.c b/tests/libtar/tar_big_file.c index dbeefac..deb41f4 100644 --- a/tests/libtar/tar_big_file.c +++ b/tests/libtar/tar_big_file.c @@ -26,6 +26,6 @@ int main(int argc, char **argv) TEST_STR_EQUAL(hdr.name, "big-file.bin"); TEST_ASSERT(!hdr.unknown_record); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_fuzz.c b/tests/libtar/tar_fuzz.c index 5942426..21e6978 100644 --- a/tests/libtar/tar_fuzz.c +++ b/tests/libtar/tar_fuzz.c @@ -41,9 +41,9 @@ int main(int argc, char **argv) goto fail; } - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; fail: - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_FAILURE; } diff --git a/tests/libtar/tar_simple.c b/tests/libtar/tar_simple.c index 8879f05..cb38abb 100644 --- a/tests/libtar/tar_simple.c +++ b/tests/libtar/tar_simple.c @@ -59,6 +59,6 @@ int main(int argc, char **argv) buffer[5] = '\0'; TEST_STR_EQUAL(buffer, "test\n"); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_sparse.c b/tests/libtar/tar_sparse.c index 511c7ba..27ce053 100644 --- a/tests/libtar/tar_sparse.c +++ b/tests/libtar/tar_sparse.c @@ -75,7 +75,7 @@ static void test_case_sparse(const char *path) TEST_NULL(sparse); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); } int main(int argc, char **argv) diff --git a/tests/libtar/tar_sparse_gnu.c b/tests/libtar/tar_sparse_gnu.c index 37167d3..19ddd0a 100644 --- a/tests/libtar/tar_sparse_gnu.c +++ b/tests/libtar/tar_sparse_gnu.c @@ -47,6 +47,6 @@ int main(int argc, char **argv) TEST_NULL(sparse->next); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_target_filled.c b/tests/libtar/tar_target_filled.c index 6c83170..abc6a47 100644 --- a/tests/libtar/tar_target_filled.c +++ b/tests/libtar/tar_target_filled.c @@ -104,7 +104,6 @@ int main(int argc, char **argv) /* end of file */ TEST_ASSERT(read_header(fp, &hdr) > 0); - sqfs_destroy(fp); - + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_xattr.c b/tests/libtar/tar_xattr.c index 4b3ed21..122d1db 100644 --- a/tests/libtar/tar_xattr.c +++ b/tests/libtar/tar_xattr.c @@ -37,6 +37,6 @@ int main(int argc, char **argv) TEST_NULL(hdr.xattr->next); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libtar/tar_xattr_bin.c b/tests/libtar/tar_xattr_bin.c index b5644a1..90443a1 100644 --- a/tests/libtar/tar_xattr_bin.c +++ b/tests/libtar/tar_xattr_bin.c @@ -45,6 +45,6 @@ int main(int argc, char **argv) TEST_NULL(hdr.xattr->next); clear_header(&hdr); - sqfs_destroy(fp); + sqfs_drop(fp); return EXIT_SUCCESS; } diff --git a/tests/libutil/str_table.c b/tests/libutil/str_table.c index 9424581..d4160eb 100644 --- a/tests/libutil/str_table.c +++ b/tests/libutil/str_table.c @@ -30,7 +30,7 @@ static int read_strings(void) strings[i] = line; } - sqfs_destroy(fp); + sqfs_drop(fp); return 0; } -- cgit v1.2.3