]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
FileJournal: Fix hang in FileJournal::close() 3317/head
authorDavid Zafman <dzafman@redhat.com>
Wed, 7 Jan 2015 23:49:20 +0000 (15:49 -0800)
committerDavid Zafman <dzafman@redhat.com>
Thu, 22 Jan 2015 15:04:09 +0000 (07:04 -0800)
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 <dzafman@redhat.com>
src/os/FileJournal.cc

index 759e96219e69d518279603164e01617de9175780..fa0bb311f14af8db24e48aedb0258e6ee473fc0f 100644 (file)
@@ -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);