]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/ObjectMap.h
import 15.2.5
[ceph.git] / ceph / src / librbd / ObjectMap.h
CommitLineData
7c673cae
FG
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"
11fdf7f2 9#include "include/rados/librados_fwd.hpp"
7c673cae 10#include "include/rbd/object_map_types.h"
f6b5b4d7 11#include "common/AsyncOpTracker.h"
7c673cae 12#include "common/bit_vector.hpp"
9f95a23c
TL
13#include "common/RWLock.h"
14#include "common/RefCountedObj.h"
7c673cae
FG
15#include "librbd/Utils.h"
16#include <boost/optional.hpp>
17
18class Context;
31f18b77 19namespace ZTracer { struct Trace; }
7c673cae
FG
20
21namespace librbd {
22
23template <typename Op> class BlockGuard;
24struct BlockGuardCell;
25class ImageCtx;
26
27template <typename ImageCtxT = ImageCtx>
9f95a23c 28class ObjectMap : public RefCountedObject {
7c673cae
FG
29public:
30 static ObjectMap *create(ImageCtxT &image_ctx, uint64_t snap_id) {
31 return new ObjectMap(image_ctx, snap_id);
32 }
33
34 ObjectMap(ImageCtxT &image_ctx, uint64_t snap_id);
35 ~ObjectMap();
36
37 static int aio_remove(librados::IoCtx &io_ctx, const std::string &image_id, librados::AioCompletion *c);
38 static std::string object_map_name(const std::string &image_id,
39 uint64_t snap_id);
40
41 static bool is_compatible(const file_layout_t& layout, uint64_t size);
42
7c673cae
FG
43 uint8_t operator[](uint64_t object_no) const;
44 inline uint64_t size() const {
9f95a23c 45 std::shared_lock locker{m_lock};
7c673cae
FG
46 return m_object_map.size();
47 }
48
9f95a23c
TL
49 inline void set_state(uint64_t object_no, uint8_t new_state,
50 const boost::optional<uint8_t> &current_state) {
51 std::unique_lock locker{m_lock};
52 ceph_assert(object_no < m_object_map.size());
53 if (current_state && m_object_map[object_no] != *current_state) {
54 return;
55 }
56 m_object_map[object_no] = new_state;
57 }
58
7c673cae
FG
59 void open(Context *on_finish);
60 void close(Context *on_finish);
b32b8144 61 bool set_object_map(ceph::BitVector<2> &target_object_map);
7c673cae 62 bool object_may_exist(uint64_t object_no) const;
11fdf7f2 63 bool object_may_not_exist(uint64_t object_no) const;
7c673cae
FG
64
65 void aio_save(Context *on_finish);
66 void aio_resize(uint64_t new_size, uint8_t default_object_state,
67 Context *on_finish);
68
69 template <typename T, void(T::*MF)(int) = &T::complete>
70 bool aio_update(uint64_t snap_id, uint64_t start_object_no, uint8_t new_state,
71 const boost::optional<uint8_t> &current_state,
91327a77
AA
72 const ZTracer::Trace &parent_trace, bool ignore_enoent,
73 T *callback_object) {
7c673cae 74 return aio_update<T, MF>(snap_id, start_object_no, start_object_no + 1,
31f18b77 75 new_state, current_state, parent_trace,
91327a77 76 ignore_enoent, callback_object);
7c673cae
FG
77 }
78
79 template <typename T, void(T::*MF)(int) = &T::complete>
80 bool aio_update(uint64_t snap_id, uint64_t start_object_no,
81 uint64_t end_object_no, uint8_t new_state,
82 const boost::optional<uint8_t> &current_state,
91327a77
AA
83 const ZTracer::Trace &parent_trace, bool ignore_enoent,
84 T *callback_object) {
11fdf7f2 85 ceph_assert(start_object_no < end_object_no);
9f95a23c
TL
86 std::unique_lock locker{m_lock};
87
7c673cae 88 if (snap_id == CEPH_NOSNAP) {
11fdf7f2
TL
89 end_object_no = std::min(end_object_no, m_object_map.size());
90 if (start_object_no >= end_object_no) {
91 return false;
92 }
93
3efd9988
FG
94 auto it = m_object_map.begin() + start_object_no;
95 auto end_it = m_object_map.begin() + end_object_no;
96 for (; it != end_it; ++it) {
97 if (update_required(it, new_state)) {
7c673cae
FG
98 break;
99 }
100 }
101
3efd9988 102 if (it == end_it) {
7c673cae
FG
103 return false;
104 }
105
f6b5b4d7 106 m_async_op_tracker.start_op();
7c673cae 107 UpdateOperation update_operation(start_object_no, end_object_no,
31f18b77 108 new_state, current_state, parent_trace,
91327a77 109 ignore_enoent,
7c673cae
FG
110 util::create_context_callback<T, MF>(
111 callback_object));
112 detained_aio_update(std::move(update_operation));
113 } else {
114 aio_update(snap_id, start_object_no, end_object_no, new_state,
91327a77 115 current_state, parent_trace, ignore_enoent,
7c673cae
FG
116 util::create_context_callback<T, MF>(callback_object));
117 }
118 return true;
119 }
120
121 void rollback(uint64_t snap_id, Context *on_finish);
122 void snapshot_add(uint64_t snap_id, Context *on_finish);
123 void snapshot_remove(uint64_t snap_id, Context *on_finish);
124
125private:
126 struct UpdateOperation {
127 uint64_t start_object_no;
128 uint64_t end_object_no;
129 uint8_t new_state;
130 boost::optional<uint8_t> current_state;
31f18b77 131 ZTracer::Trace parent_trace;
91327a77 132 bool ignore_enoent;
7c673cae
FG
133 Context *on_finish;
134
135 UpdateOperation(uint64_t start_object_no, uint64_t end_object_no,
136 uint8_t new_state,
137 const boost::optional<uint8_t> &current_state,
91327a77
AA
138 const ZTracer::Trace &parent_trace,
139 bool ignore_enoent, Context *on_finish)
7c673cae
FG
140 : start_object_no(start_object_no), end_object_no(end_object_no),
141 new_state(new_state), current_state(current_state),
91327a77
AA
142 parent_trace(parent_trace), ignore_enoent(ignore_enoent),
143 on_finish(on_finish) {
7c673cae
FG
144 }
145 };
146
147 typedef BlockGuard<UpdateOperation> UpdateGuard;
148
149 ImageCtxT &m_image_ctx;
7c673cae
FG
150 uint64_t m_snap_id;
151
9f95a23c
TL
152 mutable ceph::shared_mutex m_lock;
153 ceph::BitVector<2> m_object_map;
154
f6b5b4d7 155 AsyncOpTracker m_async_op_tracker;
7c673cae
FG
156 UpdateGuard *m_update_guard = nullptr;
157
158 void detained_aio_update(UpdateOperation &&update_operation);
159 void handle_detained_aio_update(BlockGuardCell *cell, int r,
160 Context *on_finish);
161
162 void aio_update(uint64_t snap_id, uint64_t start_object_no,
163 uint64_t end_object_no, uint8_t new_state,
164 const boost::optional<uint8_t> &current_state,
91327a77
AA
165 const ZTracer::Trace &parent_trace, bool ignore_enoent,
166 Context *on_finish);
3efd9988
FG
167 bool update_required(const ceph::BitVector<2>::Iterator &it,
168 uint8_t new_state);
7c673cae
FG
169
170};
171
172} // namespace librbd
173
174extern template class librbd::ObjectMap<librbd::ImageCtx>;
175
176#endif // CEPH_LIBRBD_OBJECT_MAP_H