Blame SOURCES/0015-librbd-avoid-blocking-AIO-API-methods.patch

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