]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/ObjectMap.h
update sources to 12.2.10
[ceph.git] / ceph / src / librbd / ObjectMap.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_LIBRBD_OBJECT_MAP_H
5 #define CEPH_LIBRBD_OBJECT_MAP_H
6
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>
13
14 class Context;
15 class RWLock;
16 namespace librados { class IoCtx; }
17 namespace ZTracer { struct Trace; }
18
19 namespace librbd {
20
21 template <typename Op> class BlockGuard;
22 struct BlockGuardCell;
23 class ImageCtx;
24
25 template <typename ImageCtxT = ImageCtx>
26 class ObjectMap {
27 public:
28 static ObjectMap *create(ImageCtxT &image_ctx, uint64_t snap_id) {
29 return new ObjectMap(image_ctx, snap_id);
30 }
31
32 ObjectMap(ImageCtxT &image_ctx, uint64_t snap_id);
33 ~ObjectMap();
34
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,
37 uint64_t snap_id);
38
39 static bool is_compatible(const file_layout_t& layout, uint64_t size);
40
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();
45 }
46
47 void open(Context *on_finish);
48 void close(Context *on_finish);
49 bool set_object_map(ceph::BitVector<2> &target_object_map);
50 bool object_may_exist(uint64_t object_no) const;
51
52 void aio_save(Context *on_finish);
53 void aio_resize(uint64_t new_size, uint8_t default_object_state,
54 Context *on_finish);
55
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> &current_state,
59 const ZTracer::Trace &parent_trace, bool ignore_enoent,
60 T *callback_object) {
61 return aio_update<T, MF>(snap_id, start_object_no, start_object_no + 1,
62 new_state, current_state, parent_trace,
63 ignore_enoent, callback_object);
64 }
65
66 template <typename T, void(T::*MF)(int) = &T::complete>
67 bool aio_update(uint64_t snap_id, uint64_t start_object_no,
68 uint64_t end_object_no, uint8_t new_state,
69 const boost::optional<uint8_t> &current_state,
70 const ZTracer::Trace &parent_trace, bool ignore_enoent,
71 T *callback_object) {
72 assert(start_object_no < end_object_no);
73 if (snap_id == CEPH_NOSNAP) {
74 auto it = m_object_map.begin() + start_object_no;
75 auto end_it = m_object_map.begin() + end_object_no;
76 for (; it != end_it; ++it) {
77 if (update_required(it, new_state)) {
78 break;
79 }
80 }
81
82 if (it == end_it) {
83 return false;
84 }
85
86 UpdateOperation update_operation(start_object_no, end_object_no,
87 new_state, current_state, parent_trace,
88 ignore_enoent,
89 util::create_context_callback<T, MF>(
90 callback_object));
91 detained_aio_update(std::move(update_operation));
92 } else {
93 aio_update(snap_id, start_object_no, end_object_no, new_state,
94 current_state, parent_trace, ignore_enoent,
95 util::create_context_callback<T, MF>(callback_object));
96 }
97 return true;
98 }
99
100 void rollback(uint64_t snap_id, Context *on_finish);
101 void snapshot_add(uint64_t snap_id, Context *on_finish);
102 void snapshot_remove(uint64_t snap_id, Context *on_finish);
103
104 private:
105 struct UpdateOperation {
106 uint64_t start_object_no;
107 uint64_t end_object_no;
108 uint8_t new_state;
109 boost::optional<uint8_t> current_state;
110 ZTracer::Trace parent_trace;
111 bool ignore_enoent;
112 Context *on_finish;
113
114 UpdateOperation(uint64_t start_object_no, uint64_t end_object_no,
115 uint8_t new_state,
116 const boost::optional<uint8_t> &current_state,
117 const ZTracer::Trace &parent_trace,
118 bool ignore_enoent, Context *on_finish)
119 : start_object_no(start_object_no), end_object_no(end_object_no),
120 new_state(new_state), current_state(current_state),
121 parent_trace(parent_trace), ignore_enoent(ignore_enoent),
122 on_finish(on_finish) {
123 }
124 };
125
126 typedef BlockGuard<UpdateOperation> UpdateGuard;
127
128 ImageCtxT &m_image_ctx;
129 ceph::BitVector<2> m_object_map;
130 uint64_t m_snap_id;
131
132 UpdateGuard *m_update_guard = nullptr;
133
134 void detained_aio_update(UpdateOperation &&update_operation);
135 void handle_detained_aio_update(BlockGuardCell *cell, int r,
136 Context *on_finish);
137
138 void aio_update(uint64_t snap_id, uint64_t start_object_no,
139 uint64_t end_object_no, uint8_t new_state,
140 const boost::optional<uint8_t> &current_state,
141 const ZTracer::Trace &parent_trace, bool ignore_enoent,
142 Context *on_finish);
143 bool update_required(const ceph::BitVector<2>::Iterator &it,
144 uint8_t new_state);
145
146 };
147
148 } // namespace librbd
149
150 extern template class librbd::ObjectMap<librbd::ImageCtx>;
151
152 #endif // CEPH_LIBRBD_OBJECT_MAP_H