From af734e63f28ac5af414b6507c945ffd9e736d5cf Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 6 Oct 2015 12:31:59 -0400 Subject: [PATCH] librbd: invalidate object map on error even w/o holding lock If there is a deep bug that prevents the object map from owning the lock before objects are updated, flag the object map as invalid regardless. Fixes: #13372 Backport: hammer Signed-off-by: Jason Dillaman (cherry picked from commit e675400df7f8ba796d60e9bac4234857f0cb1392) Conflicts: src/librbd/ObjectMap.h/cc: hammer branch doesn't support rebuild --- src/librbd/ObjectMap.cc | 20 ++++++++++---------- src/librbd/ObjectMap.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index 9e7aae2d92025..ea06d769d0502 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -176,7 +176,7 @@ void ObjectMap::refresh(uint64_t snap_id) if (r < 0) { lderr(cct) << "error refreshing object map: " << cpp_strerror(r) << dendl; - invalidate(); + invalidate(false); m_object_map.clear(); return; } @@ -189,7 +189,7 @@ void ObjectMap::refresh(uint64_t snap_id) if (m_object_map.size() < num_objs) { lderr(cct) << "object map smaller than current object count: " << m_object_map.size() << " != " << num_objs << dendl; - invalidate(); + invalidate(false); } else if (m_object_map.size() > num_objs) { // resize op might have been interrupted ldout(cct, 1) << "object map larger than current object count: " @@ -227,7 +227,7 @@ void ObjectMap::rollback(uint64_t snap_id) { if (r < 0) { lderr(cct) << "unable to load snapshot object map '" << snap_oid << "': " << cpp_strerror(r) << dendl; - invalidate(); + invalidate(false); return; } @@ -239,7 +239,7 @@ void ObjectMap::rollback(uint64_t snap_id) { if (r < 0) { lderr(cct) << "unable to rollback object map: " << cpp_strerror(r) << dendl; - invalidate(); + invalidate(true); } } @@ -265,7 +265,8 @@ void ObjectMap::snapshot(uint64_t snap_id) { if (r < 0) { lderr(cct) << "unable to load object map: " << cpp_strerror(r) << dendl; - invalidate(); + invalidate(false); + return; } std::string snap_oid(object_map_name(m_image_ctx.id, snap_id)); @@ -273,7 +274,7 @@ void ObjectMap::snapshot(uint64_t snap_id) { if (r < 0) { lderr(cct) << "unable to snapshot object map '" << snap_oid << "': " << cpp_strerror(r) << dendl; - invalidate(); + invalidate(false); } } @@ -333,7 +334,7 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, return false; } -void ObjectMap::invalidate() { +void ObjectMap::invalidate(bool force) { assert(m_image_ctx.snap_lock.is_wlocked()); assert(m_image_ctx.object_map_lock.is_wlocked()); uint64_t flags; @@ -355,7 +356,7 @@ void ObjectMap::invalidate() { } librados::ObjectWriteOperation op; - if (m_image_ctx.snap_id == CEPH_NOSNAP) { + if (m_image_ctx.snap_id == CEPH_NOSNAP && !force) { m_image_ctx.image_watcher->assert_header_locked(&op); } cls_client::set_flags(&op, m_image_ctx.snap_id, m_image_ctx.flags, @@ -380,7 +381,7 @@ bool ObjectMap::Request::should_complete(int r) { case STATE_REQUEST: if (r == -EBUSY) { lderr(cct) << "object map lock not owned by client" << dendl; - return true; + return invalidate(); } else if (r < 0) { lderr(cct) << "failed to update object map: " << cpp_strerror(r) << dendl; @@ -425,7 +426,6 @@ bool ObjectMap::Request::invalidate() { m_image_ctx.flags |= RBD_FLAG_OBJECT_MAP_INVALID; librados::ObjectWriteOperation op; - m_image_ctx.image_watcher->assert_header_locked(&op); cls_client::set_flags(&op, CEPH_NOSNAP, m_image_ctx.flags, RBD_FLAG_OBJECT_MAP_INVALID); diff --git a/src/librbd/ObjectMap.h b/src/librbd/ObjectMap.h index 4104636515782..62532070411e0 100644 --- a/src/librbd/ObjectMap.h +++ b/src/librbd/ObjectMap.h @@ -131,7 +131,7 @@ private: bool m_enabled; - void invalidate(); + void invalidate(bool force); }; -- 2.39.5