fix lots of memory leaks
This commit is contained in:
12
src/b-tree.c
12
src/b-tree.c
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
24
src/image.c
24
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_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);
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/tag.c
25
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(&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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user