librbd: move read callback helpers to narrowest scope

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2016-07-27 09:54:44 -04:00
parent a945c2c235
commit 65b336f685
5 changed files with 87 additions and 82 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <typename I>

View File

@ -265,7 +265,7 @@ void AioObjectRead::send_copyup()
}
}
void AioObjectRead::read_from_parent(const vector<pair<uint64_t,uint64_t> >& parent_extents)
void AioObjectRead::read_from_parent(const Extents& parent_extents)
{
assert(!m_parent_completion);
m_parent_completion = AioCompletion::create_and_start<AioObjectRequest>(

View File

@ -60,31 +60,41 @@ protected:
class AioObjectRead : public AioObjectRequest {
public:
typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
typedef std::map<uint64_t, uint64_t> ExtentMap;
AioObjectRead(ImageCtx *ictx, const std::string &oid,
uint64_t objectno, uint64_t offset, uint64_t len,
vector<pair<uint64_t,uint64_t> >& 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<uint64_t, uint64_t> 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<pair<uint64_t,uint64_t> > 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<pair<uint64_t,uint64_t> >& image_extents);
void read_from_parent(const Extents& image_extents);
};
class AbstractAioObjectWrite : public AioObjectRequest {