diff options
Diffstat (limited to 'src/librbd/ExclusiveLock.h')
-rw-r--r-- | src/librbd/ExclusiveLock.h | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h new file mode 100644 index 000000000..9915262f9 --- /dev/null +++ b/src/librbd/ExclusiveLock.h @@ -0,0 +1,117 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_EXCLUSIVE_LOCK_H +#define CEPH_LIBRBD_EXCLUSIVE_LOCK_H + +#include "common/AsyncOpTracker.h" +#include "librbd/ManagedLock.h" +#include "librbd/exclusive_lock/Policy.h" +#include "librbd/io/Types.h" +#include "common/RefCountedObj.h" + +struct Context; + +namespace librbd { + +namespace exclusive_lock { template <typename> struct ImageDispatch; } + +template <typename ImageCtxT = ImageCtx> +class ExclusiveLock : public RefCountedObject, + public ManagedLock<ImageCtxT> { +public: + static ExclusiveLock *create(ImageCtxT &image_ctx) { + return new ExclusiveLock<ImageCtxT>(image_ctx); + } + + ExclusiveLock(ImageCtxT &image_ctx); + + bool accept_request(exclusive_lock::OperationRequestType request_type, + int *ret_val) const; + bool accept_ops() const; + + void set_require_lock(bool init_shutdown, io::Direction direction, + Context* on_finish); + void unset_require_lock(io::Direction direction); + + void block_requests(int r); + void unblock_requests(); + + void init(uint64_t features, Context *on_init); + void shut_down(Context *on_shutdown); + + void handle_peer_notification(int r); + + int get_unlocked_op_error() const; + Context *start_op(int* ret_val); + +protected: + void shutdown_handler(int r, Context *on_finish) override; + void pre_acquire_lock_handler(Context *on_finish) override; + void post_acquire_lock_handler(int r, Context *on_finish) override; + void pre_release_lock_handler(bool shutting_down, + Context *on_finish) override; + void post_release_lock_handler(bool shutting_down, int r, + Context *on_finish) override; + void post_reacquire_lock_handler(int r, Context *on_finish) override; + +private: + + /** + * @verbatim + * + * <start> * * > WAITING_FOR_REGISTER --------\ + * | * (watch not registered) | + * | * | + * | * * > WAITING_FOR_PEER ------------\ + * | * (request_lock busy) | + * | * | + * | * * * * * * * * * * * * * * | + * | * | + * v (init) (try_lock/request_lock) * | + * UNINITIALIZED -------> UNLOCKED ------------------------> ACQUIRING <--/ + * ^ | + * | v + * RELEASING POST_ACQUIRING + * | | + * | | + * | (release_lock) v + * PRE_RELEASING <------------------------ LOCKED + * + * <LOCKED state> + * | + * v + * REACQUIRING -------------------------------------> <finish> + * . ^ + * . | + * . . . > <RELEASE action> ---> <ACQUIRE action> ---/ + * + * <UNLOCKED/LOCKED states> + * | + * | + * v + * PRE_SHUTTING_DOWN ---> SHUTTING_DOWN ---> SHUTDOWN ---> <finish> + * + * @endverbatim + */ + + ImageCtxT& m_image_ctx; + exclusive_lock::ImageDispatch<ImageCtxT>* m_image_dispatch = nullptr; + Context *m_pre_post_callback = nullptr; + + AsyncOpTracker m_async_op_tracker; + + uint32_t m_request_blocked_count = 0; + int m_request_blocked_ret_val = 0; + + int m_acquire_lock_peer_ret_val = 0; + + bool accept_ops(const ceph::mutex &lock) const; + + void handle_post_acquiring_lock(int r); + void handle_post_acquired_lock(int r); +}; + +} // namespace librbd + +#endif // CEPH_LIBRBD_EXCLUSIVE_LOCK_H |