From aa88a3f431233fdce014dbd1b6436c8787d169ec Mon Sep 17 00:00:00 2001 From: Yuan Lu Date: Tue, 14 Apr 2020 14:57:23 +0800 Subject: [PATCH] librbd: add ReadRequest to handle read Signed-off-by: Peterson, Scott Signed-off-by: Li, Xiaoyan Signed-off-by: Lu, Yuan Signed-off-by: Chamarthy, Mahati --- src/librbd/cache/rwl/Request.cc | 51 +++++++++++++++++++++++++++++++++ src/librbd/cache/rwl/Request.h | 25 ++++++++++++++++ src/librbd/cache/rwl/Types.h | 12 ++++++++ 3 files changed, 88 insertions(+) diff --git a/src/librbd/cache/rwl/Request.cc b/src/librbd/cache/rwl/Request.cc index e47c840b4e4..69783289409 100644 --- a/src/librbd/cache/rwl/Request.cc +++ b/src/librbd/cache/rwl/Request.cc @@ -403,6 +403,57 @@ std::ostream &operator<<(std::ostream &os, return os; }; +void C_ReadRequest::finish(int r) { + ldout(m_cct, 20) << "(" << get_name() << "): r=" << r << dendl; + int hits = 0; + int misses = 0; + int hit_bytes = 0; + int miss_bytes = 0; + if (r >= 0) { + /* + * At this point the miss read has completed. We'll iterate through + * read_extents and produce *m_out_bl by assembling pieces of miss_bl + * and the individual hit extent bufs in the read extents that represent + * hits. + */ + uint64_t miss_bl_offset = 0; + for (auto &extent : read_extents) { + if (extent.m_bl.length()) { + /* This was a hit */ + ceph_assert(extent.second == extent.m_bl.length()); + ++hits; + hit_bytes += extent.second; + m_out_bl->claim_append(extent.m_bl); + } else { + /* This was a miss. */ + ++misses; + miss_bytes += extent.second; + bufferlist miss_extent_bl; + miss_extent_bl.substr_of(miss_bl, miss_bl_offset, extent.second); + /* Add this read miss bufferlist to the output bufferlist */ + m_out_bl->claim_append(miss_extent_bl); + /* Consume these bytes in the read miss bufferlist */ + miss_bl_offset += extent.second; + } + } + } + ldout(m_cct, 20) << "(" << get_name() << "): r=" << r << " bl=" << *m_out_bl << dendl; + utime_t now = ceph_clock_now(); + ceph_assert((int)m_out_bl->length() == hit_bytes + miss_bytes); + m_on_finish->complete(r); + m_perfcounter->inc(l_librbd_rwl_rd_bytes, hit_bytes + miss_bytes); + m_perfcounter->inc(l_librbd_rwl_rd_hit_bytes, hit_bytes); + m_perfcounter->tinc(l_librbd_rwl_rd_latency, now - m_arrived_time); + if (!misses) { + m_perfcounter->inc(l_librbd_rwl_rd_hit_req, 1); + m_perfcounter->tinc(l_librbd_rwl_rd_hit_latency, now - m_arrived_time); + } else { + if (hits) { + m_perfcounter->inc(l_librbd_rwl_rd_part_hit_req, 1); + } + } +} + 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 79b0f9cd9bb..5426f7950ba 100644 --- a/src/librbd/cache/rwl/Request.h +++ b/src/librbd/cache/rwl/Request.h @@ -231,6 +231,31 @@ private: const C_FlushRequest &req); }; +class C_ReadRequest : public Context { +public: + io::Extents miss_extents; // move back to caller + ImageExtentBufs read_extents; + bufferlist miss_bl; + + C_ReadRequest(CephContext *cct, utime_t arrived, PerfCounters *perfcounter, bufferlist *out_bl, Context *on_finish) + : m_cct(cct), m_on_finish(on_finish), m_out_bl(out_bl), + m_arrived_time(arrived), m_perfcounter(perfcounter) {} + ~C_ReadRequest() {} + + void finish(int r) override; + + const char *get_name() const { + return "C_ReadRequest"; + } + +private: + CephContext *m_cct; + Context *m_on_finish; + bufferlist *m_out_bl; + utime_t m_arrived_time; + PerfCounters *m_perfcounter; +}; + struct BlockGuardReqState { bool barrier = false; /* This is a barrier request */ bool current_barrier = false; /* This is the currently active barrier */ diff --git a/src/librbd/cache/rwl/Types.h b/src/librbd/cache/rwl/Types.h index 48df0edf432..a894aaa8110 100644 --- a/src/librbd/cache/rwl/Types.h +++ b/src/librbd/cache/rwl/Types.h @@ -141,6 +141,9 @@ namespace librbd { namespace cache { namespace rwl { +class ImageExtentBuf; +typedef std::vector ImageExtentBufs; + const int IN_FLIGHT_FLUSH_WRITE_LIMIT = 64; const int IN_FLIGHT_FLUSH_BYTES_LIMIT = (1 * 1024 * 1024); @@ -265,6 +268,15 @@ BlockExtent block_extent(const io::Extent& image_extent); Context * override_ctx(int r, Context *ctx); +class ImageExtentBuf : public io::Extent { +public: + bufferlist m_bl; + ImageExtentBuf(io::Extent extent) + : io::Extent(extent) { } + ImageExtentBuf(io::Extent extent, bufferlist bl) + : io::Extent(extent), m_bl(bl) { } +}; + } // namespace rwl } // namespace cache } // namespace librbd