Skip to content

Commit

Permalink
Merge branch 'wip-15688' into wip-mgolub-testing
Browse files Browse the repository at this point in the history
 librbd: initial hooks for client-side, image-extent cache in IO path #9121
  • Loading branch information
Mykola Golub committed Aug 27, 2016
2 parents 443941c + 0c1e8f3 commit 5d7400a
Show file tree
Hide file tree
Showing 27 changed files with 661 additions and 210 deletions.
244 changes: 180 additions & 64 deletions src/librbd/AioImageRequest.cc

Large diffs are not rendered by default.

96 changes: 59 additions & 37 deletions src/librbd/AioImageRequest.h
Expand Up @@ -27,12 +27,12 @@ class AioImageRequest {
virtual ~AioImageRequest() {}

static void aio_read(ImageCtxT *ictx, AioCompletion *c,
const std::vector<std::pair<uint64_t,uint64_t> > &extents,
char *buf, bufferlist *pbl, int op_flags);
static void aio_read(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
size_t len, char *buf, bufferlist *pbl, int op_flags);
Extents &&image_extents, char *buf, bufferlist *pbl,
int op_flags);
static void aio_write(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
size_t len, const char *buf, int op_flags);
static void aio_write(ImageCtxT *ictx, AioCompletion *c,
Extents &&image_extents, bufferlist &&bl, int op_flags);
static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
uint64_t len);
static void aio_flush(ImageCtxT *ictx, AioCompletion *c);
Expand All @@ -48,16 +48,28 @@ class AioImageRequest {
void send();
void fail(int r);

void set_bypass_image_cache() {
m_bypass_image_cache = true;
}

protected:
typedef std::list<AioObjectRequestHandle *> AioObjectRequests;

ImageCtxT &m_image_ctx;
AioCompletion *m_aio_comp;
Extents m_image_extents;
bool m_bypass_image_cache = false;

AioImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp)
: m_image_ctx(image_ctx), m_aio_comp(aio_comp) {}
AioImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
Extents &&image_extents)
: m_image_ctx(image_ctx), m_aio_comp(aio_comp),
m_image_extents(image_extents) {
}

virtual int clip_request();
virtual void send_request() = 0;
virtual void send_image_cache_request() = 0;

virtual aio_type_t get_aio_type() const = 0;
virtual const char *get_request_type() const = 0;
};
Expand All @@ -67,31 +79,24 @@ class AioImageRead : public AioImageRequest<ImageCtxT> {
public:
using typename AioImageRequest<ImageCtxT>::Extents;

AioImageRead(ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off,
size_t len, char *buf, bufferlist *pbl, int op_flags)
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp), m_buf(buf), m_pbl(pbl),
m_op_flags(op_flags) {
m_image_extents.push_back(std::make_pair(off, len));
}

AioImageRead(ImageCtxT &image_ctx, AioCompletion *aio_comp,
const Extents &image_extents, char *buf, bufferlist *pbl,
Extents &&image_extents, char *buf, bufferlist *pbl,
int op_flags)
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp),
m_image_extents(image_extents), m_buf(buf), m_pbl(pbl),
m_op_flags(op_flags) {
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp, std::move(image_extents)),
m_buf(buf), m_pbl(pbl), m_op_flags(op_flags) {
}

protected:
virtual void send_request();
virtual void send_request() override;
virtual void send_image_cache_request() override;

virtual aio_type_t get_aio_type() const {
return AIO_TYPE_READ;
}
virtual const char *get_request_type() const {
return "aio_read";
}
private:
Extents m_image_extents;
char *m_buf;
bufferlist *m_pbl;
int m_op_flags;
Expand All @@ -110,27 +115,25 @@ class AbstractAioImageWrite : public AioImageRequest<ImageCtxT> {

protected:
using typename AioImageRequest<ImageCtxT>::AioObjectRequests;
using typename AioImageRequest<ImageCtxT>::Extents;

typedef std::vector<ObjectExtent> ObjectExtents;

const uint64_t m_off;
const size_t m_len;

AbstractAioImageWrite(ImageCtxT &image_ctx, AioCompletion *aio_comp,
uint64_t off, size_t len)
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp), m_off(off), m_len(len),
Extents &&image_extents)
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp, std::move(image_extents)),
m_synchronous(false) {
}

virtual void send_request();

virtual void prune_object_extents(ObjectExtents &object_extents) {
}
virtual uint32_t get_cache_request_count(bool journaling) const {
virtual uint32_t get_object_cache_request_count(bool journaling) const {
return 0;
}
virtual void send_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid) = 0;
virtual void send_object_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid) = 0;

