diff --git a/src/librbd/object_map/SnapshotRemoveRequest.cc b/src/librbd/object_map/SnapshotRemoveRequest.cc index c718af1da19ae1..94c0952504a149 100644 --- a/src/librbd/object_map/SnapshotRemoveRequest.cc +++ b/src/librbd/object_map/SnapshotRemoveRequest.cc @@ -72,6 +72,11 @@ bool SnapshotRemoveRequest::should_complete(int r) { bool finished = false; switch (m_state) { case STATE_LOAD_MAP: + if (r == -ENOENT) { + finished = true; + break; + } + if (r == 0) { bufferlist::iterator it = m_out_bl.begin(); r = cls_client::object_map_load_finish(&it, &m_snap_object_map); diff --git a/src/librbd/object_map/SnapshotRemoveRequest.h b/src/librbd/object_map/SnapshotRemoveRequest.h index 64696784130e9b..3b196b13c574be 100644 --- a/src/librbd/object_map/SnapshotRemoveRequest.h +++ b/src/librbd/object_map/SnapshotRemoveRequest.h @@ -58,7 +58,8 @@ class SnapshotRemoveRequest : public AsyncRequest<> { virtual bool should_complete(int r); virtual int filter_return_code(int r) const { - if (m_state == STATE_REMOVE_MAP && r == -ENOENT) { + if ((m_state == STATE_LOAD_MAP || m_state == STATE_REMOVE_MAP) && + r == -ENOENT) { return 0; } return r; diff --git a/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc b/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc index c00a3e69f132f3..215c214eb8b10b 100644 --- a/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc +++ b/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc @@ -101,6 +101,31 @@ TEST_F(TestMockObjectMapSnapshotRemoveRequest, Success) { expect_unlock_exclusive_lock(*ictx); } +TEST_F(TestMockObjectMapSnapshotRemoveRequest, LoadMapMissing) { + REQUIRE_FEATURE(RBD_FEATURE_FAST_DIFF); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_EQ(0, snap_create(*ictx, "snap1")); + ASSERT_EQ(0, ictx->state->refresh_if_required()); + + uint64_t snap_id = ictx->snap_info.rbegin()->first; + expect_load_map(ictx, snap_id, -ENOENT); + + ceph::BitVector<2> object_map; + C_SaferCond cond_ctx; + AsyncRequest<> *request = new SnapshotRemoveRequest( + *ictx, &object_map, snap_id, &cond_ctx); + { + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker snap_locker(ictx->snap_lock); + request->send(); + } + ASSERT_EQ(0, cond_ctx.wait()); + + expect_unlock_exclusive_lock(*ictx); +} + TEST_F(TestMockObjectMapSnapshotRemoveRequest, LoadMapError) { REQUIRE_FEATURE(RBD_FEATURE_FAST_DIFF);