summaryrefslogtreecommitdiffstats
path: root/src/test/librbd/journal/test_Entries.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/librbd/journal/test_Entries.cc')
-rw-r--r--src/test/librbd/journal/test_Entries.cc63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/test/librbd/journal/test_Entries.cc b/src/test/librbd/journal/test_Entries.cc
index c392fb9f8..bb4b06c03 100644
--- a/src/test/librbd/journal/test_Entries.cc
+++ b/src/test/librbd/journal/test_Entries.cc
@@ -196,6 +196,69 @@ TEST_F(TestJournalEntries, AioDiscard) {
ASSERT_EQ(234U, aio_discard_event.length);
}
+TEST_F(TestJournalEntries, AioDiscardWithPrune) {
+ REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+ // The discard path can create multiple image extents (ImageRequest.cc) in the
+ // case where the discard request needs to be pruned and multiple objects are
+ // involved in the request. This test ensures that journal event entries are
+ // queued up for each image extent.
+
+ // Create an image that is multiple objects so that we can force multiple
+ // image extents on the discard path.
+ CephContext* cct = reinterpret_cast<CephContext*>(_rados.cct());
+ auto object_size = 1ull << cct->_conf.get_val<uint64_t>("rbd_default_order");
+ auto image_size = 4 * object_size;
+
+ auto image_name = get_temp_image_name();
+ ASSERT_EQ(0, create_image_pp(m_rbd, m_ioctx, image_name, image_size));
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(image_name, &ictx));
+
+ ::journal::Journaler *journaler = create_journaler(ictx);
+ ASSERT_TRUE(journaler != NULL);
+
+ C_SaferCond cond_ctx;
+ auto c = librbd::io::AioCompletion::create(&cond_ctx);
+ c->get();
+ // We offset the discard by -4096 bytes and set discard granularity to 8192;
+ // this should cause two image extents to be formed in
+ // AbstractImageWriteRequest<I>::send_request().
+ api::Io<>::aio_discard(*ictx, c, object_size - 4096, 2 * object_size, 8192,
+ true);
+ ASSERT_EQ(0, c->wait_for_complete());
+ c->put();
+
+ for (uint64_t chunk = 0; chunk < 2; chunk++) {
+ auto offset = object_size;
+ auto size = object_size;
+ if (chunk == 1) {
+ offset = object_size * 2;
+ size = object_size - 8192;
+ }
+
+ ::journal::ReplayEntry replay_entry;
+ if (!journaler->try_pop_front(&replay_entry)) {
+ ASSERT_TRUE(wait_for_entries_available(ictx));
+ ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
+ }
+
+ librbd::journal::EventEntry event_entry;
+ ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
+
+ ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_DISCARD,
+ event_entry.get_event_type());
+
+ librbd::journal::AioDiscardEvent aio_discard_event =
+ boost::get<librbd::journal::AioDiscardEvent>(event_entry.event);
+ ASSERT_EQ(offset, aio_discard_event.offset);
+ ASSERT_EQ(size, aio_discard_event.length);
+
+ journaler->committed(replay_entry);
+ }
+}
+
TEST_F(TestJournalEntries, AioFlush) {
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);