fix lots of memory leaks

This commit is contained in:
2025-02-23 22:00:50 +00:00
parent 9aeae388a4
commit 8571a4bfec
8 changed files with 154 additions and 23 deletions

View File

@@ -81,6 +81,18 @@ void b_tree_init(
tree->tree_order = order; tree->tree_order = order;
} }
void b_tree_finish(struct b_tree *tree)
{
b_queue_iterator it;
b_queue_iterator_begin(&tree->tree_cache, &it);
while (b_queue_iterator_is_valid(&it)) {
struct cache_entry *entry
= b_unbox(struct cache_entry, it.entry, c_entry);
b_queue_iterator_erase(&it);
free(entry);
}
}
static long tree_alloc_id(struct b_tree *tree) static long tree_alloc_id(struct b_tree *tree)
{ {
return tree->tree_ops->tree_alloc_node(tree); return tree->tree_ops->tree_alloc_node(tree);

View File

@@ -54,6 +54,7 @@ extern void b_tree_init(
unsigned int node_size, unsigned int node_size,
unsigned int entry_size, unsigned int entry_size,
unsigned int order); unsigned int order);
extern void b_tree_finish(struct b_tree *tree);
extern int b_tree_put(struct b_tree *tree, const b_tree_node_entry *entry); extern int b_tree_put(struct b_tree *tree, const b_tree_node_entry *entry);
extern int b_tree_get(struct b_tree *tree, b_tree_node_entry *entry); extern int b_tree_get(struct b_tree *tree, b_tree_node_entry *entry);

View File

@@ -54,6 +54,20 @@ void cluster_cache_finish(struct cluster_cache *cache)
if (cache->c_storage) { if (cache->c_storage) {
b_file_release(cache->c_storage); b_file_release(cache->c_storage);
} }
b_btree_iterator it;
b_btree_iterator_begin(&cache->c_entries, &it);
while (b_btree_iterator_is_valid(&it)) {
struct cluster_cache_entry *entry
= b_unbox(struct cluster_cache_entry, it.node, e_node);
b_btree_iterator_erase(&it);
if (entry->e_data) {
free(entry->e_data);
}
free(entry);
}
} }
static enum ec3_status evict_one_cache_data( static enum ec3_status evict_one_cache_data(

View File

@@ -219,6 +219,7 @@ void cluster_table_init_empty_table(struct cluster_table *table)
void cluster_table_finish(struct cluster_table *table) void cluster_table_finish(struct cluster_table *table)
{ {
b_tree_finish(&table->t_base);
} }
static void encode_cluster(const struct cluster *in, struct ec3_cluster *out) static void encode_cluster(const struct cluster *in, struct ec3_cluster *out)

View File

@@ -349,20 +349,23 @@ enum ec3_status ec3_image_ioctx_open(
b_path *image_path = b_path_create_from_cstr(path); b_path *image_path = b_path_create_from_cstr(path);
b_file_info image_info; b_file_info image_info;
enum b_status status = b_path_stat(image_path, &image_info); enum b_status status = b_path_stat(image_path, &image_info);
enum ec3_status status2 = EC3_ERR_NO_ENTRY;
if ((status == B_ERR_NO_ENTRY) && (mode & EC3_IMAGE_IO_WRITE)) { if ((status == B_ERR_NO_ENTRY) && (mode & EC3_IMAGE_IO_WRITE)) {
return open_image_create(image_path, mode, param, out); status2 = open_image_create(image_path, mode, param, out);
} }
if ((status == B_SUCCESS) && (mode & EC3_IMAGE_IO_WRITE)) { if ((status == B_SUCCESS) && (mode & EC3_IMAGE_IO_WRITE)) {
return open_image_rw(image_path, mode, out); status2 = open_image_rw(image_path, mode, out);
} }
if ((status == B_SUCCESS) && (mode & EC3_IMAGE_IO_READ)) { if ((status == B_SUCCESS) && (mode & EC3_IMAGE_IO_READ)) {
return open_image_ro(image_path, mode, out); status2 = open_image_ro(image_path, mode, out);
} }
return EC3_ERR_NO_ENTRY; b_path_release(image_path);
return status2;
} }
static void destroy_image_ioctx(struct ec3_image_ioctx *image) static void destroy_image_ioctx(struct ec3_image_ioctx *image)
@@ -507,6 +510,19 @@ enum ec3_status ec3_image_ioctx_close(struct ec3_image_ioctx *image)
} }
} }
b_btree_iterator it;
b_btree_iterator_begin(&image->io_opened_tags, &it);
while (b_btree_iterator_is_valid(&it)) {
struct ec3_tag_ioctx *tag
= b_unbox(struct ec3_tag_ioctx, it.node, io_node);
b_btree_iterator_erase(&it);
/* disable write access so that ec3_tag_ioctx_close will
* actually destroy the ioctx */
tag->io_mode &= ~EC3_TAG_IO_WRITE;
ec3_tag_ioctx_close(tag);
}
shadow_image_finish(image, &shadow); shadow_image_finish(image, &shadow);
destroy_image_ioctx(image); destroy_image_ioctx(image);

