]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: place the journaler pointer under the mds_lock 41626/head
authorXiubo Li <xiubli@redhat.com>
Fri, 14 May 2021 02:38:49 +0000 (10:38 +0800)
committerCory Snyder <csnyder@iland.com>
Tue, 1 Jun 2021 12:19:30 +0000 (08:19 -0400)
When the _recovery_thread is trying to reformat the journal, it
will delete the old journal pointer and assign with a new one,
during this the mds_lock is unlocked. That means in other threads,
such as when 'flush journal', who are using the MDSLog::journaler
pointer will potentially hit use-after-free bug.

Fixes: https://tracker.ceph.com/issues/50807
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 0c143922f8a7bad0f19a0a2c97121a470b8fcba5)

src/mds/MDLog.cc

index ee2d08cebba4728b04f82754f552848ba5b40399..2ee4c70b1790f04c3a96cf002a25b68b2127d932 100644 (file)
@@ -1088,9 +1088,9 @@ void MDLog::_recovery_thread(MDSContext *completion)
      * tolerate replaying old journals until we have to go active. Use front_journal as
      * our journaler attribute and complete */
     dout(4) << "Recovered journal " << jp.front << " in format " << front_journal->get_stream_format() << dendl;
-    journaler->set_write_error_handler(new C_MDL_WriteError(this));
     {
       std::lock_guard l(mds->mds_lock);
+      journaler->set_write_error_handler(new C_MDL_WriteError(this));
       if (mds->is_daemon_stopping()) {
         return;
       }
@@ -1273,17 +1273,14 @@ void MDLog::_reformat_journal(JournalPointer const &jp_in, Journaler *old_journa
     ceph_assert(journaler == old_journal);
     journaler = NULL;
     delete old_journal;
-  }
 
-  /* Update the pointer to reflect we're back in clean single journal state. */
-  jp.back = 0;
-  write_result = jp.save(mds->objecter);
-  ceph_assert(write_result == 0);
+    /* Update the pointer to reflect we're back in clean single journal state. */
+    jp.back = 0;
+    write_result = jp.save(mds->objecter);
+    ceph_assert(write_result == 0);
 
-  /* Reset the Journaler object to its default state */
-  dout(1) << "Journal rewrite complete, continuing with normal startup" << dendl;
-  {
-    std::lock_guard l(mds->mds_lock);
+    /* Reset the Journaler object to its default state */
+    dout(1) << "Journal rewrite complete, continuing with normal startup" << dendl;
     if (mds->is_daemon_stopping()) {
       delete new_journal;
       return;
@@ -1291,11 +1288,8 @@ void MDLog::_reformat_journal(JournalPointer const &jp_in, Journaler *old_journa
     journaler = new_journal;
     journaler->set_readonly();
     journaler->set_write_error_handler(new C_MDL_WriteError(this));
-  }
 
-  /* Trigger completion */
-  {
-    std::lock_guard l(mds->mds_lock);
+    /* Trigger completion */
     if (mds->is_daemon_stopping()) {
       return;
     }