1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_OBJECT_MAP_H
5 #define CEPH_LIBRBD_OBJECT_MAP_H
7 #include "include/int_types.h"
8 #include "include/fs_types.h"
9 #include "include/rbd/object_map_types.h"
10 #include "common/bit_vector.hpp"
11 #include "librbd/Utils.h"
12 #include <boost/optional.hpp>
16 namespace librados { class IoCtx; }
17 namespace ZTracer { struct Trace; }
21 template <typename Op> class BlockGuard;
22 struct BlockGuardCell;
25 template <typename ImageCtxT = ImageCtx>
28 static ObjectMap *create(ImageCtxT &image_ctx, uint64_t snap_id) {
29 return new ObjectMap(image_ctx, snap_id);
32 ObjectMap(ImageCtxT &image_ctx, uint64_t snap_id);
35 static int aio_remove(librados::IoCtx &io_ctx, const std::string &image_id, librados::AioCompletion *c);
36 static std::string object_map_name(const std::string &image_id,
39 static bool is_compatible(const file_layout_t& layout, uint64_t size);
41 ceph::BitVector<2u>::Reference operator[](uint64_t object_no);
42 uint8_t operator[](uint64_t object_no) const;
43 inline uint64_t size() const {
44 return m_object_map.size();
47 void open(Context *on_finish);
48 void close(Context *on_finish);
50 bool object_may_exist(uint64_t object_no) const;
52 void aio_save(Context *on_finish);
53 void aio_resize(uint64_t new_size, uint8_t default_object_state,
56 template <typename T, void(T::*MF)(int) = &T::complete>
57 bool aio_update(uint64_t snap_id, uint64_t start_object_no, uint8_t new_state,
58 const boost::optional<uint8_t> ¤t_state,
59 const ZTracer::Trace &parent_trace, T *callback_object) {
60 return aio_update<T, MF>(snap_id, start_object_no, start_object_no + 1,
61 new_state, current_state, parent_trace,
65 template <typename T, void(T::*MF)(int) = &T::complete>
66 bool aio_update(uint64_t snap_id, uint64_t start_object_no,
67 uint64_t end_object_no, uint8_t new_state,
68 const boost::optional<uint8_t> ¤t_state,
69 const ZTracer::Trace &parent_trace, T *callback_object) {
70 assert(start_object_no < end_object_no);
71 if (snap_id == CEPH_NOSNAP) {
72 auto it = m_object_map.begin() + start_object_no;
73 auto end_it = m_object_map.begin() + end_object_no;
74 for (; it != end_it; ++it) {
75 if (update_required(it, new_state)) {
84 UpdateOperation update_operation(start_object_no, end_object_no,
85 new_state, current_state, parent_trace,
86 util::create_context_callback<T, MF>(
88 detained_aio_update(std::move(update_operation));
90 aio_update(snap_id, start_object_no, end_object_no, new_state,
91 current_state, parent_trace,
92 util::create_context_callback<T, MF>(callback_object));
97 void rollback(uint64_t snap_id, Context *on_finish);
98 void snapshot_add(uint64_t snap_id, Context *on_finish);
99 void snapshot_remove(uint64_t snap_id, Context *on_finish);
102 struct UpdateOperation {
103 uint64_t start_object_no;
104 uint64_t end_object_no;
106 boost::optional<uint8_t> current_state;
107 ZTracer::Trace parent_trace;
110 UpdateOperation(uint64_t start_object_no, uint64_t end_object_no,
112 const boost::optional<uint8_t> ¤t_state,
113 const ZTracer::Trace &parent_trace, Context *on_finish)
114 : start_object_no(start_object_no), end_object_no(end_object_no),
115 new_state(new_state), current_state(current_state),
116 parent_trace(parent_trace), on_finish(on_finish) {
120 typedef BlockGuard<UpdateOperation> UpdateGuard;
122 ImageCtxT &m_image_ctx;
123 ceph::BitVector<2> m_object_map;
126 UpdateGuard *m_update_guard = nullptr;
128 void detained_aio_update(UpdateOperation &&update_operation);
129 void handle_detained_aio_update(BlockGuardCell *cell, int r,
132 void aio_update(uint64_t snap_id, uint64_t start_object_no,
133 uint64_t end_object_no, uint8_t new_state,
134 const boost::optional<uint8_t> ¤t_state,
135 const ZTracer::Trace &parent_trace, Context *on_finish);
136 bool update_required(const ceph::BitVector<2>::Iterator &it,
141 } // namespace librbd
143 extern template class librbd::ObjectMap<librbd::ImageCtx>;
145 #endif // CEPH_LIBRBD_OBJECT_MAP_H