From 1fb9fc9d35b9cc6c6c1cc898a1428cf57bdfe7ec Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Wed, 14 Oct 2015 18:28:33 -0700 Subject: [PATCH] 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 --- src/librbd/RebuildObjectMapRequest.cc | 5 +++-- src/test/librbd/test_librbd.cc | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/librbd/RebuildObjectMapRequest.cc b/src/librbd/RebuildObjectMapRequest.cc index 0a7950a8fb1d9..8a3b29fe0ecd7 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 5dc5c66da471b..340d43b8c847c 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; -- 2.39.5