// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #ifndef CEPH_LIBRBD_IMAGE_REFRESH_REQUEST_H #define CEPH_LIBRBD_IMAGE_REFRESH_REQUEST_H #include "include/int_types.h" #include "include/buffer.h" #include "include/utime.h" #include "common/snap_types.h" #include "cls/lock/cls_lock_types.h" #include "librbd/ImageCtx.h" #include "librbd/Types.h" #include #include class Context; namespace librbd { class ImageCtx; namespace image { template class RefreshParentRequest; template class RefreshRequest { public: static RefreshRequest *create(ImageCtxT &image_ctx, bool acquiring_lock, bool skip_open_parent, Context *on_finish) { return new RefreshRequest(image_ctx, acquiring_lock, skip_open_parent, on_finish); } RefreshRequest(ImageCtxT &image_ctx, bool acquiring_lock, bool skip_open_parent, Context *on_finish); ~RefreshRequest(); void send(); private: /** * @verbatim * * * | * | (v1) * |-----> V1_READ_HEADER ---> V1_GET_SNAPSHOTS ---> V1_GET_LOCKS * | | * | (v2) v * \-----> V2_GET_MUTABLE_METADATA * | | * v | * V2_GET_FLAGS | * | | * v | * V2_GET_GROUP | * | | * v | * V2_GET_SNAPSHOTS (skip if no snaps) | * | | * v | * V2_GET_SNAP_TIMESTAMPS | * | | * v | * V2_GET_SNAP_NAMESPACES | * | | * v | * V2_REFRESH_PARENT (skip if no parent or | * | refresh not needed) | * v | * V2_INIT_EXCLUSIVE_LOCK (skip if lock | * | active or disabled) | * v | * V2_OPEN_OBJECT_MAP (skip if map | * | active or disabled) | * v | * V2_OPEN_JOURNAL (skip if journal | * | active or disabled) | * v | * V2_BLOCK_WRITES (skip if journal not | * | disabled) | * v | * | * | | * v | * V2_FINALIZE_REFRESH_PARENT (skip if refresh | * | not needed) | * (error) v | * * * * * > V2_SHUT_DOWN_EXCLUSIVE_LOCK (skip if lock | * | active or enabled) | * v | * V2_CLOSE_JOURNAL (skip if journal inactive | * | or enabled) | * v | * V2_CLOSE_OBJECT_MAP (skip if map inactive | * | or enabled) | * | | * \-------------------\/--------------------/ * | * v * FLUSH (skip if no new * | snapshots) * v * * * @endverbatim */ ImageCtxT &m_image_ctx; bool m_acquiring_lock; bool m_skip_open_parent_image; Context *m_on_finish; int m_error_result; bool m_flush_aio; decltype(m_image_ctx.exclusive_lock) m_exclusive_lock; decltype(m_image_ctx.object_map) m_object_map; decltype(m_image_ctx.journal) m_journal; RefreshParentRequest *m_refresh_parent; bufferlist m_out_bl; uint8_t m_order; uint64_t m_size; uint64_t m_features; uint64_t m_incompatible_features; uint64_t m_flags; std::string m_object_prefix; ParentInfo m_parent_md; cls::rbd::GroupSpec m_group_spec; ::SnapContext m_snapc; std::vector m_snap_names; std::vector m_snap_namespaces; std::vector m_snap_sizes; std::vector m_snap_parents; std::vector m_snap_protection; std::vector m_snap_flags; std::vector m_snap_timestamps; std::map m_lockers; std::string m_lock_tag; bool m_exclusive_locked; bool m_blocked_writes = false; bool m_incomplete_update = false; void send_v1_read_header(); Context *handle_v1_read_header(int *result); void send_v1_get_snapshots(); Context *handle_v1_get_snapshots(int *result); void send_v1_get_locks(); Context *handle_v1_get_locks(int *result); void send_v1_apply(); Context *handle_v1_apply(int *result); void send_v2_get_mutable_metadata(); Context *handle_v2_get_mutable_metadata(int *result); void send_v2_get_flags(); Context *handle_v2_get_flags(int *result); void send_v2_get_group(); Context *handle_v2_get_group(int *result); void send_v2_get_snapshots(); Context *handle_v2_get_snapshots(int *result); void send_v2_get_snap_namespaces(); Context *handle_v2_get_snap_namespaces(int *result); void send_v2_get_snap_timestamps(); Context *handle_v2_get_snap_timestamps(int *result); void send_v2_refresh_parent(); Context *handle_v2_refresh_parent(int *result); void send_v2_init_exclusive_lock(); Context *handle_v2_init_exclusive_lock(int *result); void send_v2_open_journal(); Context *handle_v2_open_journal(int *result); void send_v2_block_writes(); Context *handle_v2_block_writes(int *result); void send_v2_open_object_map(); Context *handle_v2_open_object_map(int *result); void send_v2_apply(); Context *handle_v2_apply(int *result); Context *send_v2_finalize_refresh_parent(); Context *handle_v2_finalize_refresh_parent(int *result); Context *send_v2_shut_down_exclusive_lock(); Context *handle_v2_shut_down_exclusive_lock(int *result); Context *send_v2_close_journal(); Context *handle_v2_close_journal(int *result); Context *send_v2_close_object_map(); Context *handle_v2_close_object_map(int *result); Context *send_flush_aio(); Context *handle_flush_aio(int *result); Context *handle_error(int *result); void save_result(int *result) { if (m_error_result == 0 && *result < 0) { m_error_result = *result; } } void apply(); int get_parent_info(uint64_t snap_id, ParentInfo *parent_md); }; } // namespace image } // namespace librbd extern template class librbd::image::RefreshRequest; #endif // CEPH_LIBRBD_IMAGE_REFRESH_REQUEST_H