diff --git a/src/b-tree.c b/src/b-tree.c index ad2b3e7..af89802 100644 --- a/src/b-tree.c +++ b/src/b-tree.c @@ -81,6 +81,18 @@ void b_tree_init( 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) { return tree->tree_ops->tree_alloc_node(tree); diff --git a/src/b-tree.h b/src/b-tree.h index f5fdf17..7f85c79 100644 --- a/src/b-tree.h +++ b/src/b-tree.h @@ -54,6 +54,7 @@ extern void b_tree_init( unsigned int node_size, unsigned int entry_size, 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_get(struct b_tree *tree, b_tree_node_entry *entry); diff --git a/src/cluster-cache.c b/src/cluster-cache.c index cf5c645..e7122ab 100644 --- a/src/cluster-cache.c +++ b/src/cluster-cache.c @@ -54,6 +54,20 @@ void cluster_cache_finish(struct cluster_cache *cache) if (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( diff --git a/src/cluster-table.c b/src/cluster-table.c index a1ce0f9..37fede5 100644 --- a/src/cluster-table.c +++ b/src/cluster-table.c @@ -219,6 +219,7 @@ void cluster_table_init_empty_table(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) diff --git a/src/image.c b/src/image.c index 897ae92..fe2b8ca 100644 --- a/src/image.c +++ b/src/image.c @@ -349,20 +349,23 @@ enum ec3_status ec3_image_ioctx_open( b_path *image_path = b_path_create_from_cstr(path); b_file_info 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)) { - 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)) { - 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)) { - 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) @@ -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); destroy_image_ioctx(image); diff --git a/src/pipeline.c b/src/pipeline.c index b705e56..24ccb73 100644 --- a/src/pipeline.c +++ b/src/pipeline.c @@ -100,6 +100,21 @@ extern enum ec3_status ec3_pipeline_create( 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( diff --git a/src/shadow-image.c b/src/shadow-image.c index 5998ca8..7aef0c9 100644 --- a/src/shadow-image.c +++ b/src/shadow-image.c @@ -143,17 +143,11 @@ static enum ec3_status align_data_file( return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE); } -enum ec3_status shadow_image_finish( - struct ec3_image_ioctx *image, - struct shadow_image *shadow) +static enum ec3_status write_cluster_table(struct shadow_image *shadow) { - b_status status = B_SUCCESS; - size_t nr_read = 0; - size_t nr_written = 0; + size_t nr_read = 0, nr_written = 0; + enum b_status status = B_SUCCESS; - align_data_file(shadow, 16); - - size_t cluster_table_offset = shadow->img_nr_bytes; struct ec3_cluster_group *buf = malloc(sizeof *buf); if (!buf) { 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); } - 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 = b_buffer_ptr(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; } - 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); size_t nr_tags = b_buffer_get_size(shadow->img_tag_table); + for (size_t i = 0; i < nr_tags; i++) { struct ec3_tag_table_entry tag; encode_tag(&tags[i], &tag); @@ -265,6 +270,39 @@ enum ec3_status shadow_image_finish( 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}; memcpy(&image_info, &image->io_header, sizeof image_info); @@ -280,15 +318,16 @@ enum ec3_status shadow_image_finish( struct ec3_header 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, 0, sizeof header, &header, &nr_written); - if (!B_OK(status)) { - return ec3_status_from_b_status(status, EC3_ERR_IO_FAILURE); + if (!B_OK(status2)) { + return ec3_status_from_b_status(status2, EC3_ERR_IO_FAILURE); } 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); - cluster_table_finish(&shadow->img_cluster_table); - b_file_release(shadow->img_f_data); - b_file_release(shadow->img_f_cluster_table); + shadow_image_cancel(shadow); return EC3_SUCCESS; } @@ -308,6 +345,16 @@ void shadow_image_cancel(struct shadow_image *shadow) { 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) { b_file_release(shadow->img_f_data); } diff --git a/src/tag.c b/src/tag.c index 15c3ce7..0582c9a 100644 --- a/src/tag.c +++ b/src/tag.c @@ -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_empty_table(&tag->io_cluster_table); + 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; 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) { free(tag->io_cluster_buf); + tag->io_cluster_buf = NULL; } 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; } + 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); free(tag);