From: Jason Dillaman Date: Wed, 12 Sep 2018 01:52:05 +0000 (-0400) Subject: luminous: librbd: fixed assert when flattening clone with zero overlap X-Git-Tag: v12.2.9~60^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F24285%2Fhead;p=ceph.git 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 --- diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index bc118915dc40..e9e8fa4b76fd 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 78cca8d38dc5..35c947c04436 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 67e348a40cdc..a4e6d1d268df 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,