From 30e05d8bdbce06c87290be1bd0ec99525d82c34f Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 11 Sep 2018 21:52:05 -0400 Subject: [PATCH] luminous: librbd: fixed assert when flattening clone with zero overlap Fixes: http://tracker.ceph.com/issues/35702 Signed-off-by: Jason Dillaman (cherry picked from commit 8e90354) Conflicts: src/librbd/Operations.cc src/test/librbd/test_librbd.cc --- src/librbd/Operations.cc | 1 - src/librbd/operation/FlattenRequest.cc | 2 +- src/test/librbd/test_librbd.cc | 32 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index bc118915dc407..e9e8fa4b76fdf 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -398,7 +398,6 @@ void Operations::execute_flatten(ProgressContext &prog_ctx, } ::SnapContext snapc = m_image_ctx.snapc; - assert(m_image_ctx.parent != NULL); uint64_t overlap; int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &overlap); diff --git a/src/librbd/operation/FlattenRequest.cc b/src/librbd/operation/FlattenRequest.cc index 78cca8d38dc55..35c947c044362 100644 --- a/src/librbd/operation/FlattenRequest.cc +++ b/src/librbd/operation/FlattenRequest.cc @@ -130,7 +130,7 @@ bool FlattenRequest::send_update_header() { RWLock::RLocker parent_locker(image_ctx.parent_lock); // stop early if the parent went away - it just means // another flatten finished first, so this one is useless. - if (!image_ctx.parent) { + if (image_ctx.parent_md.spec.pool_id == -1) { ldout(cct, 5) << "image already flattened" << dendl; return true; } diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 67e348a40cdc9..a4e6d1d268df1 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -6195,6 +6195,38 @@ TEST_F(TestLibRBD, TestTrashMoveAndRestore) { ASSERT_TRUE(found); } +TEST_F(TestLibRBD, ZeroOverlapFlatten) { + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + librados::IoCtx ioctx; + ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx)); + + librbd::RBD rbd; + librbd::Image parent_image; + std::string name = get_temp_image_name(); + + uint64_t size = 1; + int order = 0; + + ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order)); + ASSERT_EQ(0, rbd.open(ioctx, parent_image, name.c_str(), NULL)); + + uint64_t features; + ASSERT_EQ(0, parent_image.features(&features)); + + ASSERT_EQ(0, parent_image.snap_create("snap")); + ASSERT_EQ(0, parent_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_image; + ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL)); + ASSERT_EQ(0, clone_image.resize(0)); + ASSERT_EQ(0, clone_image.flatten()); +} + // poorman's assert() namespace ceph { void __ceph_assert_fail(const char *assertion, const char *file, int line, -- 2.39.5