virtual void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
Expand All @@ -150,10 +153,19 @@ class AbstractAioImageWrite : public AioImageRequest<ImageCtxT> {
template <typename ImageCtxT = ImageCtx>
class AioImageWrite : public AbstractAioImageWrite<ImageCtxT> {
public:
using typename AioImageRequest<ImageCtxT>::Extents;

AioImageWrite(ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off,
size_t len, const char *buf, int op_flags)
: AbstractAioImageWrite<ImageCtxT>(image_ctx, aio_comp, off, len),
m_buf(buf), m_op_flags(op_flags) {
: AbstractAioImageWrite<ImageCtxT>(image_ctx, aio_comp, {{off, len}}),
m_op_flags(op_flags) {
m_bl.append(buf, len);
}
AioImageWrite(ImageCtxT &image_ctx, AioCompletion *aio_comp,
Extents &&image_extents, bufferlist &&bl, int op_flags)
: AbstractAioImageWrite<ImageCtxT>(image_ctx, aio_comp,
std::move(image_extents)),
m_bl(std::move(bl)), m_op_flags(op_flags) {
}

protected:
Expand All @@ -169,8 +181,10 @@ class AioImageWrite : public AbstractAioImageWrite<ImageCtxT> {

void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);

virtual void send_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid);
virtual void send_image_cache_request() override;

virtual void send_object_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid);

virtual void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
Expand All @@ -183,7 +197,7 @@ class AioImageWrite : public AbstractAioImageWrite<ImageCtxT> {
bool synchronous);
virtual void update_stats(size_t length);
private:
const char *m_buf;
bufferlist m_bl;
int m_op_flags;
};

Expand All @@ -192,7 +206,7 @@ class AioImageDiscard : public AbstractAioImageWrite<ImageCtxT> {
public:
AioImageDiscard(ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off,
uint64_t len)
: AbstractAioImageWrite<ImageCtxT>(image_ctx, aio_comp, off, len) {
: AbstractAioImageWrite<ImageCtxT>(image_ctx, aio_comp, {{off, len}}) {
}

protected:
Expand All @@ -207,9 +221,12 @@ class AioImageDiscard : public AbstractAioImageWrite<ImageCtxT> {
}

virtual void prune_object_extents(ObjectExtents &object_extents) override;
virtual uint32_t get_cache_request_count(bool journaling) const override;
virtual void send_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid);

virtual void send_image_cache_request() override;

virtual uint32_t get_object_cache_request_count(bool journaling) const override;
virtual void send_object_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid);

virtual AioObjectRequestHandle *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Expand All @@ -224,7 +241,7 @@ template <typename ImageCtxT = ImageCtx>
class AioImageFlush : public AioImageRequest<ImageCtxT> {
public:
AioImageFlush(ImageCtxT &image_ctx, AioCompletion *aio_comp)
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp) {
: AioImageRequest<ImageCtxT>(image_ctx, aio_comp, {}) {
}

virtual bool is_write_op() const {
Expand All @@ -234,7 +251,12 @@ class AioImageFlush : public AioImageRequest<ImageCtxT> {
protected:
using typename AioImageRequest<ImageCtxT>::AioObjectRequests;

virtual int clip_request() {
return 0;
}
virtual void send_request();
virtual void send_image_cache_request() override;

virtual aio_type_t get_aio_type() const {
return AIO_TYPE_FLUSH;
}
Expand Down
18 changes: 8 additions & 10 deletions src/librbd/AioImageRequestWQ.cc
Expand Up @@ -120,10 +120,11 @@ void AioImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len,

if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty() ||
lock_required) {
queue(new AioImageRead<>(m_image_ctx, c, off, len, buf, pbl, op_flags));
queue(new AioImageRead<>(m_image_ctx, c, {{off, len}}, buf, pbl, op_flags));
} else {
c->start_op();
AioImageRequest<>::aio_read(&m_image_ctx, c, off, len, buf, pbl, op_flags);
AioImageRequest<>::aio_read(&m_image_ctx, c, {{off, len}}, buf, pbl,
op_flags);
finish_in_flight_op();
}
}
Expand Down Expand Up @@ -351,10 +352,7 @@ void AioImageRequestWQ::process(AioImageRequest<> *req) {
ldout(cct, 20) << __func__ << ": ictx=" << &m_image_ctx << ", "
<< "req=" << req << dendl;

{
RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
req->send();
}
req->send();

finish_queued_op(req);
if (req->is_write_op()) {
Expand Down Expand Up @@ -388,7 +386,6 @@ void AioImageRequestWQ::finish_in_progress_write() {
}

if (writes_blocked) {
RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
m_image_ctx.flush(new C_BlockedWrites(this));
}
}
Expand All @@ -409,19 +406,20 @@ int AioImageRequestWQ::start_in_flight_op(AioCompletion *c) {
}

void AioImageRequestWQ::finish_in_flight_op() {
Context *on_shutdown;
{
RWLock::RLocker locker(m_lock);
if (m_in_flight_ops.dec() > 0 || !m_shutdown) {
return;
}
on_shutdown = m_on_shutdown;
}

CephContext *cct = m_image_ctx.cct;
ldout(cct, 5) << __func__ << ": completing shut down" << dendl;

RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
assert(m_on_shutdown != nullptr);
m_image_ctx.flush(m_on_shutdown);
assert(on_shutdown != nullptr);
m_image_ctx.flush(on_shutdown);
}

bool AioImageRequestWQ::is_lock_required() const {
Expand Down

0 comments on commit 5d7400a

Please sign in to comment.