]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "SyncPoint.h" | |
5 | ||
6 | #define dout_subsys ceph_subsys_rbd_pwl | |
7 | #undef dout_prefix | |
8 | #define dout_prefix *_dout << "librbd::cache::pwl::SyncPoint: " << this << " " \ | |
9 | << __func__ << ": " | |
10 | ||
11 | namespace librbd { | |
12 | namespace cache { | |
13 | namespace pwl { | |
14 | ||
15 | SyncPoint::SyncPoint(uint64_t sync_gen_num, CephContext *cct) | |
16 | : log_entry(std::make_shared<SyncPointLogEntry>(sync_gen_num)), m_cct(cct) { | |
17 | m_prior_log_entries_persisted = new C_Gather(cct, nullptr); | |
18 | m_sync_point_persist = new C_Gather(cct, nullptr); | |
19 | on_sync_point_appending.reserve(MAX_WRITES_PER_SYNC_POINT + 2); | |
20 | on_sync_point_persisted.reserve(MAX_WRITES_PER_SYNC_POINT + 2); | |
21 | ldout(m_cct, 20) << "sync point " << sync_gen_num << dendl; | |
22 | } | |
23 | ||
24 | SyncPoint::~SyncPoint() { | |
25 | ceph_assert(on_sync_point_appending.empty()); | |
26 | ceph_assert(on_sync_point_persisted.empty()); | |
27 | ceph_assert(!earlier_sync_point); | |
28 | } | |
29 | ||
30 | std::ostream &operator<<(std::ostream &os, | |
31 | const SyncPoint &p) { | |
20effc67 TL |
32 | os << "log_entry=[" << *p.log_entry |
33 | << "], earlier_sync_point=" << p.earlier_sync_point | |
34 | << ", later_sync_point=" << p.later_sync_point | |
35 | << ", m_final_op_sequence_num=" << p.m_final_op_sequence_num | |
36 | << ", m_prior_log_entries_persisted=" << p.m_prior_log_entries_persisted | |
37 | << ", m_prior_log_entries_persisted_complete=" << p.m_prior_log_entries_persisted_complete | |
38 | << ", m_append_scheduled=" << p.m_append_scheduled | |
39 | << ", appending=" << p.appending | |
40 | << ", on_sync_point_appending=" << p.on_sync_point_appending.size() | |
41 | << ", on_sync_point_persisted=" << p.on_sync_point_persisted.size(); | |
f67539c2 TL |
42 | return os; |
43 | } | |
44 | ||
45 | void SyncPoint::persist_gather_set_finisher(Context *ctx) { | |
46 | m_append_scheduled = true; | |
47 | /* All prior sync points that are still in this list must already be scheduled for append */ | |
48 | std::shared_ptr<SyncPoint> previous = earlier_sync_point; | |
49 | while (previous) { | |
50 | ceph_assert(previous->m_append_scheduled); | |
51 | previous = previous->earlier_sync_point; | |
52 | } | |
53 | ||
54 | m_sync_point_persist->set_finisher(ctx); | |
55 | } | |
56 | ||
57 | void SyncPoint::persist_gather_activate() { | |
58 | m_sync_point_persist->activate(); | |
59 | } | |
60 | ||
61 | Context* SyncPoint::persist_gather_new_sub() { | |
62 | return m_sync_point_persist->new_sub(); | |
63 | } | |
64 | ||
65 | void SyncPoint::prior_persisted_gather_activate() { | |
66 | m_prior_log_entries_persisted->activate(); | |
67 | } | |
68 | ||
69 | Context* SyncPoint::prior_persisted_gather_new_sub() { | |
70 | return m_prior_log_entries_persisted->new_sub(); | |
71 | } | |
72 | ||
73 | void SyncPoint::prior_persisted_gather_set_finisher() { | |
74 | Context *sync_point_persist_ready = persist_gather_new_sub(); | |
75 | std::shared_ptr<SyncPoint> sp = shared_from_this(); | |
76 | m_prior_log_entries_persisted-> | |
77 | set_finisher(new LambdaContext([this, sp, sync_point_persist_ready](int r) { | |
78 | ldout(m_cct, 20) << "Prior log entries persisted for sync point =[" | |
79 | << sp << "]" << dendl; | |
80 | sp->m_prior_log_entries_persisted_result = r; | |
81 | sp->m_prior_log_entries_persisted_complete = true; | |
82 | sync_point_persist_ready->complete(r); | |
83 | })); | |
84 | } | |
85 | ||
86 | void SyncPoint::add_in_on_persisted_ctxs(Context* ctx) { | |
87 | on_sync_point_persisted.push_back(ctx); | |
88 | } | |
89 | ||
90 | void SyncPoint::add_in_on_appending_ctxs(Context* ctx) { | |
91 | on_sync_point_appending.push_back(ctx); | |
92 | } | |
93 | ||
94 | void SyncPoint::setup_earlier_sync_point(std::shared_ptr<SyncPoint> sync_point, | |
95 | uint64_t last_op_sequence_num) { | |
96 | earlier_sync_point = sync_point; | |
97 | log_entry->prior_sync_point_flushed = false; | |
98 | earlier_sync_point->log_entry->next_sync_point_entry = log_entry; | |
99 | earlier_sync_point->later_sync_point = shared_from_this(); | |
100 | earlier_sync_point->m_final_op_sequence_num = last_op_sequence_num; | |
101 | if (!earlier_sync_point->appending) { | |
102 | /* Append of new sync point deferred until old sync point is appending */ | |
103 | earlier_sync_point->add_in_on_appending_ctxs(prior_persisted_gather_new_sub()); | |
104 | } | |
105 | } | |
106 | ||
107 | } // namespace pwl | |
108 | } // namespace cache | |
109 | } // namespace librbd |