diff options
author | Xiubo Li <xiubli@redhat.com> | 2021-05-14 04:38:49 +0200 |
---|---|---|
committer | Xiubo Li <xiubli@redhat.com> | 2021-05-14 04:45:25 +0200 |
commit | 0c143922f8a7bad0f19a0a2c97121a470b8fcba5 (patch) | |
tree | 7c77a1fd449480268ef948281df73db4f6575176 /src/mds/MDLog.cc | |
parent | Merge pull request #41245 from tchaikov/wip-doc-confval-ext (diff) | |
download | ceph-0c143922f8a7bad0f19a0a2c97121a470b8fcba5.tar.xz ceph-0c143922f8a7bad0f19a0a2c97121a470b8fcba5.zip |
mds: place the journaler pointer under the mds_lock
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>
Diffstat (limited to 'src/mds/MDLog.cc')
-rw-r--r-- | src/mds/MDLog.cc | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc index 1fc4b58f17e..f438d6ba7ed 100644 --- a/src/mds/MDLog.cc +++ b/src/mds/MDLog.cc @@ -1086,9 +1086,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; } @@ -1271,17 +1271,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; @@ -1289,11 +1286,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; } |