From: Jason Dillaman Date: Sat, 21 Mar 2015 18:40:26 +0000 (-0400) Subject: librbd: allow snapshot object maps to be updated X-Git-Tag: v9.0.1~149^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e714800c48473321b2e8cf3355ce4ba481f6b5c6;p=ceph.git librbd: allow snapshot object maps to be updated Rebuild will need to be able to update/resize the object maps for image snapshots. This was previously not permitted. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index 4c9e2a73cdf4..5e40555cc9ac 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -17,7 +17,7 @@ namespace librbd { ObjectMap::ObjectMap(ImageCtx &image_ctx) - : m_image_ctx(image_ctx), m_enabled(false) + : m_image_ctx(image_ctx), m_snap_id(CEPH_NOSNAP), m_enabled(false) { } @@ -154,6 +154,7 @@ void ObjectMap::refresh(uint64_t snap_id) { assert(m_image_ctx.snap_lock.is_wlocked()); RWLock::WLocker l(m_image_ctx.object_map_lock); + m_snap_id = snap_id; if ((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) == 0 || (m_image_ctx.snap_id == snap_id && !m_image_ctx.snap_exists)) { @@ -178,7 +179,10 @@ void ObjectMap::refresh(uint64_t snap_id) invalidate(snap_id); librados::ObjectWriteOperation op; - rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + if (snap_id == CEPH_NOSNAP) { + rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", + ""); + } op.truncate(0); cls_client::object_map_resize(&op, num_objs, OBJECT_NONEXISTENT); @@ -206,7 +210,10 @@ void ObjectMap::refresh(uint64_t snap_id) // correct the size issue so future IO can keep the object map in sync librados::ObjectWriteOperation op; - rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + if (snap_id == CEPH_NOSNAP) { + rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", + ""); + } cls_client::object_map_resize(&op, num_objs, OBJECT_NONEXISTENT); r = m_image_ctx.md_ctx.operate(oid, &op); @@ -300,10 +307,11 @@ void ObjectMap::aio_resize(uint64_t new_size, uint8_t default_object_state, Context *on_finish) { assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)); assert(m_image_ctx.owner_lock.is_locked()); - assert(m_image_ctx.image_watcher->is_lock_owner()); + assert(!m_image_ctx.image_watcher->is_lock_supported() || + m_image_ctx.image_watcher->is_lock_owner()); ResizeRequest *req = new ResizeRequest( - m_image_ctx, new_size, default_object_state, on_finish); + m_image_ctx, m_snap_id, new_size, default_object_state, on_finish); req->send(); } @@ -322,7 +330,8 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, { assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)); assert(m_image_ctx.owner_lock.is_locked()); - assert(m_image_ctx.image_watcher->is_lock_owner()); + assert(!m_image_ctx.image_watcher->is_lock_supported() || + m_image_ctx.image_watcher->is_lock_owner()); assert(m_image_ctx.object_map_lock.is_wlocked()); assert(start_object_no < end_object_no); @@ -339,9 +348,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, ++object_no) { if ((!current_state || m_object_map[object_no] == *current_state) && m_object_map[object_no] != new_state) { - UpdateRequest *req = new UpdateRequest(m_image_ctx, start_object_no, - end_object_no, new_state, - current_state, on_finish); + UpdateRequest *req = new UpdateRequest(m_image_ctx, m_snap_id, + start_object_no, end_object_no, + new_state, current_state, + on_finish); req->send(); return true; } @@ -462,11 +472,13 @@ void ObjectMap::ResizeRequest::send() { << m_num_objs << dendl; librados::ObjectWriteOperation op; - rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + if (m_snap_id == CEPH_NOSNAP) { + rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + } cls_client::object_map_resize(&op, m_num_objs, m_default_object_state); librados::AioCompletion *rados_completion = create_callback_completion(); - std::string oid(object_map_name(m_image_ctx.id, CEPH_NOSNAP)); + std::string oid(object_map_name(m_image_ctx.id, m_snap_id)); int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op); assert(r == 0); rados_completion->release(); @@ -503,12 +515,14 @@ void ObjectMap::UpdateRequest::send() { } librados::ObjectWriteOperation op; - rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + if (m_snap_id == CEPH_NOSNAP) { + rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); + } cls_client::object_map_update(&op, m_start_object_no, m_end_object_no, m_new_state, m_current_state); librados::AioCompletion *rados_completion = create_callback_completion(); - std::string oid(object_map_name(m_image_ctx.id, CEPH_NOSNAP)); + std::string oid(object_map_name(m_image_ctx.id, m_snap_id)); int r = m_image_ctx.md_ctx.aio_operate(oid, rados_completion, &op); assert(r == 0); rados_completion->release(); diff --git a/src/librbd/ObjectMap.h b/src/librbd/ObjectMap.h index 653bba553086..78ee5f3231fe 100644 --- a/src/librbd/ObjectMap.h +++ b/src/librbd/ObjectMap.h @@ -57,15 +57,17 @@ private: class Request : public AsyncRequest { public: - Request(ImageCtx &image_ctx, Context *on_finish) - : AsyncRequest(image_ctx, on_finish), m_state(STATE_REQUEST) + Request(ImageCtx &image_ctx, uint64_t snap_id, Context *on_finish) + : AsyncRequest(image_ctx, on_finish), m_snap_id(snap_id), + m_state(STATE_REQUEST) { } protected: + const uint64_t m_snap_id; + virtual bool should_complete(int r); virtual void finish(ObjectMap *object_map) = 0; - private: /** * ---> STATE_REQUEST ---> @@ -81,14 +83,14 @@ private: State m_state; bool invalidate(); - }; + }; class ResizeRequest : public Request { public: - ResizeRequest(ImageCtx &image_ctx, uint64_t new_size, + ResizeRequest(ImageCtx &image_ctx, uint64_t snap_id, uint64_t new_size, uint8_t default_object_state, Context *on_finish) - : Request(image_ctx, on_finish), m_num_objs(0), m_new_size(new_size), - m_default_object_state(default_object_state) + : Request(image_ctx, snap_id, on_finish), m_num_objs(0), + m_new_size(new_size), m_default_object_state(default_object_state) { } @@ -103,13 +105,14 @@ private: class UpdateRequest : public Request { public: - UpdateRequest(ImageCtx &image_ctx, uint64_t start_object_no, - uint64_t end_object_no, uint8_t new_state, + UpdateRequest(ImageCtx &image_ctx, uint64_t snap_id, + uint64_t start_object_no, uint64_t end_object_no, + uint8_t new_state, const boost::optional ¤t_state, Context *on_finish) - : Request(image_ctx, on_finish), m_start_object_no(start_object_no), - m_end_object_no(end_object_no), m_new_state(new_state), - m_current_state(current_state) + : Request(image_ctx, snap_id, on_finish), + m_start_object_no(start_object_no), m_end_object_no(end_object_no), + m_new_state(new_state), m_current_state(current_state) { } @@ -125,6 +128,7 @@ private: ImageCtx &m_image_ctx; ceph::BitVector<2> m_object_map; + uint64_t m_snap_id; bool m_enabled; void invalidate(uint64_t snap_id);