From: Josh Durgin Date: Thu, 15 Oct 2015 01:28:33 +0000 (-0700) Subject: librbd: fix rebuild_object_map() when no object map exists X-Git-Tag: v9.2.0~11^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F6273%2Fhead;p=ceph.git librbd: fix rebuild_object_map() when no object map exists Enabling the object map feature and then attempting to rebuild it results in an assert failure, since the number of objects was accidentally passed to ObjectMap::aio_resize() instead of the size of the image. Fixes: #13496 Signed-off-by: Josh Durgin --- diff --git a/src/librbd/RebuildObjectMapRequest.cc b/src/librbd/RebuildObjectMapRequest.cc index 0a7950a8fb1d..8a3b29fe0ecd 100644 --- a/src/librbd/RebuildObjectMapRequest.cc +++ b/src/librbd/RebuildObjectMapRequest.cc @@ -228,9 +228,10 @@ void RebuildObjectMapRequest::send_resize_object_map() { CephContext *cct = m_image_ctx.cct; uint64_t num_objects; + uint64_t size; { RWLock::RLocker l(m_image_ctx.snap_lock); - uint64_t size = get_image_size(); + size = get_image_size(); num_objects = Striper::get_num_objects(m_image_ctx.layout, size); } @@ -245,7 +246,7 @@ void RebuildObjectMapRequest::send_resize_object_map() { // should have been canceled prior to releasing lock assert(!m_image_ctx.image_watcher->is_lock_supported() || m_image_ctx.image_watcher->is_lock_owner()); - m_image_ctx.object_map.aio_resize(num_objects, OBJECT_NONEXISTENT, + m_image_ctx.object_map.aio_resize(size, OBJECT_NONEXISTENT, create_callback_context()); } diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 5dc5c66da471..340d43b8c847 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -3080,6 +3080,31 @@ TEST_F(TestLibRBD, RebuildObjectMap) ASSERT_PASSED(validate_object_map, image2); } +TEST_F(TestLibRBD, RebuildNewObjectMap) +{ + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + rados_ioctx_t ioctx; + rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx); + + std::string name = get_temp_image_name(); + uint64_t size = 1 << 20; + int order = 18; + uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK; + ASSERT_EQ(0, create_image_full(ioctx, name.c_str(), size, &order, + false, features)); + + rbd_image_t image; + ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL)); + ASSERT_EQ(0, rbd_update_features(image, RBD_FEATURE_OBJECT_MAP, true)); + ASSERT_EQ(0, rbd_rebuild_object_map(image, print_progress_percent, NULL)); + + ASSERT_PASSED(validate_object_map, image); + + ASSERT_EQ(0, rbd_close(image)); + rados_ioctx_destroy(ioctx); +} + TEST_F(TestLibRBD, BlockingAIO) { librados::IoCtx ioctx;