m_journaler->flush_commit_position(on_finish);
}
+template <typename I>
+void Journal<I>::user_flushed() {
+ if (m_state == STATE_READY && !m_user_flushed.exchange(true) &&
+ m_image_ctx.config.template get_val<bool>("rbd_journal_object_writethrough_until_flush")) {
+ Mutex::Locker locker(m_lock);
+ if (m_state == STATE_READY) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << dendl;
+
+ ceph_assert(m_journaler != nullptr);
+ m_journaler->set_append_batch_options(
+ m_image_ctx.config.template get_val<uint64_t>("rbd_journal_object_flush_interval"),
+ m_image_ctx.config.template get_val<Option::size_t>("rbd_journal_object_flush_bytes"),
+ m_image_ctx.config.template get_val<double>("rbd_journal_object_flush_age"));
+ } else {
+ m_user_flushed = false;
+ }
+ }
+}
+
template <typename I>
uint64_t Journal<I>::append_write_event(uint64_t offset, size_t length,
const bufferlist &bl,
m_journaler->start_append(
m_image_ctx.config.template get_val<uint64_t>("rbd_journal_object_max_in_flight_appends"));
- m_journaler->set_append_batch_options(
- m_image_ctx.config.template get_val<uint64_t>("rbd_journal_object_flush_interval"),
- m_image_ctx.config.template get_val<Option::size_t>("rbd_journal_object_flush_bytes"),
- m_image_ctx.config.template get_val<double>("rbd_journal_object_flush_age"));
+ if (!m_image_ctx.config.template get_val<bool>("rbd_journal_object_writethrough_until_flush")) {
+ m_journaler->set_append_batch_options(
+ m_image_ctx.config.template get_val<uint64_t>("rbd_journal_object_flush_interval"),
+ m_image_ctx.config.template get_val<Option::size_t>("rbd_journal_object_flush_bytes"),
+ m_image_ctx.config.template get_val<double>("rbd_journal_object_flush_age"));
+ }
transition_state(STATE_READY, 0);
}
EXPECT_CALL(mock_journaler, start_append(_));
}
- void expect_set_append_batch_options(::journal::MockJournaler &mock_journaler) {
- EXPECT_CALL(mock_journaler, set_append_batch_options(_, _, _));
+ void expect_set_append_batch_options(MockJournalImageCtx &mock_image_ctx,
+ ::journal::MockJournaler &mock_journaler,
+ bool user_flushed) {
+ if (mock_image_ctx.image_ctx->config.get_val<bool>("rbd_journal_object_writethrough_until_flush") ==
+ user_flushed) {
+ EXPECT_CALL(mock_journaler, set_append_batch_options(_, _, _));
+ }
}
void expect_stop_append(::journal::MockJournaler &mock_journaler, int r) {
expect_committed(mock_journaler, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
}
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
expect_stop_append(mock_journaler, 0);
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
expect_stop_append(mock_journaler, 0);
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
expect_stop_append(mock_journaler, -EINVAL);
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
ASSERT_EQ(0, when_open(mock_journal));
expect_stop_append(mock_journaler, -EINVAL);
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
C_SaferCond ctx;
mock_journal.open(&ctx);
expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
expect_flush_commit_position(mock_journaler);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
C_SaferCond ctx;
mock_journal.open(&ctx);
InSequence seq;
expect_stop_append(mock_journaler, 0);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
expect_shut_down_journaler(mock_journaler);
C_SaferCond start_ctx;
InSequence seq;
expect_stop_append(mock_journaler, -EINVAL);
expect_start_append(mock_journaler);
- expect_set_append_batch_options(mock_journaler);
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, false);
expect_shut_down_journaler(mock_journaler);
C_SaferCond start_ctx;
ASSERT_EQ(0, listener.ctx.wait());
}
+TEST_F(TestMockJournal, UserFlushed) {
+ REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockJournalImageCtx mock_image_ctx(*ictx);
+ MockJournal mock_journal(mock_image_ctx);
+ MockObjectDispatch mock_object_dispatch;
+ ::journal::MockJournaler mock_journaler;
+ MockJournalOpenRequest mock_open_request;
+ open_journal(mock_image_ctx, mock_journal, mock_object_dispatch,
+ mock_journaler, mock_open_request);
+ BOOST_SCOPE_EXIT_ALL(&) {
+ close_journal(mock_image_ctx, mock_journal, mock_journaler);
+ };
+
+ expect_set_append_batch_options(mock_image_ctx, mock_journaler, true);
+ mock_journal.user_flushed();
+
+ expect_shut_down_journaler(mock_journaler);
+}
+
} // namespace librbd