diff --git a/src/flb_fstore.c b/src/flb_fstore.c index e02dbcd18ea..84b46fc1df2 100644 --- a/src/flb_fstore.c +++ b/src/flb_fstore.c @@ -215,12 +215,33 @@ struct flb_fstore_file *flb_fstore_file_get(struct flb_fstore *fs, * Set a file to inactive mode. Inactive means just to remove the reference * from the list. */ +static int chunk_is_linked_to_stream(struct flb_fstore_file *fsf) +{ + struct mk_list *head; + struct cio_chunk *chunk; + + if (fsf == NULL || fsf->chunk == NULL || fsf->stream == NULL) { + return FLB_FALSE; + } + + mk_list_foreach(head, &fsf->stream->chunks) { + chunk = mk_list_entry(head, struct cio_chunk, _head); + + if (chunk == fsf->chunk) { + return FLB_TRUE; + } + } + + return FLB_FALSE; +} + int flb_fstore_file_inactive(struct flb_fstore *fs, struct flb_fstore_file *fsf) { /* close the Chunk I/O reference, but don't delete the real file */ - if (fsf->chunk) { + if (chunk_is_linked_to_stream(fsf) == FLB_TRUE) { cio_chunk_close(fsf->chunk, CIO_FALSE); + fsf->chunk = NULL; } /* release */ @@ -239,7 +260,10 @@ int flb_fstore_file_delete(struct flb_fstore *fs, struct flb_fstore_file *fsf) { /* close the Chunk I/O reference, but don't delete it the real file */ - cio_chunk_close(fsf->chunk, CIO_TRUE); + if (chunk_is_linked_to_stream(fsf) == FLB_TRUE) { + cio_chunk_close(fsf->chunk, CIO_TRUE); + fsf->chunk = NULL; + } /* release */ mk_list_del(&fsf->_head); @@ -415,6 +439,7 @@ static int map_chunks(struct flb_fstore *ctx, struct flb_fstore_stream *fs_strea return -1; } + fsf->stream = stream; fsf->chunk = chunk; /* load metadata */ diff --git a/tests/internal/fstore.c b/tests/internal/fstore.c index 1f4de61b567..8979378b400 100644 --- a/tests/internal/fstore.c +++ b/tests/internal/fstore.c @@ -30,6 +30,7 @@ #include #include +#include #ifdef FLB_SYSTEM_WINDOWS /* Not yet implemented! */ @@ -78,7 +79,57 @@ void cb_all() flb_fstore_destroy(fs); } +void cb_delete_after_external_close() +{ + int ret; + struct stat st_data; + struct flb_fstore *fs; + struct flb_fstore_stream *st; + struct flb_fstore_file *fsf; + struct cio_chunk *chunk; + + cio_utils_recursive_delete(FSF_STORE_PATH); + + fs = flb_fstore_create(FSF_STORE_PATH, FLB_FSTORE_FS); + TEST_CHECK(fs != NULL); + if (!fs) { + return; + } + + st = flb_fstore_stream_create(fs, "abc"); + TEST_CHECK(st != NULL); + if (!st) { + flb_fstore_destroy(fs); + return; + } + + fsf = flb_fstore_file_create(fs, st, "example.txt", 100); + TEST_CHECK(fsf != NULL); + if (!fsf) { + flb_fstore_destroy(fs); + return; + } + + chunk = fsf->chunk; + TEST_CHECK(chunk != NULL); + if (!chunk) { + flb_fstore_destroy(fs); + return; + } + + cio_chunk_close(chunk, CIO_TRUE); + + ret = stat(FSF_STORE_PATH "/abc/example.txt", &st_data); + TEST_CHECK(ret == -1 && errno == ENOENT); + + ret = flb_fstore_file_delete(fs, fsf); + TEST_CHECK(ret == 0); + + flb_fstore_destroy(fs); +} + TEST_LIST = { { "all" , cb_all}, + { "delete_after_external_close", cb_delete_after_external_close}, { NULL } };