diff options
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; } |