View File

@@ -100,6 +100,21 @@ extern enum ec3_status ec3_pipeline_create(
void ec3_pipeline_destroy(struct ec3_pipeline *p) void ec3_pipeline_destroy(struct ec3_pipeline *p)
{ {
b_queue_iterator it;
b_queue_iterator_begin(&p->p_stages, &it);
while (b_queue_iterator_is_valid(&it)) {
struct ec3_pipeline_stage *stage
= b_unbox(struct ec3_pipeline_stage, it.entry, s_entry);
b_queue_iterator_erase(&it);
if (stage->s_buf) {
free(stage->s_buf);
}
free(stage);
}
free(p);
} }
enum ec3_status ec3_pipeline_encode_cluster( enum ec3_status ec3_pipeline_encode_cluster(

View File

@@ -143,17 +143,11 @@ static enum ec3_status align_data_file(
return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE); return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE);
} }
enum ec3_status shadow_image_finish( static enum ec3_status write_cluster_table(struct shadow_image *shadow)
struct ec3_image_ioctx *image,
struct shadow_image *shadow)
{ {
b_status status = B_SUCCESS; size_t nr_read = 0, nr_written = 0;
size_t nr_read = 0; enum b_status status = B_SUCCESS;
size_t nr_written = 0;
align_data_file(shadow, 16);
size_t cluster_table_offset = shadow->img_nr_bytes;
struct ec3_cluster_group *buf = malloc(sizeof *buf); struct ec3_cluster_group *buf = malloc(sizeof *buf);
if (!buf) { if (!buf) {
return EC3_ERR_NO_MEMORY; return EC3_ERR_NO_MEMORY;
@@ -205,9 +199,14 @@ enum ec3_status shadow_image_finish(
return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE); return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE);
} }
align_data_file(shadow, 16); return EC3_SUCCESS;
}
static enum ec3_status write_extent_table(struct shadow_image *shadow)
{
size_t nr_read = 0, nr_written = 0;
b_status status = B_SUCCESS;
size_t extent_table_offset = shadow->img_nr_bytes;
const struct ec3_extent_info *extents const struct ec3_extent_info *extents
= b_buffer_ptr(shadow->img_extent_table); = b_buffer_ptr(shadow->img_extent_table);
size_t nr_extents = b_buffer_get_size(shadow->img_extent_table); size_t nr_extents = b_buffer_get_size(shadow->img_extent_table);
@@ -236,11 +235,17 @@ enum ec3_status shadow_image_finish(
shadow->img_nr_bytes += sizeof extent; shadow->img_nr_bytes += sizeof extent;
} }
align_data_file(shadow, 16); return EC3_SUCCESS;
}
static enum ec3_status write_tag_table(struct shadow_image *shadow)
{
size_t nr_read = 0, nr_written = 0;
b_status status = B_SUCCESS;
size_t tag_table_offset = shadow->img_nr_bytes;
const struct ec3_tag_info *tags = b_buffer_ptr(shadow->img_tag_table); const struct ec3_tag_info *tags = b_buffer_ptr(shadow->img_tag_table);
size_t nr_tags = b_buffer_get_size(shadow->img_tag_table); size_t nr_tags = b_buffer_get_size(shadow->img_tag_table);
for (size_t i = 0; i < nr_tags; i++) { for (size_t i = 0; i < nr_tags; i++) {
struct ec3_tag_table_entry tag; struct ec3_tag_table_entry tag;
encode_tag(&tags[i], &tag); encode_tag(&tags[i], &tag);
@@ -265,6 +270,39 @@ enum ec3_status shadow_image_finish(
shadow->img_nr_bytes += sizeof tag; shadow->img_nr_bytes += sizeof tag;
} }
return EC3_SUCCESS;
}
enum ec3_status shadow_image_finish(
struct ec3_image_ioctx *image,
struct shadow_image *shadow)
{
enum ec3_status status = EC3_SUCCESS;
size_t nr_tags = b_buffer_get_size(shadow->img_tag_table);
size_t nr_extents = b_buffer_get_size(shadow->img_extent_table);
align_data_file(shadow, 16);
size_t cluster_table_offset = shadow->img_nr_bytes;
status = write_cluster_table(shadow);
if (status != EC3_SUCCESS) {
return status;
}
align_data_file(shadow, 16);
size_t extent_table_offset = shadow->img_nr_bytes;
status = write_extent_table(shadow);
if (status != EC3_SUCCESS) {
return status;
}
align_data_file(shadow, 16);
size_t tag_table_offset = shadow->img_nr_bytes;
status = write_tag_table(shadow);
if (status != EC3_SUCCESS) {
return status;
}
struct ec3_image_info image_info = {0}; struct ec3_image_info image_info = {0};
memcpy(&image_info, &image->io_header, sizeof image_info); memcpy(&image_info, &image->io_header, sizeof image_info);
@@ -280,15 +318,16 @@ enum ec3_status shadow_image_finish(
struct ec3_header header; struct ec3_header header;
encode_header(&image_info, &header); encode_header(&image_info, &header);
status = b_file_write( size_t nr_written = 0;
b_status status2 = b_file_write(
shadow->img_f_data, shadow->img_f_data,
0, 0,
sizeof header, sizeof header,
&header, &header,
&nr_written); &nr_written);
if (!B_OK(status)) { if (!B_OK(status2)) {
return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE); return ec3_status_from_b_status(status2, EC3_ERR_IO_FAILURE);
} }
if (nr_written < sizeof header) { if (nr_written < sizeof header) {
@@ -297,9 +336,7 @@ enum ec3_status shadow_image_finish(
b_file_swap_shadow(image->io_main, shadow->img_f_data); b_file_swap_shadow(image->io_main, shadow->img_f_data);
cluster_table_finish(&shadow->img_cluster_table); shadow_image_cancel(shadow);
b_file_release(shadow->img_f_data);
b_file_release(shadow->img_f_cluster_table);
return EC3_SUCCESS; return EC3_SUCCESS;
} }
@@ -308,6 +345,16 @@ void shadow_image_cancel(struct shadow_image *shadow)
{ {
cluster_table_finish(&shadow->img_cluster_table); cluster_table_finish(&shadow->img_cluster_table);
if (shadow->img_extent_table) {
b_buffer_release(shadow->img_extent_table);
shadow->img_extent_table = NULL;
}
if (shadow->img_tag_table) {
b_buffer_release(shadow->img_tag_table);
shadow->img_tag_table = NULL;
}
if (shadow->img_f_data) { if (shadow->img_f_data) {
b_file_release(shadow->img_f_data); b_file_release(shadow->img_f_data);
} }

View File

@@ -27,6 +27,8 @@ static enum ec3_status init_seq_write_temp_files(struct ec3_tag_ioctx *tag)
} }
cluster_table_init(&tag->io_cluster_table, tag->io_f_cluster_table, 0); cluster_table_init(&tag->io_cluster_table, tag->io_f_cluster_table, 0);
cluster_table_init_empty_table(&tag->io_cluster_table);
return EC3_SUCCESS; return EC3_SUCCESS;
} }
@@ -79,8 +81,14 @@ enum ec3_status ec3_tag_ioctx_close(struct ec3_tag_ioctx *tag)
enum ec3_tag_ioctx_mode mode = tag->io_mode; enum ec3_tag_ioctx_mode mode = tag->io_mode;
tag->io_mode |= EC3_TAG_IO_CLOSED; tag->io_mode |= EC3_TAG_IO_CLOSED;
if (tag->io_f_image) {
b_file_release(tag->io_f_image);
tag->io_f_image = NULL;
}
if (tag->io_cluster_buf) { if (tag->io_cluster_buf) {
free(tag->io_cluster_buf); free(tag->io_cluster_buf);
tag->io_cluster_buf = NULL;
} }
if (mode & EC3_TAG_IO_WRITE) { if (mode & EC3_TAG_IO_WRITE) {
@@ -88,6 +96,23 @@ enum ec3_status ec3_tag_ioctx_close(struct ec3_tag_ioctx *tag)
return EC3_SUCCESS; return EC3_SUCCESS;
} }
if (tag->io_pipeline) {
ec3_pipeline_destroy(tag->io_pipeline);
tag->io_pipeline = NULL;
}
if (tag->io_f_data) {
b_file_release(tag->io_f_data);
tag->io_f_data = NULL;
}
if (tag->io_f_cluster_table) {
b_file_release(tag->io_f_cluster_table);
tag->io_f_cluster_table = NULL;
}
cluster_cache_finish(&tag->io_cache);
cluster_table_finish(&tag->io_cluster_table);
b_btree_delete(&tag->io_parent->io_opened_tags, &tag->io_node); b_btree_delete(&tag->io_parent->io_opened_tags, &tag->io_node);
free(tag); free(tag);