]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fixed assert when flattening clone with zero overlap 24356/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 12 Sep 2018 01:52:05 +0000 (21:52 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 1 Oct 2018 18:36:31 +0000 (14:36 -0400)
Fixes: http://tracker.ceph.com/issues/35702
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 8e9035443322f8cbdb8c7aff5da0d1c7599a2592)

Conflicts:
src/librbd/Operations.cc: trivial resolution
src/test/librbd/test_librbd.cc: trivial resolution

src/librbd/Operations.cc
src/librbd/operation/FlattenRequest.cc
src/test/librbd/test_librbd.cc

index 0e3ba2ac881d024070c493d4d8530dc0c55889a9..fe44274d1f9cd0c90eb165e92ce5afd49758c1d4 100644 (file)
@@ -400,7 +400,6 @@ void Operations<I>::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);
index 877384bb6df831037aaf309aa7d4b8a7cc080339..e1fe1a2667d511e5edde5d2bf318bfc95a0929c0 100644 (file)
@@ -160,7 +160,7 @@ bool FlattenRequest<I>::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;
     }
index 246b3b8ba742cb2f97fa95f5740b933a77aa3f59..3656c36254fd0df8bd025a06a223eda509a78434 100644 (file)
@@ -6646,6 +6646,38 @@ TEST_F(TestLibRBD, TestSetSnapById) {
   ASSERT_EQ(0, image.snap_set_by_id(CEPH_NOSNAP));
 }
 
+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,