From: Jason Dillaman Date: Wed, 17 Aug 2016 18:02:32 +0000 (-0400) Subject: librbd: image state machine now has hooks for lock requests X-Git-Tag: v10.2.6~66^2~18 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3d61b69b11ef67719e78d77fec000403d43d70d3;p=ceph.git librbd: image state machine now has hooks for lock requests Signed-off-by: Jason Dillaman (cherry picked from commit a5b8c9c1d81ed609e71a5a8abe4d0e90194408cc) --- diff --git a/src/librbd/ImageState.cc b/src/librbd/ImageState.cc index 5b450b0671e5..3e0a3853f066 100644 --- a/src/librbd/ImageState.cc +++ b/src/librbd/ImageState.cc @@ -377,6 +377,37 @@ void ImageState::snap_set(const std::string &snap_name, Context *on_finish) { execute_action_unlock(action, on_finish); } +template +void ImageState::prepare_lock(Context *on_ready) { + CephContext *cct = m_image_ctx->cct; + ldout(cct, 10) << __func__ << dendl; + + m_lock.Lock(); + if (is_closed()) { + m_lock.Unlock(); + on_ready->complete(-ESHUTDOWN); + return; + } + + Action action(ACTION_TYPE_LOCK); + action.on_ready = on_ready; + execute_action_unlock(action, nullptr); +} + +template +void ImageState::handle_prepare_lock_complete() { + CephContext *cct = m_image_ctx->cct; + ldout(cct, 10) << __func__ << dendl; + + m_lock.Lock(); + if (m_state != STATE_PREPARING_LOCK) { + m_lock.Unlock(); + return; + } + + complete_action_unlock(STATE_OPEN, 0); +} + template int ImageState::register_update_watcher(UpdateWatchCtx *watcher, uint64_t *handle) { @@ -426,6 +457,7 @@ bool ImageState::is_transition_state() const { case STATE_CLOSING: case STATE_REFRESHING: case STATE_SETTING_SNAP: + case STATE_PREPARING_LOCK: break; } return true; @@ -479,6 +511,9 @@ void ImageState::execute_next_action_unlock() { case ACTION_TYPE_SET_SNAP: send_set_snap_unlock(); return; + case ACTION_TYPE_LOCK: + send_prepare_lock_unlock(); + return; } assert(false); } @@ -663,6 +698,30 @@ void ImageState::handle_set_snap(int r) { complete_action_unlock(STATE_OPEN, r); } +template +void ImageState::send_prepare_lock_unlock() { + CephContext *cct = m_image_ctx->cct; + ldout(cct, 10) << this << " " << __func__ << dendl; + + assert(m_lock.is_locked()); + m_state = STATE_PREPARING_LOCK; + + assert(!m_actions_contexts.empty()); + ActionContexts &action_contexts(m_actions_contexts.front()); + assert(action_contexts.first.action_type == ACTION_TYPE_LOCK); + + Context *on_ready = action_contexts.first.on_ready; + m_lock.Unlock(); + + if (on_ready == nullptr) { + complete_action_unlock(STATE_OPEN, 0); + return; + } + + // wake up the lock handler now that its safe to proceed + on_ready->complete(0); +} + } // namespace librbd template class librbd::ImageState; diff --git a/src/librbd/ImageState.h b/src/librbd/ImageState.h index bad42775d393..2e0fb63fbde4 100644 --- a/src/librbd/ImageState.h +++ b/src/librbd/ImageState.h @@ -42,6 +42,9 @@ public: void snap_set(const std::string &snap_name, Context *on_finish); + void prepare_lock(Context *on_ready); + void handle_prepare_lock_complete(); + int register_update_watcher(UpdateWatchCtx *watcher, uint64_t *handle); int unregister_update_watcher(uint64_t handle); void flush_update_watchers(Context *on_finish); @@ -55,14 +58,16 @@ private: STATE_OPENING, STATE_CLOSING, STATE_REFRESHING, - STATE_SETTING_SNAP + STATE_SETTING_SNAP, + STATE_PREPARING_LOCK }; enum ActionType { ACTION_TYPE_OPEN, ACTION_TYPE_CLOSE, ACTION_TYPE_REFRESH, - ACTION_TYPE_SET_SNAP + ACTION_TYPE_SET_SNAP, + ACTION_TYPE_LOCK }; struct Action { @@ -70,6 +75,7 @@ private: uint64_t refresh_seq = 0; bool refresh_acquiring_lock = false; std::string snap_name; + Context *on_ready = nullptr; Action(ActionType action_type) : action_type(action_type) { } @@ -83,6 +89,8 @@ private: refresh_acquiring_lock == action.refresh_acquiring_lock); case ACTION_TYPE_SET_SNAP: return snap_name == action.snap_name; + case ACTION_TYPE_LOCK: + return false; default: return true; } @@ -126,6 +134,8 @@ private: void send_set_snap_unlock(); void handle_set_snap(int r); + void send_prepare_lock_unlock(); + }; } // namespace librbd diff --git a/src/test/librbd/mock/MockImageState.h b/src/test/librbd/mock/MockImageState.h index 3ba1ee5d7dd0..603871b5b46e 100644 --- a/src/test/librbd/mock/MockImageState.h +++ b/src/test/librbd/mock/MockImageState.h @@ -21,6 +21,9 @@ struct MockImageState { MOCK_METHOD1(close, void(Context*)); MOCK_METHOD2(snap_set, void(const std::string &, Context*)); + + MOCK_METHOD1(prepare_lock, void(Context*)); + MOCK_METHOD0(handle_prepare_lock_complete, void()); }; } // namespace librbd