--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "SyncPoint.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::cache::rwl::SyncPoint: " << this << " " \
+ << __func__ << ": "
+
+namespace librbd {
+namespace cache {
+namespace rwl {
+
+template <typename T>
+SyncPoint<T>::SyncPoint(T &rwl, const uint64_t sync_gen_num)
+ : rwl(rwl), log_entry(std::make_shared<SyncPointLogEntry>(sync_gen_num)) {
+ prior_log_entries_persisted = new C_Gather(rwl.m_image_ctx.cct, nullptr);
+ sync_point_persist = new C_Gather(rwl.m_image_ctx.cct, nullptr);
+ on_sync_point_appending.reserve(MAX_WRITES_PER_SYNC_POINT + 2);
+ on_sync_point_persisted.reserve(MAX_WRITES_PER_SYNC_POINT + 2);
+ if (RWL_VERBOSE_LOGGING) {
+ ldout(rwl.m_image_ctx.cct, 20) << "sync point " << sync_gen_num << dendl;
+ }
+}
+
+template <typename T>
+SyncPoint<T>::~SyncPoint() {
+ assert(on_sync_point_appending.empty());
+ assert(on_sync_point_persisted.empty());
+ assert(!earlier_sync_point);
+}
+
+template <typename T>
+std::ostream &SyncPoint<T>::format(std::ostream &os) const {
+ os << "log_entry=[" << *log_entry << "], "
+ << "earlier_sync_point=" << earlier_sync_point << ", "
+ << "later_sync_point=" << later_sync_point << ", "
+ << "final_op_sequence_num=" << final_op_sequence_num << ", "
+ << "prior_log_entries_persisted=" << prior_log_entries_persisted << ", "
+ << "prior_log_entries_persisted_complete=" << prior_log_entries_persisted_complete << ", "
+ << "append_scheduled=" << append_scheduled << ", "
+ << "appending=" << appending << ", "
+ << "on_sync_point_appending=" << on_sync_point_appending.size() << ", "
+ << "on_sync_point_persisted=" << on_sync_point_persisted.size() << "";
+ return os;
+};
+
+} // namespace rwl
+} // namespace cache
+} // namespace librbd
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_CACHE_RWL_SYNC_POINT_H
+#define CEPH_LIBRBD_CACHE_RWL_SYNC_POINT_H
+
+#include "librbd/ImageCtx.h"
+#include "librbd/cache/rwl/LogEntry.h"
+#include "librbd/cache/rwl/Types.h"
+
+namespace librbd {
+namespace cache {
+namespace rwl {
+/* Limit work between sync points */
+static const uint64_t MAX_WRITES_PER_SYNC_POINT = 256;
+
+template <typename T>
+class SyncPoint {
+public:
+ T &rwl;
+ std::shared_ptr<SyncPointLogEntry> log_entry;
+ /* Use m_lock for earlier/later links */
+ std::shared_ptr<SyncPoint<T>> earlier_sync_point; /* NULL if earlier has completed */
+ std::shared_ptr<SyncPoint<T>> later_sync_point;
+ uint64_t final_op_sequence_num = 0;
+ /* A sync point can't appear in the log until all the writes bearing
+ * it and all the prior sync points have been appended and
+ * persisted.
+ *
+ * Writes bearing this sync gen number and the prior sync point will be
+ * sub-ops of this Gather. This sync point will not be appended until all
+ * these complete to the point where their persist order is guaranteed. */
+ C_Gather *prior_log_entries_persisted;
+ int prior_log_entries_persisted_result = 0;
+ int prior_log_entries_persisted_complete = false;
+ /* The finisher for this will append the sync point to the log. The finisher
+ * for m_prior_log_entries_persisted will be a sub-op of this. */
+ C_Gather *sync_point_persist;
+ bool append_scheduled = false;
+ bool appending = false;
+ /* Signal these when this sync point is appending to the log, and its order
+ * of appearance is guaranteed. One of these is is a sub-operation of the
+ * next sync point's m_prior_log_entries_persisted Gather. */
+ std::vector<Context*> on_sync_point_appending;
+ /* Signal these when this sync point is appended and persisted. User
+ * aio_flush() calls are added to this. */
+ std::vector<Context*> on_sync_point_persisted;
+
+ SyncPoint(T &rwl, const uint64_t sync_gen_num);
+ ~SyncPoint();
+ SyncPoint(const SyncPoint&) = delete;
+ SyncPoint &operator=(const SyncPoint&) = delete;
+ std::ostream &format(std::ostream &os) const;
+ friend std::ostream &operator<<(std::ostream &os,
+ const SyncPoint &p) {
+ return p.format(os);
+ }
+};
+
+} // namespace rwl
+} // namespace cache
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_CACHE_RWL_SYNC_POINT_H