diff --git a/src/core/file.cc b/src/core/file.cc index 2f68645e1ea..597326fdc12 100644 --- a/src/core/file.cc +++ b/src/core/file.cc @@ -498,7 +498,10 @@ append_challenged_posix_file_impl::append_challenged_posix_file_impl(int fd, ope append_challenged_posix_file_impl::~append_challenged_posix_file_impl() { // If the file has not been closed we risk having running tasks // that will try to access freed memory. - assert(_closing_state == state::closed); + // + // It is safe to destory it if nothing is queued. + // Note that posix_file_impl::~posix_file_impl auto-closes the file descriptor. + assert(_q.empty() && _logical_size == _committed_size); } bool diff --git a/tests/unit/file_io_test.cc b/tests/unit/file_io_test.cc index eec328bf549..00c77d2a1ba 100644 --- a/tests/unit/file_io_test.cc +++ b/tests/unit/file_io_test.cc @@ -676,3 +676,38 @@ SEASTAR_TEST_CASE(test_nowait_flag_correctness) { } }); } + +SEASTAR_TEST_CASE(test_destruct_just_constructed_append_challenged_file) { + return tmp_dir::do_with_thread([] (tmp_dir& t) { + sstring filename = (t.get_path() / "testfile.tmp").native(); + auto oflags = open_flags::rw | open_flags::create; + auto f = open_file_dma(filename, oflags).get0(); + }); +} + +SEASTAR_TEST_CASE(test_destruct_append_challenged_file_after_write) { + return tmp_dir::do_with_thread([] (tmp_dir& t) { + sstring filename = (t.get_path() / "testfile.tmp").native(); + auto buf = allocate_aligned_buffer(4096, 4096); + std::fill(buf.get(), buf.get() + 4096, 0); + + auto f = open_file_dma(filename, open_flags::rw | open_flags::create).get0(); + f.dma_write(0, buf.get(), 4096).get(); + }); +} + +SEASTAR_TEST_CASE(test_destruct_append_challenged_file_after_read) { + return tmp_dir::do_with_thread([] (tmp_dir& t) { + sstring filename = (t.get_path() / "testfile.tmp").native(); + auto buf = allocate_aligned_buffer(4096, 4096); + std::fill(buf.get(), buf.get() + 4096, 0); + + auto f = open_file_dma(filename, open_flags::rw | open_flags::create).get0(); + f.dma_write(0, buf.get(), 4096).get(); + f.flush().get0(); + f.close().get(); + + f = open_file_dma(filename, open_flags::rw).get0(); + f.dma_read(0, buf.get(), 4096).get(); + }); +}