From: Yuan Lu Date: Tue, 11 Feb 2020 08:08:32 +0000 (+0800) Subject: librbd: add FlushRequest to handle flush X-Git-Tag: v17.0.0~2733^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=07fb05a6584b6f5066c22a9c461c8703da2ea9e7;p=ceph.git librbd: add FlushRequest to handle flush Signed-off-by: Peterson, Scott Signed-off-by: Li, Xiaoyan Signed-off-by: Lu, Yuan Signed-off-by: Chamarthy, Mahati --- diff --git a/src/librbd/cache/rwl/Request.cc b/src/librbd/cache/rwl/Request.cc index 6dd46fe8e07da..fc9b6f52eae26 100644 --- a/src/librbd/cache/rwl/Request.cc +++ b/src/librbd/cache/rwl/Request.cc @@ -321,6 +321,71 @@ void C_WriteRequest::dispatch() } } +template +C_FlushRequest::C_FlushRequest(T &rwl, const utime_t arrived, + io::Extents &&image_extents, + bufferlist&& bl, const int fadvise_flags, + ceph::mutex &lock, PerfCounters *perfcounter, + Context *user_req) + : C_BlockIORequest(rwl, arrived, std::move(image_extents), std::move(bl), + fadvise_flags, user_req), + m_lock(lock), m_perfcounter(perfcounter) { + ldout(rwl.get_context(), 20) << this << dendl; +} + +template +void C_FlushRequest::finish_req(int r) { + ldout(rwl.get_context(), 20) << "flush_req=" << this + << " cell=" << this->get_cell() << dendl; + /* Block guard already released */ + ceph_assert(!this->get_cell()); + + /* Completed to caller by here */ + utime_t now = ceph_clock_now(); + m_perfcounter->tinc(l_librbd_rwl_aio_flush_latency, now - this->m_arrived_time); +} + +template +bool C_FlushRequest::alloc_resources() { + ldout(rwl.get_context(), 20) << "req type=" << get_name() << " " + << "req=[" << *this << "]" << dendl; + return rwl.alloc_resources(this); +} + +template +void C_FlushRequest::dispatch() { + utime_t now = ceph_clock_now(); + ldout(rwl.get_context(), 20) << "req type=" << get_name() << " " + << "req=[" << *this << "]" << dendl; + ceph_assert(this->m_resources.allocated); + this->m_dispatched_time = now; + + op = std::make_shared(m_lock, + to_append, + now, + m_perfcounter, + rwl.get_context()); + + m_perfcounter->inc(l_librbd_rwl_log_ops, 1); + rwl.schedule_append(op); +} + +template +void C_FlushRequest::setup_buffer_resources( + uint64_t &bytes_cached, uint64_t &bytes_dirtied, uint64_t &bytes_allocated, + uint64_t &number_lanes, uint64_t &number_log_entries, + uint64_t &number_unpublished_reserves) { + number_log_entries = 1; +} + +template +std::ostream &operator<<(std::ostream &os, + const C_FlushRequest &req) { + os << (C_BlockIORequest&)req + << " m_resources.allocated=" << req.m_resources.allocated; + return os; +}; + std::ostream &operator<<(std::ostream &os, const BlockGuardReqState &r) { os << "barrier=" << r.barrier << ", " diff --git a/src/librbd/cache/rwl/Request.h b/src/librbd/cache/rwl/Request.h index 595e06c4396d4..49794766e7897 100644 --- a/src/librbd/cache/rwl/Request.h +++ b/src/librbd/cache/rwl/Request.h @@ -182,6 +182,54 @@ private: const C_WriteRequest &req); }; +/** + * This is the custodian of the BlockGuard cell for this + * aio_flush. Block guard is released as soon as the new + * sync point (if required) is created. Subsequent IOs can + * proceed while this flush waits for prior IOs to complete + * and any required sync points to be persisted. + */ +template +class C_FlushRequest : public C_BlockIORequest { +public: + using C_BlockIORequest::rwl; + std::shared_ptr to_append; + + C_FlushRequest(T &rwl, const utime_t arrived, + io::Extents &&image_extents, + bufferlist&& bl, const int fadvise_flags, + ceph::mutex &lock, PerfCounters *perfcounter, + Context *user_req); + + ~C_FlushRequest() override {} + + bool alloc_resources() override; + + void dispatch() override; + + const char *get_name() const override { + return "C_FlushRequest"; + } + + void setup_buffer_resources( + uint64_t &bytes_cached, uint64_t &bytes_dirtied, uint64_t &bytes_allocated, + uint64_t &number_lanes, uint64_t &number_log_entries, + uint64_t &number_unpublished_reserves) override; +private: + std::shared_ptr op; + ceph::mutex &m_lock; + PerfCounters *m_perfcounter = nullptr; + + void finish_req(int r) override; + void deferred_handler() override { + m_perfcounter->inc(l_librbd_rwl_aio_flush_def, 1); + } + + template + friend std::ostream &operator<<(std::ostream &os, + const C_FlushRequest &req); +}; + struct BlockGuardReqState { bool barrier = false; /* This is a barrier request */ bool current_barrier = false; /* This is the currently active barrier */