]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
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_RWL_LOG_ENTRY_H | |
5 | #define CEPH_LIBRBD_CACHE_RWL_LOG_ENTRY_H | |
6 | ||
7 | #include "common/ceph_mutex.h" | |
8 | #include "librbd/Utils.h" | |
9 | #include "librbd/cache/rwl/Types.h" | |
10 | #include <atomic> | |
11 | #include <memory> | |
12 | ||
13 | namespace librbd { | |
14 | namespace cache { | |
15 | namespace rwl { | |
16 | ||
17 | class SyncPointLogEntry; | |
18 | class GenericWriteLogEntry; | |
19 | class WriteLogEntry; | |
20 | ||
21 | class GenericLogEntry { | |
22 | public: | |
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) { | |
29 | }; | |
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); | |
36 | }; | |
37 | ||
38 | class SyncPointLogEntry : public GenericLogEntry { | |
39 | public: | |
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; | |
54 | }; | |
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); | |
61 | }; | |
62 | ||
63 | class GenericWriteLogEntry : public GenericLogEntry { | |
64 | public: | |
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; | |
80 | }; | |
81 | virtual inline unsigned int bytes_dirty() { | |
82 | /* The bytes in the image this op makes dirty. Discard and WS override. */ | |
83 | return write_bytes(); | |
84 | }; | |
85 | BlockExtent block_extent() { | |
86 | return ram_entry.block_extent(); | |
87 | } | |
88 | uint32_t get_map_ref() { | |
89 | return(referring_map_entries); | |
90 | } | |
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); | |
96 | }; | |
97 | ||
98 | class WriteLogEntry : public GenericWriteLogEntry { | |
99 | protected: | |
100 | buffer::ptr pmem_bp; | |
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; | |
105 | ||
106 | void init_pmem_bp(); | |
107 | ||
108 | /* Write same will override */ | |
109 | virtual void init_bl(buffer::ptr &bp, buffer::list &bl) { | |
110 | bl.append(bp); | |
111 | } | |
112 | ||
113 | void init_pmem_bl(); | |
114 | ||
115 | public: | |
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))) | |
122 | { } | |
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))) | |
127 | { } | |
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); | |
142 | }; | |
143 | ||
144 | } // namespace rwl | |
145 | } // namespace cache | |
146 | } // namespace librbd | |
147 | ||
148 | #endif // CEPH_LIBRBD_CACHE_RWL_LOG_ENTRY_H |