From: Jason Dillaman Date: Wed, 27 Jul 2016 13:54:44 +0000 (-0400) Subject: librbd: move read callback helpers to narrowest scope X-Git-Tag: ses5-milestone5~226^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=65b336f68596a430629692a8682c5cfe883c31f1;p=ceph.git librbd: move read callback helpers to narrowest scope Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/AioCompletion.cc b/src/librbd/AioCompletion.cc index c5cb3a1bad0e..e4044fa82a54 100644 --- a/src/librbd/AioCompletion.cc +++ b/src/librbd/AioCompletion.cc @@ -9,7 +9,6 @@ #include "common/perf_counters.h" #include "common/WorkQueue.h" -#include "librbd/AioObjectRequest.h" #include "librbd/ImageCtx.h" #include "librbd/internal.h" @@ -222,46 +221,4 @@ ssize_t AioCompletion::get_return_value() { return r; } -void C_AioRead::finish(int r) -{ - m_completion->lock.Lock(); - CephContext *cct = m_completion->ictx->cct; - ldout(cct, 10) << "C_AioRead::finish() " << this << " r = " << r << dendl; - - if (r >= 0 || r == -ENOENT) { // this was a sparse_read operation - ldout(cct, 10) << " got " << m_req->m_ext_map - << " for " << m_req->m_buffer_extents - << " bl " << m_req->data().length() << dendl; - // reads from the parent don't populate the m_ext_map and the overlap - // may not be the full buffer. compensate here by filling in m_ext_map - // with the read extent when it is empty. - if (m_req->m_ext_map.empty()) - m_req->m_ext_map[m_req->m_object_off] = m_req->data().length(); - - m_completion->destriper.add_partial_sparse_result( - cct, m_req->data(), m_req->m_ext_map, m_req->m_object_off, - m_req->m_buffer_extents); - r = m_req->m_object_len; - } - m_completion->lock.Unlock(); - - C_AioRequest::finish(r); -} - -void C_CacheRead::complete(int r) { - if (!m_enqueued) { - // cache_lock creates a lock ordering issue -- so re-execute this context - // outside the cache_lock - m_enqueued = true; - m_image_ctx.op_work_queue->queue(this, r); - return; - } - Context::complete(r); -} - -void C_CacheRead::finish(int r) -{ - m_req->complete(r); -} - } // namespace librbd diff --git a/src/librbd/AioCompletion.h b/src/librbd/AioCompletion.h index 1ec87f4417cd..6a83677cd964 100644 --- a/src/librbd/AioCompletion.h +++ b/src/librbd/AioCompletion.h @@ -19,8 +19,6 @@ class CephContext; namespace librbd { -class AioObjectRead; - typedef enum { AIO_TYPE_NONE = 0, AIO_TYPE_OPEN, @@ -235,33 +233,6 @@ protected: AioCompletion *m_completion; }; -class C_AioRead : public C_AioRequest { -public: - C_AioRead(AioCompletion *completion) - : C_AioRequest(completion), m_req(nullptr) { - } - virtual ~C_AioRead() {} - virtual void finish(int r); - void set_req(AioObjectRead *req) { - m_req = req; - } -private: - AioObjectRead *m_req; -}; - -class C_CacheRead : public Context { -public: - explicit C_CacheRead(ImageCtx *ictx, AioObjectRead *req) - : m_image_ctx(*ictx), m_req(req), m_enqueued(false) {} - virtual void complete(int r); -protected: - virtual void finish(int r); -private: - ImageCtx &m_image_ctx; - AioObjectRead *m_req; - bool m_enqueued; -}; - } // namespace librbd #endif // CEPH_LIBRBD_AIO_COMPLETION_H diff --git a/src/librbd/AioImageRequest.cc b/src/librbd/AioImageRequest.cc index f7fb0a5d0499..c0a2b9b24ab5 100644 --- a/src/librbd/AioImageRequest.cc +++ b/src/librbd/AioImageRequest.cc @@ -10,6 +10,7 @@ #include "librbd/Utils.h" #include "librbd/journal/Types.h" #include "include/rados/librados.hpp" +#include "common/WorkQueue.h" #include "osdc/Striper.h" #define dout_subsys ceph_subsys_rbd @@ -77,6 +78,72 @@ struct C_FlushJournalCommit : public Context { } }; +class C_AioRead : public C_AioRequest { +public: + C_AioRead(AioCompletion *completion) + : C_AioRequest(completion), m_req(nullptr) { + } + + virtual void finish(int r) { + m_completion->lock.Lock(); + CephContext *cct = m_completion->ictx->cct; + ldout(cct, 10) << "C_AioRead::finish() " << this << " r = " << r << dendl; + + if (r >= 0 || r == -ENOENT) { // this was a sparse_read operation + ldout(cct, 10) << " got " << m_req->get_extent_map() + << " for " << m_req->get_buffer_extents() + << " bl " << m_req->data().length() << dendl; + // reads from the parent don't populate the m_ext_map and the overlap + // may not be the full buffer. compensate here by filling in m_ext_map + // with the read extent when it is empty. + if (m_req->get_extent_map().empty()) { + m_req->get_extent_map()[m_req->get_offset()] = m_req->data().length(); + } + + m_completion->destriper.add_partial_sparse_result( + cct, m_req->data(), m_req->get_extent_map(), m_req->get_offset(), + m_req->get_buffer_extents()); + r = m_req->get_length(); + } + m_completion->lock.Unlock(); + + C_AioRequest::finish(r); + } + + void set_req(AioObjectRead *req) { + m_req = req; + } +private: + AioObjectRead *m_req; +}; + +class C_CacheRead : public Context { +public: + explicit C_CacheRead(ImageCtx *ictx, AioObjectRead *req) + : m_image_ctx(*ictx), m_req(req), m_enqueued(false) {} + + virtual void complete(int r) { + if (!m_enqueued) { + // cache_lock creates a lock ordering issue -- so re-execute this context + // outside the cache_lock + m_enqueued = true; + m_image_ctx.op_work_queue->queue(this, r); + return; + } + Context::complete(r); + } + +protected: + virtual void finish(int r) { + m_req->complete(r); + } + +private: + ImageCtx &m_image_ctx; + AioObjectRead *m_req; + bool m_enqueued; +}; + } // anonymous namespace template diff --git a/src/librbd/AioObjectRequest.cc b/src/librbd/AioObjectRequest.cc index 799109b0ffbb..a958ee176cb2 100644 --- a/src/librbd/AioObjectRequest.cc +++ b/src/librbd/AioObjectRequest.cc @@ -265,7 +265,7 @@ void AioObjectRead::send_copyup() } } -void AioObjectRead::read_from_parent(const vector >& parent_extents) +void AioObjectRead::read_from_parent(const Extents& parent_extents) { assert(!m_parent_completion); m_parent_completion = AioCompletion::create_and_start( diff --git a/src/librbd/AioObjectRequest.h b/src/librbd/AioObjectRequest.h index 024142323295..8e4bcfc8f024 100644 --- a/src/librbd/AioObjectRequest.h +++ b/src/librbd/AioObjectRequest.h @@ -60,31 +60,41 @@ protected: class AioObjectRead : public AioObjectRequest { public: + typedef std::vector > Extents; + typedef std::map ExtentMap; + AioObjectRead(ImageCtx *ictx, const std::string &oid, uint64_t objectno, uint64_t offset, uint64_t len, - vector >& be, - librados::snap_t snap_id, bool sparse, + Extents& buffer_extents, librados::snap_t snap_id, bool sparse, Context *completion, int op_flags); virtual bool should_complete(int r); virtual void send(); void guard_read(); + inline uint64_t get_offset() const { + return m_object_off; + } + inline uint64_t get_length() const { + return m_object_len; + } ceph::bufferlist &data() { return m_read_data; } - - std::map m_ext_map; - - friend class C_AioRead; - + const Extents &get_buffer_extents() const { + return m_buffer_extents; + } + ExtentMap &get_extent_map() { + return m_ext_map; + } private: - vector > m_buffer_extents; + Extents m_buffer_extents; bool m_tried_parent; bool m_sparse; int m_op_flags; ceph::bufferlist m_read_data; AioCompletion *m_parent_completion; + ExtentMap m_ext_map; /** * Reads go through the following state machine to deal with @@ -112,7 +122,7 @@ private: void send_copyup(); - void read_from_parent(const vector >& image_extents); + void read_from_parent(const Extents& image_extents); }; class AbstractAioObjectWrite : public AioObjectRequest {