From 07eadc453cfe0af358d726616b60612d94ca8736 Mon Sep 17 00:00:00 2001 From: David Zafman Date: Wed, 7 Jan 2015 15:49:20 -0800 Subject: [PATCH] FileJournal: Fix hang in FileJournal::close() On FileStore::umount() when stopping and in ENOSPC condition, don't let write_thread_entry() get stuck in commit_cond.Wait(write_lock). Fixes: #10474 Signed-off-by: David Zafman --- src/os/FileJournal.cc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/os/FileJournal.cc b/src/os/FileJournal.cc index 759e96219e69..fa0bb311f14a 100644 --- a/src/os/FileJournal.cc +++ b/src/os/FileJournal.cc @@ -636,6 +636,9 @@ void FileJournal::stop_writer() Mutex::Locker p(writeq_lock); write_stop = true; writeq_cond.Signal(); + // Doesn't hurt to signal commit_cond in case thread is waiting there + // and caller didn't use committed_thru() first. + commit_cond.Signal(); } write_thread.join(); @@ -1181,11 +1184,23 @@ void FileJournal::write_thread_entry() bufferlist bl; int r = prepare_multi_write(bl, orig_ops, orig_bytes); + // Don't care about journal full if stoppping, so drop queue and + // possibly let header get written and loop above to notice stop if (r == -ENOSPC) { - dout(20) << "write_thread_entry full, going to sleep (waiting for commit)" << dendl; - commit_cond.Wait(write_lock); - dout(20) << "write_thread_entry woke up" << dendl; - continue; + if (write_stop) { + dout(20) << "write_thread_entry full and stopping, throw out queue and finish up" << dendl; + while (!writeq_empty()) { + put_throttle(1, peek_write().bl.length()); + pop_write(); + } + print_header(); + r = 0; + } else { + dout(20) << "write_thread_entry full, going to sleep (waiting for commit)" << dendl; + commit_cond.Wait(write_lock); + dout(20) << "write_thread_entry woke up" << dendl; + continue; + } } assert(r == 0); -- 2.47.3