From 58770188ab57a53b786cf616ccfbf6acfcdc115a Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 14 Sep 2018 11:21:28 -0400 Subject: [PATCH] librbd: converted object map snapshot remove state machine to new style Signed-off-by: Jason Dillaman --- .../object_map/SnapshotRemoveRequest.cc | 193 +++++++++--------- src/librbd/object_map/SnapshotRemoveRequest.h | 32 ++- 2 files changed, 108 insertions(+), 117 deletions(-) diff --git a/src/librbd/object_map/SnapshotRemoveRequest.cc b/src/librbd/object_map/SnapshotRemoveRequest.cc index ec33df7c1ced3..ca28ba5a0a261 100644 --- a/src/librbd/object_map/SnapshotRemoveRequest.cc +++ b/src/librbd/object_map/SnapshotRemoveRequest.cc @@ -11,37 +11,12 @@ #define dout_subsys ceph_subsys_rbd #undef dout_prefix -#define dout_prefix *_dout << "librbd::object_map::SnapshotRemoveRequest: " +#define dout_prefix *_dout << "librbd::object_map::SnapshotRemoveRequest: " \ + << this << " " << __func__ << ": " namespace librbd { namespace object_map { -namespace { - -std::ostream& operator<<(std::ostream& os, - const SnapshotRemoveRequest::State& state) { - switch(state) { - case SnapshotRemoveRequest::STATE_LOAD_MAP: - os << "LOAD_MAP"; - break; - case SnapshotRemoveRequest::STATE_REMOVE_SNAPSHOT: - os << "REMOVE_SNAPSHOT"; - break; - case SnapshotRemoveRequest::STATE_INVALIDATE_NEXT_MAP: - os << "INVALIDATE_NEXT_MAP"; - break; - case SnapshotRemoveRequest::STATE_REMOVE_MAP: - os << "REMOVE_MAP"; - break; - default: - os << "UNKNOWN (" << static_cast(state) << ")"; - break; - } - return os; -} - -} // anonymous namespace - void SnapshotRemoveRequest::send() { ceph_assert(m_image_ctx.owner_lock.is_locked()); ceph_assert(m_image_ctx.snap_lock.is_wlocked()); @@ -54,84 +29,60 @@ void SnapshotRemoveRequest::send() { ceph_assert(r == 0); if ((flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0) { - send_invalidate_next_map(); + invalidate_next_map(); } else { - send_load_map(); + load_map(); } } else { - send_remove_map(); - } -} - -bool SnapshotRemoveRequest::should_complete(int r) { - CephContext *cct = m_image_ctx.cct; - ldout(cct, 5) << this << " " << __func__ << ": state=" << m_state << ", " - << "r=" << r << dendl; - - RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - bool finished = false; - switch (m_state) { - case STATE_LOAD_MAP: - if (r == -ENOENT) { - finished = true; - break; - } - - if (r == 0) { - auto it = m_out_bl.cbegin(); - r = cls_client::object_map_load_finish(&it, &m_snap_object_map); - } - if (r < 0) { - RWLock::WLocker snap_locker(m_image_ctx.snap_lock); - send_invalidate_next_map(); - } else { - send_remove_snapshot(); - } - break; - case STATE_REMOVE_SNAPSHOT: - if (r < 0 && r != -ENOENT) { - RWLock::WLocker snap_locker(m_image_ctx.snap_lock); - send_invalidate_next_map(); - } else { - update_object_map(); - send_remove_map(); - } - break; - case STATE_INVALIDATE_NEXT_MAP: - send_remove_map(); - break; - case STATE_REMOVE_MAP: - finished = true; - break; - default: - ceph_abort(); - break; + remove_map(); } - return finished; } -void SnapshotRemoveRequest::send_load_map() { +void SnapshotRemoveRequest::load_map() { CephContext *cct = m_image_ctx.cct; std::string snap_oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id)); - ldout(cct, 5) << this << " " << __func__ << ": snap_oid=" << snap_oid - << dendl; - m_state = STATE_LOAD_MAP; + ldout(cct, 5) << "snap_oid=" << snap_oid << dendl; librados::ObjectReadOperation op; cls_client::object_map_load_start(&op); - librados::AioCompletion *rados_completion = create_callback_completion(); + auto rados_completion = librbd::util::create_rados_callback< + SnapshotRemoveRequest, &SnapshotRemoveRequest::handle_load_map>(this); int r = m_image_ctx.md_ctx.aio_operate(snap_oid, rados_completion, &op, &m_out_bl); ceph_assert(r == 0); rados_completion->release(); } -void SnapshotRemoveRequest::send_remove_snapshot() { +void SnapshotRemoveRequest::handle_load_map(int r) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << "r=" << r << dendl; + + if (r == 0) { + auto it = m_out_bl.cbegin(); + r = cls_client::object_map_load_finish(&it, &m_snap_object_map); + } + if (r == -ENOENT) { + complete(0); + return; + } else if (r < 0) { + std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id)); + lderr(cct) << "failed to load object map " << oid << ": " + << cpp_strerror(r) << dendl; + + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + RWLock::WLocker snap_locker(m_image_ctx.snap_lock); + invalidate_next_map(); + return; + } + + remove_snapshot(); +} + +void SnapshotRemoveRequest::remove_snapshot() { CephContext *cct = m_image_ctx.cct; std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_next_snap_id)); - ldout(cct, 5) << this << " " << __func__ << ": oid=" << oid << dendl; - m_state = STATE_REMOVE_SNAPSHOT; + ldout(cct, 5) << "oid=" << oid << dendl; librados::ObjectWriteOperation op; if (m_next_snap_id == CEPH_NOSNAP) { @@ -139,41 +90,87 @@ void SnapshotRemoveRequest::send_remove_snapshot() { } cls_client::object_map_snap_remove(&op, m_snap_object_map); - librados::AioCompletion *rados_completion = create_callback_completion(); + auto rados_completion = librbd::util::create_rados_callback< + SnapshotRemoveRequest, + &SnapshotRemoveRequest::handle_remove_snapshot>(this); int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op); ceph_assert(r == 0); rados_completion->release(); } -void SnapshotRemoveRequest::send_invalidate_next_map() { +void SnapshotRemoveRequest::handle_remove_snapshot(int r) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << "r=" << r << dendl; + if (r < 0 && r != -ENOENT) { + std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, + m_next_snap_id)); + lderr(cct) << "failed to remove object map snapshot " << oid << ": " + << cpp_strerror(r) << dendl; + + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + RWLock::WLocker snap_locker(m_image_ctx.snap_lock); + invalidate_next_map(); + return; + } + + RWLock::RLocker snap_locker(m_image_ctx.snap_lock); + update_object_map(); + remove_map(); +} + +void SnapshotRemoveRequest::invalidate_next_map() { ceph_assert(m_image_ctx.owner_lock.is_locked()); ceph_assert(m_image_ctx.snap_lock.is_wlocked()); CephContext *cct = m_image_ctx.cct; - ldout(cct, 5) << this << " " << __func__ << dendl; - m_state = STATE_INVALIDATE_NEXT_MAP; + ldout(cct, 5) << dendl; + auto ctx = librbd::util::create_context_callback< + SnapshotRemoveRequest, + &SnapshotRemoveRequest::handle_invalidate_next_map>(this); InvalidateRequest<> *req = new InvalidateRequest<>(m_image_ctx, - m_next_snap_id, true, - create_callback_context()); + m_next_snap_id, true, ctx); req->send(); } -void SnapshotRemoveRequest::send_remove_map() { +void SnapshotRemoveRequest::handle_invalidate_next_map(int r) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << "r=" << r << dendl; + ceph_assert(r == 0); + + remove_map(); +} + +void SnapshotRemoveRequest::remove_map() { CephContext *cct = m_image_ctx.cct; std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id)); - ldout(cct, 5) << this << " " << __func__ << ": oid=" << oid << dendl; - m_state = STATE_REMOVE_MAP; + ldout(cct, 5) << "oid=" << oid << dendl; librados::ObjectWriteOperation op; op.remove(); - librados::AioCompletion *rados_completion = create_callback_completion(); + auto rados_completion = librbd::util::create_rados_callback< + SnapshotRemoveRequest, &SnapshotRemoveRequest::handle_remove_map>(this); int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op); ceph_assert(r == 0); rados_completion->release(); } +void SnapshotRemoveRequest::handle_remove_map(int r) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << "r=" << r << dendl; + + if (r < 0 && r != -ENOENT) { + std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id)); + lderr(cct) << "failed to remove object map " << oid << ": " + << cpp_strerror(r) << dendl; + complete(r); + return; + } + + complete(0); +} + void SnapshotRemoveRequest::compute_next_snap_id() { ceph_assert(m_image_ctx.snap_lock.is_locked()); @@ -189,12 +186,12 @@ void SnapshotRemoveRequest::compute_next_snap_id() { } void SnapshotRemoveRequest::update_object_map() { - RWLock::RLocker snap_locker(m_image_ctx.snap_lock); + assert(m_image_ctx.snap_lock.is_locked()); RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock); if (m_next_snap_id == m_image_ctx.snap_id && m_next_snap_id == CEPH_NOSNAP) { CephContext *cct = m_image_ctx.cct; - ldout(cct, 5) << this << " " << __func__ << dendl; - + ldout(cct, 5) << dendl; + auto it = m_object_map.begin(); auto end_it = m_object_map.end(); auto snap_it = m_snap_object_map.begin(); diff --git a/src/librbd/object_map/SnapshotRemoveRequest.h b/src/librbd/object_map/SnapshotRemoveRequest.h index a6dea08e1efb0..ede490045579a 100644 --- a/src/librbd/object_map/SnapshotRemoveRequest.h +++ b/src/librbd/object_map/SnapshotRemoveRequest.h @@ -39,12 +39,6 @@ public: * invalid, the next snapshot / HEAD object mapis flagged as invalid; * otherwise, the state machine proceeds to remove the object map. */ - enum State { - STATE_LOAD_MAP, - STATE_REMOVE_SNAPSHOT, - STATE_INVALIDATE_NEXT_MAP, - STATE_REMOVE_MAP - }; SnapshotRemoveRequest(ImageCtx &image_ctx, ceph::BitVector<2> *object_map, uint64_t snap_id, Context *on_finish) @@ -55,18 +49,11 @@ public: void send() override; protected: - bool should_complete(int r) override; - - int filter_return_code(int r) const override { - if ((m_state == STATE_LOAD_MAP || m_state == STATE_REMOVE_MAP) && - r == -ENOENT) { - return 0; - } - return r; + bool should_complete(int r) override { + return true; } private: - State m_state = STATE_LOAD_MAP; ceph::BitVector<2> &m_object_map; uint64_t m_snap_id; uint64_t m_next_snap_id; @@ -74,10 +61,17 @@ private: ceph::BitVector<2> m_snap_object_map; bufferlist m_out_bl; - void send_load_map(); - void send_remove_snapshot(); - void send_invalidate_next_map(); - void send_remove_map(); + void load_map(); + void handle_load_map(int r); + + void remove_snapshot(); + void handle_remove_snapshot(int r); + + void invalidate_next_map(); + void handle_invalidate_next_map(int r); + + void remove_map(); + void handle_remove_map(int r); void compute_next_snap_id(); void update_object_map(); -- 2.39.5