]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/cache/pwl/LogEntry.h
b29d7fb88bcb3439fd2da04f53d90ef19c3055b7
[ceph.git] / ceph / src / librbd / cache / pwl / LogEntry.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_CACHE_PWL_LOG_ENTRY_H
5 #define CEPH_LIBRBD_CACHE_PWL_LOG_ENTRY_H
6
7 #include "common/ceph_mutex.h"
8 #include "librbd/Utils.h"
9 #include "librbd/cache/pwl/Types.h"
10 #include <atomic>
11 #include <memory>
12
13 namespace librbd {
14 namespace cache {
15 class ImageWritebackInterface;
16 namespace pwl {
17
18 class SyncPointLogEntry;
19 class GenericWriteLogEntry;
20 class WriteLogEntry;
21
22 typedef std::list<std::shared_ptr<GenericWriteLogEntry>> GenericWriteLogEntries;
23
24 class GenericLogEntry {
25 public:
26 WriteLogCacheEntry ram_entry;
27 WriteLogCacheEntry *cache_entry = nullptr;
28 uint32_t log_entry_index = 0;
29 bool completed = false;
30 GenericLogEntry(uint64_t image_offset_bytes = 0, uint64_t write_bytes = 0)
31 : ram_entry(image_offset_bytes, write_bytes) {
32 };
33 virtual ~GenericLogEntry() { };
34 GenericLogEntry(const GenericLogEntry&) = delete;
35 GenericLogEntry &operator=(const GenericLogEntry&) = delete;
36 virtual bool can_writeback() const {
37 return false;
38 }
39 virtual bool can_retire() const {
40 return false;
41 }
42 virtual void set_flushed(bool flushed) {
43 ceph_assert(false);
44 }
45 virtual unsigned int write_bytes() const {
46 return 0;
47 };
48 virtual unsigned int bytes_dirty() const {
49 return 0;
50 };
51 virtual std::shared_ptr<SyncPointLogEntry> get_sync_point_entry() {
52 return nullptr;
53 }
54 virtual void writeback(librbd::cache::ImageWritebackInterface &image_writeback,
55 Context *ctx) {
56 ceph_assert(false);
57 };
58 virtual void writeback_bl(librbd::cache::ImageWritebackInterface &image_writeback,
59 Context *ctx, ceph::bufferlist &&bl) {
60 ceph_assert(false);
61 }
62 virtual bool is_write_entry() const {
63 return false;
64 }
65 virtual bool is_writesame_entry() const {
66 return false;
67 }
68 virtual bool is_sync_point() const {
69 return false;
70 }
71 virtual unsigned int get_aligned_data_size() const {
72 return 0;
73 }
74 virtual void remove_cache_bl() {}
75 virtual std::ostream& format(std::ostream &os) const;
76 friend std::ostream &operator<<(std::ostream &os,
77 const GenericLogEntry &entry);
78 };
79
80 class SyncPointLogEntry : public GenericLogEntry {
81 public:
82 /* Writing entries using this sync gen number */
83 std::atomic<unsigned int> writes = {0};
84 /* Total bytes for all writing entries using this sync gen number */
85 std::atomic<uint64_t> bytes = {0};
86 /* Writing entries using this sync gen number that have completed */
87 std::atomic<unsigned int> writes_completed = {0};
88 /* Writing entries using this sync gen number that have completed flushing to the writeback interface */
89 std::atomic<unsigned int> writes_flushed = {0};
90 /* All writing entries using all prior sync gen numbers have been flushed */
91 std::atomic<bool> prior_sync_point_flushed = {true};
92 std::shared_ptr<SyncPointLogEntry> next_sync_point_entry = nullptr;
93 SyncPointLogEntry(uint64_t sync_gen_number) {
94 ram_entry.sync_gen_number = sync_gen_number;
95 ram_entry.sync_point = 1;
96 };
97 ~SyncPointLogEntry() override {};
98 SyncPointLogEntry(const SyncPointLogEntry&) = delete;
99 SyncPointLogEntry &operator=(const SyncPointLogEntry&) = delete;
100 bool can_retire() const override {
101 return this->completed;
102 }
103 bool is_sync_point() const override {
104 return true;
105 }
106 std::ostream& format(std::ostream &os) const;
107 friend std::ostream &operator<<(std::ostream &os,
108 const SyncPointLogEntry &entry);
109 };
110
111 class GenericWriteLogEntry : public GenericLogEntry {
112 public:
113 uint32_t referring_map_entries = 0;
114 std::shared_ptr<SyncPointLogEntry> sync_point_entry;
115 GenericWriteLogEntry(std::shared_ptr<SyncPointLogEntry> sync_point_entry,
116 uint64_t image_offset_bytes, uint64_t write_bytes)
117 : GenericLogEntry(image_offset_bytes, write_bytes), sync_point_entry(sync_point_entry) { }
118 GenericWriteLogEntry(uint64_t image_offset_bytes, uint64_t write_bytes)
119 : GenericLogEntry(image_offset_bytes, write_bytes), sync_point_entry(nullptr) { }
120 ~GenericWriteLogEntry() override {};
121 GenericWriteLogEntry(const GenericWriteLogEntry&) = delete;
122 GenericWriteLogEntry &operator=(const GenericWriteLogEntry&) = delete;
123 unsigned int write_bytes() const override {
124 /* The valid bytes in this ops data buffer. Discard and WS override. */
125 return ram_entry.write_bytes;
126 };
127 unsigned int bytes_dirty() const override {
128 /* The bytes in the image this op makes dirty. Discard and WS override. */
129 return write_bytes();
130 };
131 BlockExtent block_extent() {
132 return ram_entry.block_extent();
133 }
134 uint32_t get_map_ref() {
135 return(referring_map_entries);
136 }
137 void inc_map_ref() { referring_map_entries++; }
138 void dec_map_ref() { referring_map_entries--; }
139 bool can_writeback() const override;
140 std::shared_ptr<SyncPointLogEntry> get_sync_point_entry() override {
141 return sync_point_entry;
142 }
143 virtual void copy_cache_bl(bufferlist *out_bl) = 0;
144 void set_flushed(bool flushed) override {
145 m_flushed = flushed;
146 }
147 bool get_flushed() const {
148 return m_flushed;
149 }
150 std::ostream &format(std::ostream &os) const;
151 friend std::ostream &operator<<(std::ostream &os,
152 const GenericWriteLogEntry &entry);
153
154 private:
155 bool m_flushed = false; /* or invalidated */
156 };
157
158 class WriteLogEntry : public GenericWriteLogEntry {
159 protected:
160 bool is_writesame = false;
161 buffer::ptr cache_bp;
162 buffer::list cache_bl;
163 std::atomic<int> bl_refs = {0}; /* The refs held on cache_bp by cache_bl */
164 /* Used in WriteLogEntry::get_cache_bl() to syncronize between threads making entries readable */
165 mutable ceph::mutex m_entry_bl_lock;
166
167 virtual void init_cache_bp() {}
168
169 virtual void init_bl(buffer::ptr &bp, buffer::list &bl) {}
170 public:
171 uint8_t *cache_buffer = nullptr;
172 WriteLogEntry(std::shared_ptr<SyncPointLogEntry> sync_point_entry,
173 uint64_t image_offset_bytes, uint64_t write_bytes)
174 : GenericWriteLogEntry(sync_point_entry, image_offset_bytes, write_bytes),
175 m_entry_bl_lock(ceph::make_mutex(pwl::unique_lock_name(
176 "librbd::cache::pwl::WriteLogEntry::m_entry_bl_lock", this)))
177 { }
178 WriteLogEntry(uint64_t image_offset_bytes, uint64_t write_bytes)
179 : GenericWriteLogEntry(nullptr, image_offset_bytes, write_bytes),
180 m_entry_bl_lock(ceph::make_mutex(pwl::unique_lock_name(
181 "librbd::cache::pwl::WriteLogEntry::m_entry_bl_lock", this)))
182 { }
183 WriteLogEntry(std::shared_ptr<SyncPointLogEntry> sync_point_entry,
184 uint64_t image_offset_bytes, uint64_t write_bytes,
185 uint32_t data_length)
186 : WriteLogEntry(sync_point_entry, image_offset_bytes, write_bytes) {
187 ram_entry.writesame = 1;
188 ram_entry.ws_datalen = data_length;
189 is_writesame = true;
190 };
191 WriteLogEntry(uint64_t image_offset_bytes, uint64_t write_bytes,
192 uint32_t data_length)
193 : WriteLogEntry(nullptr, image_offset_bytes, write_bytes) {
194 ram_entry.writesame = 1;
195 ram_entry.ws_datalen = data_length;
196 is_writesame = true;
197 };
198 ~WriteLogEntry() override {};
199 WriteLogEntry(const WriteLogEntry&) = delete;
200 WriteLogEntry &operator=(const WriteLogEntry&) = delete;
201 unsigned int write_bytes() const override {
202 // The valid bytes in this ops data buffer.
203 if(is_writesame) {
204 return ram_entry.ws_datalen;
205 }
206 return ram_entry.write_bytes;
207 };
208 unsigned int bytes_dirty() const override {
209 // The bytes in the image this op makes dirty.
210 return ram_entry.write_bytes;
211 };
212 void init(bool has_data,
213 uint64_t current_sync_gen, uint64_t last_op_sequence_num, bool persist_on_flush);
214 virtual void init_cache_buffer(std::vector<WriteBufferAllocation>::iterator allocation) {}
215 virtual void init_cache_bl(bufferlist &src_bl, uint64_t off, uint64_t len) {}
216 /* Returns a ref to a bl containing bufferptrs to the entry cache buffer */
217 virtual buffer::list &get_cache_bl() = 0;
218
219 BlockExtent block_extent();
220 unsigned int reader_count() const;
221 /* Constructs a new bl containing copies of cache_bp */
222 void copy_cache_bl(bufferlist *out_bl) override {};
223 bool can_retire() const override {
224 return (this->completed && this->get_flushed() && (0 == reader_count()));
225 }
226 bool is_write_entry() const override {
227 return true;
228 }
229 bool is_writesame_entry() const override {
230 return is_writesame;
231 }
232 std::ostream &format(std::ostream &os) const;
233 friend std::ostream &operator<<(std::ostream &os,
234 const WriteLogEntry &entry);
235 };
236
237 class DiscardLogEntry : public GenericWriteLogEntry {
238 public:
239 DiscardLogEntry(std::shared_ptr<SyncPointLogEntry> sync_point_entry,
240 uint64_t image_offset_bytes, uint64_t write_bytes,
241 uint32_t discard_granularity_bytes)
242 : GenericWriteLogEntry(sync_point_entry, image_offset_bytes, write_bytes),
243 m_discard_granularity_bytes(discard_granularity_bytes) {
244 ram_entry.discard = 1;
245 };
246 DiscardLogEntry(uint64_t image_offset_bytes, uint64_t write_bytes)
247 : GenericWriteLogEntry(nullptr, image_offset_bytes, write_bytes) {
248 ram_entry.discard = 1;
249 };
250 DiscardLogEntry(const DiscardLogEntry&) = delete;
251 DiscardLogEntry &operator=(const DiscardLogEntry&) = delete;
252 unsigned int write_bytes() const override {
253 /* The valid bytes in this ops data buffer. */
254 return 0;
255 };
256 unsigned int bytes_dirty() const override {
257 /* The bytes in the image this op makes dirty. */
258 return ram_entry.write_bytes;
259 };
260 bool can_retire() const override {
261 return this->completed;
262 }
263 void copy_cache_bl(bufferlist *out_bl) override {
264 ceph_assert(false);
265 }
266 void writeback(librbd::cache::ImageWritebackInterface &image_writeback,
267 Context *ctx) override;
268 void init(uint64_t current_sync_gen, bool persist_on_flush, uint64_t last_op_sequence_num);
269 std::ostream &format(std::ostream &os) const;
270 friend std::ostream &operator<<(std::ostream &os,
271 const DiscardLogEntry &entry);
272 private:
273 uint32_t m_discard_granularity_bytes;
274 };
275
276 } // namespace pwl
277 } // namespace cache
278 } // namespace librbd
279
280 #endif // CEPH_LIBRBD_CACHE_PWL_LOG_ENTRY_H