aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2022-12-04 01:33:45 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-19 16:24:56 +0100
commit47f24f2a8faf71395a1d054e9823beb000442cce (patch)
treedd01d8b69125b3dda444c9b92437ad0c5a0af9bc /lib/sqfs
parent4160b50a0b4c51f8b7191928cdf38d9fb0147fe2 (diff)
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 <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs')
-rw-r--r--lib/sqfs/block_processor/block_processor.c18
-rw-r--r--lib/sqfs/block_writer.c4
-rw-r--r--lib/sqfs/data_reader.c15
-rw-r--r--lib/sqfs/dir_reader/dir_reader.c24
-rw-r--r--lib/sqfs/dir_reader/internal.h2
-rw-r--r--lib/sqfs/dir_writer.c3
-rw-r--r--lib/sqfs/meta_reader.c14
-rw-r--r--lib/sqfs/meta_writer.c6
-rw-r--r--lib/sqfs/read_table.c4
-rw-r--r--lib/sqfs/write_table.c2
-rw-r--r--lib/sqfs/xattr/xattr_reader.c38
-rw-r--r--lib/sqfs/xattr/xattr_writer_flush.c2
12 files changed, 67 insertions, 65 deletions
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(&copy->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;
}