From: Jason Dillaman Date: Thu, 18 Feb 2016 16:28:52 +0000 (-0500) Subject: librbd: differentiate journal replay flush vs shut down X-Git-Tag: v10.1.0~350^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1cfd965815555bf59b17019adcbf8d64ecdb4c12;p=ceph.git librbd: differentiate journal replay flush vs shut down Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index a5976716171f..5bd1759864e0 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -629,13 +629,13 @@ void Journal::handle_replay_complete(int r) { transition_state(STATE_FLUSHING_RESTART, r); m_lock.Unlock(); - m_journal_replay->flush(create_context_callback< + m_journal_replay->shut_down(create_context_callback< Journal, &Journal::handle_flushing_restart>(this)); } else { transition_state(STATE_FLUSHING_REPLAY, 0); m_lock.Unlock(); - m_journal_replay->flush(create_context_callback< + m_journal_replay->shut_down(create_context_callback< Journal, &Journal::handle_flushing_replay>(this)); } } @@ -665,7 +665,7 @@ void Journal::handle_replay_process_safe(ReplayEntry replay_entry, int r) { m_journaler->stop_replay(); transition_state(STATE_FLUSHING_RESTART, r); - m_journal_replay->flush(create_context_callback< + m_journal_replay->shut_down(create_context_callback< Journal, &Journal::handle_flushing_restart>(this)); return; } else if (m_state == STATE_FLUSHING_REPLAY) { diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc index 0db4bb3da6c0..64b5fe9d92a7 100644 --- a/src/librbd/journal/Replay.cc +++ b/src/librbd/journal/Replay.cc @@ -66,7 +66,7 @@ void Replay::process(bufferlist::iterator *it, Context *on_ready, } template -void Replay::flush(Context *on_finish) { +void Replay::shut_down(Context *on_finish) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << this << " " << __func__ << dendl; @@ -110,6 +110,19 @@ void Replay::flush(Context *on_finish) { } } +template +void Replay::flush(Context *on_finish) { + AioCompletion *aio_comp; + { + Mutex::Locker locker(m_lock); + aio_comp = create_aio_flush_completion( + nullptr, util::create_async_context_callback(m_image_ctx, on_finish)); + } + + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + AioImageRequest::aio_flush(&m_image_ctx, aio_comp); +} + template void Replay::replay_op_ready(uint64_t op_tid, Context *on_resume) { CephContext *cct = m_image_ctx.cct; diff --git a/src/librbd/journal/Replay.h b/src/librbd/journal/Replay.h index c8c58cbe2d2a..ad08208fd5ca 100644 --- a/src/librbd/journal/Replay.h +++ b/src/librbd/journal/Replay.h @@ -34,6 +34,8 @@ public: ~Replay(); void process(bufferlist::iterator *it, Context *on_ready, Context *on_safe); + + void shut_down(Context *on_finish); void flush(Context *on_finish); void replay_op_ready(uint64_t op_tid, Context *on_resume); diff --git a/src/test/librbd/journal/test_mock_Replay.cc b/src/test/librbd/journal/test_mock_Replay.cc index 174f52bf88e2..43c35396431d 100644 --- a/src/test/librbd/journal/test_mock_Replay.cc +++ b/src/test/librbd/journal/test_mock_Replay.cc @@ -191,6 +191,12 @@ public: return ctx.wait(); } + int when_shut_down(MockJournalReplay &mock_journal_replay) { + C_SaferCond ctx; + mock_journal_replay.shut_down(&ctx); + return ctx.wait(); + } + void when_replay_op_ready(MockJournalReplay &mock_journal_replay, uint64_t op_tid, Context *on_resume) { mock_journal_replay.replay_op_ready(op_tid, on_resume); @@ -227,7 +233,7 @@ TEST_F(TestMockJournalReplay, AioDiscard) { ASSERT_EQ(0, on_ready.wait()); expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0); - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); ASSERT_EQ(0, on_safe.wait()); } @@ -255,7 +261,7 @@ TEST_F(TestMockJournalReplay, AioWrite) { ASSERT_EQ(0, on_ready.wait()); expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0); - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); ASSERT_EQ(0, on_safe.wait()); } @@ -281,7 +287,7 @@ TEST_F(TestMockJournalReplay, AioFlush) { when_complete(mock_image_ctx, aio_comp, 0); ASSERT_EQ(0, on_safe.wait()); - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); ASSERT_EQ(0, on_ready.wait()); } @@ -309,7 +315,7 @@ TEST_F(TestMockJournalReplay, IOError) { ASSERT_EQ(-EINVAL, on_safe.wait()); expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0); - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); ASSERT_EQ(0, on_ready.wait()); } @@ -349,7 +355,7 @@ TEST_F(TestMockJournalReplay, SoftFlushIO) { ASSERT_EQ(0, on_safe.wait()); } - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); } TEST_F(TestMockJournalReplay, PauseIO) { @@ -392,7 +398,33 @@ TEST_F(TestMockJournalReplay, PauseIO) { ASSERT_EQ(0, on_safe.wait()); } + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); +} + +TEST_F(TestMockJournalReplay, Flush) { + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockImageCtx mock_image_ctx(*ictx); + MockJournalReplay mock_journal_replay(mock_image_ctx); + MockAioImageRequest mock_aio_image_request; + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + AioCompletion *aio_comp; + C_SaferCond on_ready; + C_SaferCond on_safe; + expect_aio_discard(mock_aio_image_request, &aio_comp, 123, 456); + when_process(mock_journal_replay, + EventEntry{AioDiscardEvent(123, 456)}, + &on_ready, &on_safe); + + when_complete(mock_image_ctx, aio_comp, 0); + ASSERT_EQ(0, on_ready.wait()); + + expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0); ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, on_safe.wait()); } TEST_F(TestMockJournalReplay, MissingOpFinishEvent) { @@ -411,7 +443,7 @@ TEST_F(TestMockJournalReplay, MissingOpFinishEvent) { ASSERT_EQ(0, on_ready.wait()); - ASSERT_EQ(0, when_flush(mock_journal_replay)); + ASSERT_EQ(0, when_shut_down(mock_journal_replay)); ASSERT_EQ(-ERESTART, on_safe.wait()); } diff --git a/src/test/librbd/test_mock_Journal.cc b/src/test/librbd/test_mock_Journal.cc index c849e6084c77..483b0a05db29 100644 --- a/src/test/librbd/test_mock_Journal.cc +++ b/src/test/librbd/test_mock_Journal.cc @@ -198,7 +198,7 @@ struct MockReplay { s_instance = this; } - MOCK_METHOD1(flush, void(Context *)); + MOCK_METHOD1(shut_down, void(Context *)); MOCK_METHOD3(process, void(bufferlist::iterator*, Context *, Context *)); MOCK_METHOD2(replay_op_ready, void(uint64_t, Context *)); }; @@ -210,8 +210,8 @@ public: return new Replay(); } - void flush(Context *on_finish) { - MockReplay::get_instance().flush(on_finish); + void shut_down(Context *on_finish) { + MockReplay::get_instance().shut_down(on_finish); } void process(bufferlist::iterator *it, Context *on_ready, @@ -308,9 +308,9 @@ public: EXPECT_CALL(mock_journaler, stop_replay()); } - void expect_flush_replay(MockImageCtx &mock_image_ctx, - MockJournalReplay &mock_journal_replay, int r) { - EXPECT_CALL(mock_journal_replay, flush(_)) + void expect_shut_down_replay(MockImageCtx &mock_image_ctx, + MockJournalReplay &mock_journal_replay, int r) { + EXPECT_CALL(mock_journal_replay, shut_down(_)) .WillOnce(Invoke([this, &mock_image_ctx, r](Context *on_flush) { this->commit_replay(mock_image_ctx, on_flush, r);})); } @@ -426,7 +426,7 @@ public: MockJournalReplay mock_journal_replay; expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_committed(mock_journaler, 0); expect_start_append(mock_journaler); ASSERT_EQ(0, when_open(mock_journal)); @@ -481,7 +481,7 @@ TEST_F(TestMockJournal, StateTransitions) { expect_try_pop_front(mock_journaler, false, mock_replay_entry); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_committed(mock_journaler, 3); expect_start_append(mock_journaler); @@ -532,7 +532,7 @@ TEST_F(TestMockJournal, ReplayCompleteError) { MockJournalReplay mock_journal_replay; expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); // replay failure should result in replay-restart expect_construct_journaler(mock_journaler); @@ -543,7 +543,7 @@ TEST_F(TestMockJournal, ReplayCompleteError) { }); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_start_append(mock_journaler); ASSERT_EQ(0, when_open(mock_journal)); @@ -578,7 +578,7 @@ TEST_F(TestMockJournal, FlushReplayError) { expect_replay_process(mock_journal_replay); expect_try_pop_front(mock_journaler, false, mock_replay_entry); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, -EINVAL); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, -EINVAL); // replay flush failure should result in replay-restart expect_construct_journaler(mock_journaler); @@ -589,7 +589,7 @@ TEST_F(TestMockJournal, FlushReplayError) { }); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_start_append(mock_journaler); ASSERT_EQ(0, when_open(mock_journal)); @@ -619,7 +619,7 @@ TEST_F(TestMockJournal, StopError) { MockJournalReplay mock_journal_replay; expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_start_append(mock_journaler); ASSERT_EQ(0, when_open(mock_journal)); @@ -660,7 +660,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) { expect_try_pop_front(mock_journaler, false, mock_replay_entry); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); // replay write-to-disk failure should result in replay-restart expect_construct_journaler(mock_journaler); @@ -671,7 +671,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) { }); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_start_append(mock_journaler); C_SaferCond ctx; @@ -729,7 +729,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) { expect_stop_replay(mock_journaler); Context *on_flush = nullptr; - EXPECT_CALL(mock_journal_replay, flush(_)) + EXPECT_CALL(mock_journal_replay, shut_down(_)) .WillOnce(DoAll(SaveArg<0>(&on_flush), InvokeWithoutArgs(this, &TestMockJournal::wake_up))); @@ -742,7 +742,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) { }); expect_stop_replay(mock_journaler); - expect_flush_replay(mock_image_ctx, mock_journal_replay, 0); + expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0); expect_start_append(mock_journaler); C_SaferCond ctx;