Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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
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, 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,
62                              callback_object);
63   }
64
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> &current_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)) {
76           break;
77         }
78       }
79
80       if (it == end_it) {
81         return false;
82       }
83
84       UpdateOperation update_operation(start_object_no, end_object_no,
85                                        new_state, current_state, parent_trace,
86                                        util::create_context_callback<T, MF>(
87                                          callback_object));
88       detained_aio_update(std::move(update_operation));
89     } else {
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));
93     }
94     return true;
95   }
96
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);
100
101 private:
102   struct UpdateOperation {
103     uint64_t start_object_no;
104     uint64_t end_object_no;
105     uint8_t new_state;
106     boost::optional<uint8_t> current_state;
107     ZTracer::Trace parent_trace;
108     Context *on_finish;
109
110     UpdateOperation(uint64_t start_object_no, uint64_t end_object_no,
111                     uint8_t new_state,
112                     const boost::optional<uint8_t> &current_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) {
117     }
118   };
119
120   typedef BlockGuard<UpdateOperation> UpdateGuard;
121
122   ImageCtxT &m_image_ctx;
123   ceph::BitVector<2> m_object_map;
124   uint64_t m_snap_id;
125
126   UpdateGuard *m_update_guard = nullptr;
127
128   void detained_aio_update(UpdateOperation &&update_operation);
129   void handle_detained_aio_update(BlockGuardCell *cell, int r,
130                                   Context *on_finish);
131
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> &current_state,
135                   const ZTracer::Trace &parent_trace, Context *on_finish);
136   bool update_required(const ceph::BitVector<2>::Iterator &it,
137                        uint8_t new_state);
138
139 };
140
141 } // namespace librbd
142
143 extern template class librbd::ObjectMap<librbd::ImageCtx>;
144
145 #endif // CEPH_LIBRBD_OBJECT_MAP_H