]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: differentiate journal replay flush vs shut down
authorJason Dillaman <dillaman@redhat.com>
Thu, 18 Feb 2016 16:28:52 +0000 (11:28 -0500)
committerJason Dillaman <dillaman@redhat.com>
Fri, 19 Feb 2016 00:58:48 +0000 (19:58 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/Journal.cc
src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h
src/test/librbd/journal/test_mock_Replay.cc
src/test/librbd/test_mock_Journal.cc

index a5976716171f47e19627cb2ff5c6401308136cfb..5bd1759864e0cf17cee1768f097cb576c3483598 100644 (file)
@@ -629,13 +629,13 @@ void Journal<I>::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<I>, &Journal<I>::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<I>, &Journal<I>::handle_flushing_replay>(this));
   }
 }
@@ -665,7 +665,7 @@ void Journal<I>::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<I>, &Journal<I>::handle_flushing_restart>(this));
       return;
     } else if (m_state == STATE_FLUSHING_REPLAY) {
index 0db4bb3da6c00b731cdff11d82638ab7579f7348..64b5fe9d92a707d3ed136a734007c216b16fb680 100644 (file)
@@ -66,7 +66,7 @@ void Replay<I>::process(bufferlist::iterator *it, Context *on_ready,
 }
 
 template <typename I>
-void Replay<I>::flush(Context *on_finish) {
+void Replay<I>::shut_down(Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
@@ -110,6 +110,19 @@ void Replay<I>::flush(Context *on_finish) {
   }
 }
 
+template <typename I>
+void Replay<I>::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<I>::aio_flush(&m_image_ctx, aio_comp);
+}
+
 template <typename I>
 void Replay<I>::replay_op_ready(uint64_t op_tid, Context *on_resume) {
   CephContext *cct = m_image_ctx.cct;
index c8c58cbe2d2a114d08355a9bd215f36542ecfb3a..ad08208fd5cab147fcfccd3b00f8361b521624b6 100644 (file)
@@ -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);
index 174f52bf88e2092ba4db2b94ccde38e8692b7246..43c35396431d1eaff7f8c01f57b254d628e94b7f 100644 (file)
@@ -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());
 }
 
index c849e6084c77ed8cdd9cb8064e537b05c3beb6e1..483b0a05db29e6ca23442452e8470e1a9476ef70 100644 (file)
@@ -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;