uint64_t when_append_io_event(MockJournalImageCtx &mock_image_ctx,
MockJournal &mock_journal,
- io::ObjectRequest<> *object_request = nullptr) {
+ io::ObjectRequest<> *object_request,
+ int filter_ret_val) {
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
MockJournal::IOObjectRequests object_requests;
if (object_request != nullptr) {
}
return mock_journal.append_io_event(
journal::EventEntry{journal::AioFlushEvent{}}, object_requests, 0, 0,
- false);
+ false, filter_ret_val);
}
void save_commit_context(Context *ctx) {
Context *on_journal_safe1;
expect_append_journaler(mock_journaler);
expect_wait_future(mock_future, &on_journal_safe1);
- ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal));
+ ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal, nullptr, 0));
mock_journal.get_work_queue()->drain();
Context *on_journal_safe2;
expect_append_journaler(mock_journaler);
expect_wait_future(mock_future, &on_journal_safe2);
- ASSERT_EQ(2U, when_append_io_event(mock_image_ctx, mock_journal));
+ ASSERT_EQ(2U, when_append_io_event(mock_image_ctx, mock_journal, nullptr, 0));
mock_journal.get_work_queue()->drain();
// commit journal event followed by IO event (standard)
};
C_SaferCond object_request_ctx;
- auto object_request = new io::ObjectRemoveRequest(
- ictx, "oid", 0, {}, {}, &object_request_ctx);
+ auto object_request = new io::ObjectDiscardRequest<>(
+ ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
+ &object_request_ctx);
::journal::MockFuture mock_future;
Context *on_journal_safe;
expect_append_journaler(mock_journaler);
expect_wait_future(mock_future, &on_journal_safe);
ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal,
- object_request));
+ object_request, 0));
mock_journal.get_work_queue()->drain();
// commit the event in the journal w/o waiting writeback
};
C_SaferCond object_request_ctx;
- auto object_request = new io::ObjectRemoveRequest(
- ictx, "oid", 0, {}, {}, &object_request_ctx);
+ auto object_request = new io::ObjectDiscardRequest<>(
+ ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
+ &object_request_ctx);
::journal::MockFuture mock_future;
Context *on_journal_safe;
expect_append_journaler(mock_journaler);
expect_wait_future(mock_future, &on_journal_safe);
ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal,
- object_request));
+ object_request, 0));
mock_journal.get_work_queue()->drain();
expect_future_is_valid(mock_future);
Context *on_journal_safe;
expect_append_journaler(mock_journaler);
expect_wait_future(mock_future, &on_journal_safe);
- ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal));
+ ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal, nullptr, 0));
mock_journal.get_work_queue()->drain();
// failed IO remains uncommitted in journal
expect_shut_down_journaler(mock_journaler);
}
+TEST_F(TestMockJournal, IOCommitErrorFiltered) {
+ 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);
+ ::journal::MockJournaler mock_journaler;
+ MockJournalOpenRequest mock_open_request;
+ open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
+ BOOST_SCOPE_EXIT_ALL(&) {
+ close_journal(mock_journal, mock_journaler);
+ };
+
+ ::journal::MockFuture mock_future;
+ Context *on_journal_safe;
+ expect_append_journaler(mock_journaler);
+ expect_wait_future(mock_future, &on_journal_safe);
+ ASSERT_EQ(1U, when_append_io_event(mock_image_ctx, mock_journal, nullptr,
+ -EILSEQ));
+ mock_journal.get_work_queue()->drain();
+
+ // filter failed IO committed in journal
+ on_journal_safe->complete(0);
+ ictx->op_work_queue->drain();
+ expect_future_committed(mock_journaler);
+ mock_journal.commit_io_event(1U, -EILSEQ);
+
+ expect_shut_down_journaler(mock_journaler);
+}
+
TEST_F(TestMockJournal, FlushCommitPosition) {
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);