From 0f293714f39d1b38d0bf933984d6945139ff9c26 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Wed, 5 Jan 2022 20:24:40 +0100 Subject: [PATCH] librbd: restore diff-iterate include_parent functionality in fast-diff mode Commit 4429ed4f3f4c ("librbd: switch diff iterate API to use new snaps list dispatch methods") removed the recursive execute() call. The new list_snaps method does indeed handle parent diffs internally but it is not used in fast-diff mode. Nothing changed there -- we still need to load the parent object map, calculate parent object_diff_state, etc. Fixes: https://tracker.ceph.com/issues/53787 Signed-off-by: Ilya Dryomov (cherry picked from commit 04293bef6ccd2b9ca3db53906b63c952e235cdb4) Conflicts: src/librbd/api/DiffIterate.cc [ drop all changes, bring in just the new test ] --- src/test/librbd/test_librbd.cc | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 7937dd95d6643..7a000222b4afe 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -4213,6 +4213,73 @@ TYPED_TEST(DiffIterateTest, DiffIterateRegression6926) ASSERT_EQ(static_cast(0), extents.size()); } +TYPED_TEST(DiffIterateTest, DiffIterateParent) +{ + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + librados::IoCtx ioctx; + ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + + { + librbd::RBD rbd; + librbd::Image image; + int order = 22; + std::string name = this->get_temp_image_name(); + ssize_t size = 20 << 20; + + ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order)); + ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), NULL)); + + uint64_t features; + ASSERT_EQ(0, image.features(&features)); + uint64_t object_size = 0; + if (this->whole_object) { + object_size = 1 << order; + } + + ceph::bufferlist bl; + bl.append(std::string(size, '1')); + ASSERT_EQ(size, image.write(0, size, bl)); + ASSERT_EQ(0, image.snap_create("snap")); + ASSERT_EQ(0, image.snap_protect("snap")); + + std::string clone_name = this->get_temp_image_name(); + ASSERT_EQ(0, rbd.clone(ioctx, name.c_str(), "snap", ioctx, + clone_name.c_str(), features, &order)); + librbd::Image clone; + ASSERT_EQ(0, rbd.open(ioctx, clone, clone_name.c_str(), NULL)); + + std::vector extents; + ASSERT_EQ(0, clone.diff_iterate2(NULL, 0, size, true, this->whole_object, + vector_iterate_cb, &extents)); + ASSERT_EQ(5u, extents.size()); + ASSERT_EQ(diff_extent(0, 4194304, true, object_size), extents[0]); + ASSERT_EQ(diff_extent(4194304, 4194304, true, object_size), extents[1]); + ASSERT_EQ(diff_extent(8388608, 4194304, true, object_size), extents[2]); + ASSERT_EQ(diff_extent(12582912, 4194304, true, object_size), extents[3]); + ASSERT_EQ(diff_extent(16777216, 4194304, true, object_size), extents[4]); + extents.clear(); + + ASSERT_EQ(0, clone.resize(size / 2)); + ASSERT_EQ(0, clone.resize(size)); + ASSERT_EQ(1, clone.write(size - 1, 1, bl)); + + ASSERT_EQ(0, clone.diff_iterate2(NULL, 0, size, true, this->whole_object, + vector_iterate_cb, &extents)); + ASSERT_EQ(4u, extents.size()); + ASSERT_EQ(diff_extent(0, 4194304, true, object_size), extents[0]); + ASSERT_EQ(diff_extent(4194304, 4194304, true, object_size), extents[1]); + ASSERT_EQ(diff_extent(8388608, 2097152, true, object_size), extents[2]); + // hole (parent overlap = 10M) followed by copyup'ed object + ASSERT_EQ(diff_extent(16777216, 4194304, true, object_size), extents[3]); + + ASSERT_PASSED(this->validate_object_map, image); + ASSERT_PASSED(this->validate_object_map, clone); + } + + ioctx.close(); +} + TYPED_TEST(DiffIterateTest, DiffIterateIgnoreParent) { REQUIRE_FEATURE(RBD_FEATURE_LAYERING); -- 2.39.5