|
|
545b23 |
From 6122f6c80df874f68ec6d8e2e0098cf703cc531e Mon Sep 17 00:00:00 2001
|
|
|
545b23 |
From: Jason Dillaman <dillaman@redhat.com>
|
|
|
545b23 |
Date: Wed, 8 Apr 2015 19:06:52 -0400
|
|
|
545b23 |
Subject: [PATCH 15/22] librbd: avoid blocking AIO API methods
|
|
|
545b23 |
|
|
|
545b23 |
Enqueue all AIO API methods within the new librbd thread pool to
|
|
|
545b23 |
reduce the possibility of any blocking operations. To maintain
|
|
|
545b23 |
backwards compatibility with the legacy return codes of the API's
|
|
|
545b23 |
AIO methods, it's still possible to block attempting to acquire
|
|
|
545b23 |
the snap_lock.
|
|
|
545b23 |
|
|
|
545b23 |
Fixes: #11056
|
|
|
545b23 |
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
|
|
|
545b23 |
(cherry picked from commit 3a7b5e30efdb21aa1a0aeb68a5d02a1ac2a5faf3)
|
|
|
545b23 |
(cherry picked from commit aa45ee0d7d6f9d8e2cc43ef43f0a9762977ca53f)
|
|
|
545b23 |
---
|
|
|
545b23 |
src/librbd/librbd.cc | 110 +++++++++++++++++++++++++++++++++++++++++++++------
|
|
|
545b23 |
1 file changed, 99 insertions(+), 11 deletions(-)
|
|
|
545b23 |
|
|
|
545b23 |
diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc
|
|
|
545b23 |
index 658f24b..7f966be 100644
|
|
|
545b23 |
--- a/src/librbd/librbd.cc
|
|
|
545b23 |
+++ b/src/librbd/librbd.cc
|
|
|
545b23 |
@@ -20,6 +20,7 @@
|
|
|
545b23 |
#include "common/errno.h"
|
|
|
545b23 |
#include "common/snap_types.h"
|
|
|
545b23 |
#include "common/perf_counters.h"
|
|
|
545b23 |
+#include "common/WorkQueue.h"
|
|
|
545b23 |
#include "include/Context.h"
|
|
|
545b23 |
#include "include/rbd/librbd.hpp"
|
|
|
545b23 |
#include "osdc/ObjectCacher.h"
|
|
|
545b23 |
@@ -45,6 +46,82 @@ using ceph::bufferlist;
|
|
|
545b23 |
using librados::snap_t;
|
|
|
545b23 |
using librados::IoCtx;
|
|
|
545b23 |
|
|
|
545b23 |
+namespace {
|
|
|
545b23 |
+
|
|
|
545b23 |
+class C_AioReadWQ : public Context {
|
|
|
545b23 |
+public:
|
|
|
545b23 |
+ C_AioReadWQ(librbd::ImageCtx *ictx, uint64_t off, size_t len,
|
|
|
545b23 |
+ char *buf, bufferlist *pbl, librbd::AioCompletion *c)
|
|
|
545b23 |
+ : m_ictx(ictx), m_off(off), m_len(len), m_buf(buf), m_pbl(pbl), m_comp(c) {
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+protected:
|
|
|
545b23 |
+ virtual void finish(int r) {
|
|
|
545b23 |
+ librbd::aio_read(m_ictx, m_off, m_len, m_buf, m_pbl, m_comp);
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+private:
|
|
|
545b23 |
+ librbd::ImageCtx *m_ictx;
|
|
|
545b23 |
+ uint64_t m_off;
|
|
|
545b23 |
+ uint64_t m_len;
|
|
|
545b23 |
+ char *m_buf;
|
|
|
545b23 |
+ bufferlist *m_pbl;
|
|
|
545b23 |
+ librbd::AioCompletion *m_comp;
|
|
|
545b23 |
+};
|
|
|
545b23 |
+
|
|
|
545b23 |
+class C_AioWriteWQ : public Context {
|
|
|
545b23 |
+public:
|
|
|
545b23 |
+ C_AioWriteWQ(librbd::ImageCtx *ictx, uint64_t off, size_t len,
|
|
|
545b23 |
+ const char *buf, librbd::AioCompletion *c)
|
|
|
545b23 |
+ : m_ictx(ictx), m_off(off), m_len(len), m_buf(buf), m_comp(c) {
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+protected:
|
|
|
545b23 |
+ virtual void finish(int r) {
|
|
|
545b23 |
+ librbd::aio_write(m_ictx, m_off, m_len, m_buf, m_comp);
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+private:
|
|
|
545b23 |
+ librbd::ImageCtx *m_ictx;
|
|
|
545b23 |
+ uint64_t m_off;
|
|
|
545b23 |
+ uint64_t m_len;
|
|
|
545b23 |
+ const char *m_buf;
|
|
|
545b23 |
+ librbd::AioCompletion *m_comp;
|
|
|
545b23 |
+};
|
|
|
545b23 |
+
|
|
|
545b23 |
+class C_AioDiscardWQ : public Context {
|
|
|
545b23 |
+public:
|
|
|
545b23 |
+ C_AioDiscardWQ(librbd::ImageCtx *ictx, uint64_t off, uint64_t len,
|
|
|
545b23 |
+ librbd::AioCompletion *c)
|
|
|
545b23 |
+ : m_ictx(ictx), m_off(off), m_len(len), m_comp(c) {
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+protected:
|
|
|
545b23 |
+ virtual void finish(int r) {
|
|
|
545b23 |
+ librbd::aio_discard(m_ictx, m_off, m_len, m_comp);
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+private:
|
|
|
545b23 |
+ librbd::ImageCtx *m_ictx;
|
|
|
545b23 |
+ uint64_t m_off;
|
|
|
545b23 |
+ uint64_t m_len;
|
|
|
545b23 |
+ librbd::AioCompletion *m_comp;
|
|
|
545b23 |
+};
|
|
|
545b23 |
+
|
|
|
545b23 |
+class C_AioFlushWQ : public Context {
|
|
|
545b23 |
+public:
|
|
|
545b23 |
+ C_AioFlushWQ(librbd::ImageCtx *ictx, librbd::AioCompletion *c)
|
|
|
545b23 |
+ : m_ictx(ictx), m_comp(c) {
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+protected:
|
|
|
545b23 |
+ virtual void finish(int r) {
|
|
|
545b23 |
+ librbd::aio_flush(m_ictx, m_comp);
|
|
|
545b23 |
+ }
|
|
|
545b23 |
+private:
|
|
|
545b23 |
+ librbd::ImageCtx *m_ictx;
|
|
|
545b23 |
+ librbd::AioCompletion *m_comp;
|
|
|
545b23 |
+};
|
|
|
545b23 |
+
|
|
|
545b23 |
+librbd::AioCompletion* get_aio_completion(librbd::RBD::AioCompletion *comp) {
|
|
|
545b23 |
+ return reinterpret_cast<librbd::AioCompletion *>(comp->pc);
|
|
|
545b23 |
+}
|
|
|
545b23 |
+
|
|
|
545b23 |
+} // anonymous namespace
|
|
|
545b23 |
+
|
|
|
545b23 |
namespace librbd {
|
|
|
545b23 |
ProgressContext::~ProgressContext()
|
|
|
545b23 |
{
|
|
|
545b23 |
@@ -483,14 +560,17 @@ namespace librbd {
|
|
|
545b23 |
ImageCtx *ictx = (ImageCtx *)ctx;
|
|
|
545b23 |
if (bl.length() < len)
|
|
|
545b23 |
return -EINVAL;
|
|
|
545b23 |
- return librbd::aio_write(ictx, off, len, bl.c_str(),
|
|
|
545b23 |
- (librbd::AioCompletion *)c->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, bl.c_str(),
|
|
|
545b23 |
+ get_aio_completion(c)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
int Image::aio_discard(uint64_t off, uint64_t len, RBD::AioCompletion *c)
|
|
|
545b23 |
{
|
|
|
545b23 |
ImageCtx *ictx = (ImageCtx *)ctx;
|
|
|
545b23 |
- return librbd::aio_discard(ictx, off, len, (librbd::AioCompletion *)c->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioDiscardWQ(ictx, off, len,
|
|
|
545b23 |
+ get_aio_completion(c)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
int Image::aio_read(uint64_t off, size_t len, bufferlist& bl,
|
|
|
545b23 |
@@ -499,7 +579,9 @@ namespace librbd {
|
|
|
545b23 |
ImageCtx *ictx = (ImageCtx *)ctx;
|
|
|
545b23 |
ldout(ictx->cct, 10) << "Image::aio_read() buf=" << (void *)bl.c_str() << "~"
|
|
|
545b23 |
<< (void *)(bl.c_str() + len - 1) << dendl;
|
|
|
545b23 |
- return librbd::aio_read(ictx, off, len, NULL, &bl, (librbd::AioCompletion *)c->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, NULL, &bl,
|
|
|
545b23 |
+ get_aio_completion(c)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
int Image::flush()
|
|
|
545b23 |
@@ -511,7 +593,8 @@ namespace librbd {
|
|
|
545b23 |
int Image::aio_flush(RBD::AioCompletion *c)
|
|
|
545b23 |
{
|
|
|
545b23 |
ImageCtx *ictx = (ImageCtx *)ctx;
|
|
|
545b23 |
- return librbd::aio_flush(ictx, (librbd::AioCompletion *)c->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioFlushWQ(ictx, get_aio_completion(c)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
int Image::invalidate_cache()
|
|
|
545b23 |
@@ -1102,8 +1185,9 @@ extern "C" int rbd_aio_write(rbd_image_t image, uint64_t off, size_t len,
|
|
|
545b23 |
{
|
|
|
545b23 |
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
|
|
|
545b23 |
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
|
|
|
545b23 |
- return librbd::aio_write(ictx, off, len, buf,
|
|
|
545b23 |
- (librbd::AioCompletion *)comp->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, buf,
|
|
|
545b23 |
+ get_aio_completion(comp)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
extern "C" int rbd_aio_discard(rbd_image_t image, uint64_t off, uint64_t len,
|
|
|
545b23 |
@@ -1111,7 +1195,9 @@ extern "C" int rbd_aio_discard(rbd_image_t image, uint64_t off, uint64_t len,
|
|
|
545b23 |
{
|
|
|
545b23 |
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
|
|
|
545b23 |
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
|
|
|
545b23 |
- return librbd::aio_discard(ictx, off, len, (librbd::AioCompletion *)comp->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioDiscardWQ(ictx, off, len,
|
|
|
545b23 |
+ get_aio_completion(comp)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
extern "C" int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len,
|
|
|
545b23 |
@@ -1119,8 +1205,9 @@ extern "C" int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len,
|
|
|
545b23 |
{
|
|
|
545b23 |
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
|
|
|
545b23 |
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
|
|
|
545b23 |
- return librbd::aio_read(ictx, off, len, buf, NULL,
|
|
|
545b23 |
- (librbd::AioCompletion *)comp->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, buf, NULL,
|
|
|
545b23 |
+ get_aio_completion(comp)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
extern "C" int rbd_flush(rbd_image_t image)
|
|
|
545b23 |
@@ -1133,7 +1220,8 @@ extern "C" int rbd_aio_flush(rbd_image_t image, rbd_completion_t c)
|
|
|
545b23 |
{
|
|
|
545b23 |
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
|
|
|
545b23 |
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
|
|
|
545b23 |
- return librbd::aio_flush(ictx, (librbd::AioCompletion *)comp->pc);
|
|
|
545b23 |
+ ictx->aio_work_queue->queue(new C_AioFlushWQ(ictx, get_aio_completion(comp)));
|
|
|
545b23 |
+ return 0;
|
|
|
545b23 |
}
|
|
|
545b23 |
|
|
|
545b23 |
extern "C" int rbd_invalidate_cache(rbd_image_t image)
|
|
|
545b23 |
--
|
|
|
545b23 |
2.1.0
|
|
|
545b23 |
|