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_CACHE_PWL_LOG_ENTRY_H
5 #define CEPH_LIBRBD_CACHE_PWL_LOG_ENTRY_H
7 #include "common/ceph_mutex.h"
8 #include "librbd/Utils.h"
9 #include "librbd/cache/pwl/Types.h"
15 class ImageWritebackInterface
;
18 class SyncPointLogEntry
;
19 class GenericWriteLogEntry
;
22 typedef std::list
<std::shared_ptr
<GenericWriteLogEntry
>> GenericWriteLogEntries
;
24 class GenericLogEntry
{
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
) {
33 virtual ~GenericLogEntry() { };
34 GenericLogEntry(const GenericLogEntry
&) = delete;
35 GenericLogEntry
&operator=(const GenericLogEntry
&) = delete;
36 virtual bool can_writeback() const {
39 virtual bool can_retire() const {
42 virtual void set_flushed(bool flushed
) {
45 virtual unsigned int write_bytes() const {
48 virtual unsigned int bytes_dirty() const {
51 virtual std::shared_ptr
<SyncPointLogEntry
> get_sync_point_entry() {
54 virtual void writeback(librbd::cache::ImageWritebackInterface
&image_writeback
,
58 virtual void writeback_bl(librbd::cache::ImageWritebackInterface
&image_writeback
,
59 Context
*ctx
, ceph::bufferlist
&&bl
) {
62 virtual bool is_write_entry() const {
65 virtual bool is_writesame_entry() const {
68 virtual bool is_sync_point() const {
71 virtual unsigned int get_aligned_data_size() const {
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
);
80 class SyncPointLogEntry
: public GenericLogEntry
{
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;
97 ~SyncPointLogEntry() override
{};
98 SyncPointLogEntry(const SyncPointLogEntry
&) = delete;
99 SyncPointLogEntry
&operator=(const SyncPointLogEntry
&) = delete;
100 bool can_retire() const override
{
101 return this->completed
;
103 bool is_sync_point() const override
{
106 std::ostream
& format(std::ostream
&os
) const;
107 friend std::ostream
&operator<<(std::ostream
&os
,
108 const SyncPointLogEntry
&entry
);
111 class GenericWriteLogEntry
: public GenericLogEntry
{
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
;
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();
131 BlockExtent
block_extent() {
132 return ram_entry
.block_extent();
134 uint32_t get_map_ref() {
135 return(referring_map_entries
);
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
;
143 virtual void copy_cache_bl(bufferlist
*out_bl
) = 0;
144 void set_flushed(bool flushed
) override
{
147 bool get_flushed() const {
150 std::ostream
&format(std::ostream
&os
) const;
151 friend std::ostream
&operator<<(std::ostream
&os
,
152 const GenericWriteLogEntry
&entry
);
155 bool m_flushed
= false; /* or invalidated */
158 class WriteLogEntry
: public GenericWriteLogEntry
{
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
;
167 virtual void init_cache_bp() {}
169 virtual void init_bl(buffer::ptr
&bp
, buffer::list
&bl
) {}
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)))
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)))
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
;
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
;
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.
204 return ram_entry
.ws_datalen
;
206 return ram_entry
.write_bytes
;
208 unsigned int bytes_dirty() const override
{
209 // The bytes in the image this op makes dirty.
210 return ram_entry
.write_bytes
;
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;
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()));
226 bool is_write_entry() const override
{
229 bool is_writesame_entry() const override
{
232 std::ostream
&format(std::ostream
&os
) const;
233 friend std::ostream
&operator<<(std::ostream
&os
,
234 const WriteLogEntry
&entry
);
237 class DiscardLogEntry
: public GenericWriteLogEntry
{
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;
246 DiscardLogEntry(uint64_t image_offset_bytes
, uint64_t write_bytes
)
247 : GenericWriteLogEntry(nullptr, image_offset_bytes
, write_bytes
) {
248 ram_entry
.discard
= 1;
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. */
256 unsigned int bytes_dirty() const override
{
257 /* The bytes in the image this op makes dirty. */
258 return ram_entry
.write_bytes
;
260 bool can_retire() const override
{
261 return this->completed
;
263 void copy_cache_bl(bufferlist
*out_bl
) override
{
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
);
273 uint32_t m_discard_granularity_bytes
;
278 } // namespace librbd
280 #endif // CEPH_LIBRBD_CACHE_PWL_LOG_ENTRY_H