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_RWL_LOG_ENTRY_H
5 #define CEPH_LIBRBD_CACHE_RWL_LOG_ENTRY_H
7 #include "common/ceph_mutex.h"
8 #include "librbd/Utils.h"
9 #include "librbd/cache/rwl/Types.h"
17 class SyncPointLogEntry
;
18 class GenericWriteLogEntry
;
21 class GenericLogEntry
{
23 WriteLogPmemEntry ram_entry
;
24 WriteLogPmemEntry
*pmem_entry
= nullptr;
25 uint32_t log_entry_index
= 0;
26 bool completed
= false;
27 GenericLogEntry(const uint64_t image_offset_bytes
= 0, const uint64_t write_bytes
= 0)
28 : ram_entry(image_offset_bytes
, write_bytes
) {
30 virtual ~GenericLogEntry() { };
31 GenericLogEntry(const GenericLogEntry
&) = delete;
32 GenericLogEntry
&operator=(const GenericLogEntry
&) = delete;
33 virtual std::ostream
& format(std::ostream
&os
) const;
34 friend std::ostream
&operator<<(std::ostream
&os
,
35 const GenericLogEntry
&entry
);
38 class SyncPointLogEntry
: public GenericLogEntry
{
40 /* Writing entries using this sync gen number */
41 std::atomic
<unsigned int> writes
= {0};
42 /* Total bytes for all writing entries using this sync gen number */
43 std::atomic
<uint64_t> bytes
= {0};
44 /* Writing entries using this sync gen number that have completed */
45 std::atomic
<unsigned int> writes_completed
= {0};
46 /* Writing entries using this sync gen number that have completed flushing to the writeback interface */
47 std::atomic
<unsigned int> writes_flushed
= {0};
48 /* All writing entries using all prior sync gen numbers have been flushed */
49 std::atomic
<bool> prior_sync_point_flushed
= {true};
50 std::shared_ptr
<SyncPointLogEntry
> next_sync_point_entry
= nullptr;
51 SyncPointLogEntry(const uint64_t sync_gen_number
) {
52 ram_entry
.sync_gen_number
= sync_gen_number
;
53 ram_entry
.sync_point
= 1;
55 ~SyncPointLogEntry() override
{};
56 SyncPointLogEntry(const SyncPointLogEntry
&) = delete;
57 SyncPointLogEntry
&operator=(const SyncPointLogEntry
&) = delete;
58 std::ostream
& format(std::ostream
&os
) const;
59 friend std::ostream
&operator<<(std::ostream
&os
,
60 const SyncPointLogEntry
&entry
);
63 class GenericWriteLogEntry
: public GenericLogEntry
{
65 uint32_t referring_map_entries
= 0;
66 bool flushing
= false;
67 bool flushed
= false; /* or invalidated */
68 std::shared_ptr
<SyncPointLogEntry
> sync_point_entry
;
69 GenericWriteLogEntry(std::shared_ptr
<SyncPointLogEntry
> sync_point_entry
,
70 const uint64_t image_offset_bytes
, const uint64_t write_bytes
)
71 : GenericLogEntry(image_offset_bytes
, write_bytes
), sync_point_entry(sync_point_entry
) { }
72 GenericWriteLogEntry(const uint64_t image_offset_bytes
, const uint64_t write_bytes
)
73 : GenericLogEntry(image_offset_bytes
, write_bytes
), sync_point_entry(nullptr) { }
74 ~GenericWriteLogEntry() override
{};
75 GenericWriteLogEntry(const GenericWriteLogEntry
&) = delete;
76 GenericWriteLogEntry
&operator=(const GenericWriteLogEntry
&) = delete;
77 inline unsigned int write_bytes() {
78 /* The valid bytes in this ops data buffer. Discard and WS override. */
79 return ram_entry
.write_bytes
;
81 virtual inline unsigned int bytes_dirty() {
82 /* The bytes in the image this op makes dirty. Discard and WS override. */
85 BlockExtent
block_extent() {
86 return ram_entry
.block_extent();
88 uint32_t get_map_ref() {
89 return(referring_map_entries
);
91 void inc_map_ref() { referring_map_entries
++; }
92 void dec_map_ref() { referring_map_entries
--; }
93 std::ostream
&format(std::ostream
&os
) const;
94 friend std::ostream
&operator<<(std::ostream
&os
,
95 const GenericWriteLogEntry
&entry
);
98 class WriteLogEntry
: public GenericWriteLogEntry
{
101 buffer::list pmem_bl
;
102 std::atomic
<int> bl_refs
= {0}; /* The refs held on pmem_bp by pmem_bl */
103 /* Used in WriteLogEntry::get_pmem_bl() to syncronize between threads making entries readable */
104 mutable ceph::mutex m_entry_bl_lock
;
108 /* Write same will override */
109 virtual void init_bl(buffer::ptr
&bp
, buffer::list
&bl
) {
116 uint8_t *pmem_buffer
= nullptr;
117 WriteLogEntry(std::shared_ptr
<SyncPointLogEntry
> sync_point_entry
,
118 const uint64_t image_offset_bytes
, const uint64_t write_bytes
)
119 : GenericWriteLogEntry(sync_point_entry
, image_offset_bytes
, write_bytes
),
120 m_entry_bl_lock(ceph::make_mutex(util::unique_lock_name(
121 "librbd::cache::rwl::WriteLogEntry::m_entry_bl_lock", this)))
123 WriteLogEntry(const uint64_t image_offset_bytes
, const uint64_t write_bytes
)
124 : GenericWriteLogEntry(nullptr, image_offset_bytes
, write_bytes
),
125 m_entry_bl_lock(ceph::make_mutex(util::unique_lock_name(
126 "librbd::cache::rwl::WriteLogEntry::m_entry_bl_lock", this)))
128 ~WriteLogEntry() override
{};
129 WriteLogEntry(const WriteLogEntry
&) = delete;
130 WriteLogEntry
&operator=(const WriteLogEntry
&) = delete;
131 void init(bool has_data
, std::vector
<WriteBufferAllocation
>::iterator allocation
,
132 uint64_t current_sync_gen
, uint64_t last_op_sequence_num
, bool persist_on_flush
);
133 BlockExtent
block_extent();
134 unsigned int reader_count();
135 /* Returns a ref to a bl containing bufferptrs to the entry pmem buffer */
136 buffer::list
&get_pmem_bl();
137 /* Constructs a new bl containing copies of pmem_bp */
138 void copy_pmem_bl(bufferlist
*out_bl
);
139 std::ostream
&format(std::ostream
&os
) const;
140 friend std::ostream
&operator<<(std::ostream
&os
,
141 const WriteLogEntry
&entry
);
146 } // namespace librbd
148 #endif // CEPH_LIBRBD_CACHE_RWL_LOG_ENTRY_H