]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: re-use common logic between aio_write/discard
authorJason Dillaman <dillaman@redhat.com>
Thu, 9 Jul 2015 18:43:56 +0000 (14:43 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 13 Nov 2015 01:17:53 +0000 (20:17 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioImageRequest.cc
src/librbd/AioImageRequest.h
src/librbd/AioImageRequestWQ.cc
src/librbd/AioObjectRequest.cc
src/librbd/CopyupRequest.cc
src/librbd/internal.cc

index 9f0a5d78ed8b5594755f5b19e43861eb93178702..56fbc453ef31b99df9aa738f6280c600af2f5d8a 100644 (file)
@@ -7,6 +7,8 @@
 #include "librbd/ImageCtx.h"
 #include "librbd/ImageWatcher.h"
 #include "librbd/internal.h"
+#include "include/rados/librados.hpp"
+#include "osdc/Striper.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -14,7 +16,7 @@
 
 namespace librbd {
 
-void AioImageRequest::read(
+void AioImageRequest::aio_read(
     ImageCtx *ictx, AioCompletion *c,
     const std::vector<std::pair<uint64_t,uint64_t> > &extents,
     char *buf, bufferlist *pbl, int op_flags) {
@@ -22,26 +24,26 @@ void AioImageRequest::read(
   req.send();
 }
 
-void AioImageRequest::read(ImageCtx *ictx, AioCompletion *c, uint64_t off,
-                           size_t len, char *buf, bufferlist *pbl,
-                           int op_flags) {
+void AioImageRequest::aio_read(ImageCtx *ictx, AioCompletion *c, uint64_t off,
+                               size_t len, char *buf, bufferlist *pbl,
+                               int op_flags) {
   AioImageRead req(*ictx, c, off, len, buf, pbl, op_flags);
   req.send();
 }
 
-void AioImageRequest::write(ImageCtx *ictx, AioCompletion *c, uint64_t off,
-                            size_t len, const char *buf, int op_flags) {
+void AioImageRequest::aio_write(ImageCtx *ictx, AioCompletion *c, uint64_t off,
+                                size_t len, const char *buf, int op_flags) {
   AioImageWrite req(*ictx, c, off, len, buf, op_flags);
   req.send();
 }
 
-void AioImageRequest::discard(ImageCtx *ictx, AioCompletion *c, uint64_t off,
-                              uint64_t len) {
+void AioImageRequest::aio_discard(ImageCtx *ictx, AioCompletion *c,
+                                  uint64_t off, uint64_t len) {
   AioImageDiscard req(*ictx, c, off, len);
   req.send();
 }
 
-void AioImageRequest::flush(ImageCtx *ictx, AioCompletion *c) {
+void AioImageRequest::aio_flush(ImageCtx *ictx, AioCompletion *c) {
   AioImageFlush req(*ictx, c);
   req.send();
 }
@@ -60,11 +62,10 @@ void AioImageRequest::send() {
     return;
   }
 
-  execute_request();
+  send_request();
 }
 
-
-void AioImageRead::execute_request() {
+void AioImageRead::send_request() {
   CephContext *cct = m_image_ctx.cct;
 
   if (m_image_ctx.object_cacher && m_image_ctx.readahead_max_bytes > 0 &&
@@ -141,7 +142,7 @@ void AioImageRead::execute_request() {
   m_image_ctx.perfcounter->inc(l_librbd_rd_bytes, buffer_ofs);
 }
 
-void AioImageWrite::execute_request() {
+void AbstractAioImageWrite::send_request() {
   CephContext *cct = m_image_ctx.cct;
 
   RWLock::RLocker md_locker(m_image_ctx.md_lock);
@@ -164,125 +165,115 @@ void AioImageWrite::execute_request() {
     }
 
     snapc = m_image_ctx.snapc;
-    m_aio_comp->start_op(&m_image_ctx, AIO_TYPE_WRITE);
+    m_aio_comp->start_op(&m_image_ctx, AIO_TYPE_WRITE); // TODO use correct enum
   }
 
   assert(!m_image_ctx.image_watcher->is_lock_supported() ||
           m_image_ctx.image_watcher->is_lock_owner());
 
-  // map
-  vector<ObjectExtent> extents;
-  if (m_len > 0) {
+  // map to object extents
+  ObjectExtents extents;
+  if (clip_len > 0) {
     Striper::file_to_extents(cct, m_image_ctx.format_string,
                              &m_image_ctx.layout, m_off, clip_len, 0, extents);
   }
 
-  for (vector<ObjectExtent>::iterator p = extents.begin();
-       p != extents.end(); ++p) {
-    ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
-                   << " from " << p->buffer_extents << dendl;
-    // assemble extent
-    bufferlist bl;
-    for (vector<pair<uint64_t,uint64_t> >::iterator q =
-           p->buffer_extents.begin();
-         q != p->buffer_extents.end(); ++q) {
-      bl.append(m_buf + q->first, q->second);
-    }
-
-    C_AioRequest *req_comp = new C_AioRequest(cct, m_aio_comp);
-    if (m_image_ctx.object_cacher) {
-      m_image_ctx.write_to_cache(p->oid, bl, p->length, p->offset, req_comp,
-                                 m_op_flags);
-    } else {
-      AioObjectWrite *req = new AioObjectWrite(&m_image_ctx, p->oid.name,
-                                               p->objectno, p->offset, bl,
-                                               snapc, req_comp);
-
-      req->set_op_flags(m_op_flags);
-      req->send();
-    }
-  }
+  send_object_requests(extents, snapc);
+  update_stats(clip_len);
 
   m_aio_comp->finish_adding_requests(cct);
   m_aio_comp->put();
-
-  m_image_ctx.perfcounter->inc(l_librbd_wr);
-  m_image_ctx.perfcounter->inc(l_librbd_wr_bytes, clip_len);
 }
 
-void AioImageDiscard::execute_request() {
+void AbstractAioImageWrite::send_object_requests(
+    const ObjectExtents &object_extents, const ::SnapContext &snapc) {
   CephContext *cct = m_image_ctx.cct;
+  for (ObjectExtents::const_iterator p = object_extents.begin();
+       p != object_extents.end(); ++p) {
+    ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
+                   << " from " << p->buffer_extents << dendl;
+    send_object_request(*p, snapc);
+  }
+}
 
-  RWLock::RLocker md_locker(m_image_ctx.md_lock);
+void AioImageWrite::send_object_request(const ObjectExtent &object_extent,
+                                        const ::SnapContext &snapc) {
+  CephContext *cct = m_image_ctx.cct;
 
-  uint64_t clip_len = m_len;
-  ::SnapContext snapc;
-  {
-    // prevent image size from changing between computing clip and recording
-    // pending async operation
-    RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
-    if (m_image_ctx.snap_id != CEPH_NOSNAP || m_image_ctx.read_only) {
-      m_aio_comp->fail(cct, -EROFS);
-      return;
-    }
+  // assemble extent
+  bufferlist bl;
+  for (Extents::const_iterator q = object_extent.buffer_extents.begin();
+       q != object_extent.buffer_extents.end(); ++q) {
+    bl.append(m_buf + q->first, q->second);
+  }
 
-    int r = clip_io(&m_image_ctx, m_off, &clip_len);
-    if (r < 0) {
-      m_aio_comp->fail(cct, r);
-      return;
-    }
+  C_AioRequest *req_comp = new C_AioRequest(cct, m_aio_comp);
+  if (m_image_ctx.object_cacher) {
+    m_image_ctx.write_to_cache(object_extent.oid, bl, object_extent.length,
+                               object_extent.offset, req_comp, m_op_flags);
+  } else {
+    AioObjectWrite *req = new AioObjectWrite(&m_image_ctx,
+                                             object_extent.oid.name,
+                                             object_extent.objectno,
+                                             object_extent.offset, bl,
+                                             snapc, req_comp);
 
-    snapc = m_image_ctx.snapc;
-    m_aio_comp->start_op(&m_image_ctx, AIO_TYPE_DISCARD);
+    req->set_op_flags(m_op_flags);
+    req->send();
   }
+}
 
-  assert(!m_image_ctx.image_watcher->is_lock_supported() ||
-          m_image_ctx.image_watcher->is_lock_owner());
 
-  // map
-  vector<ObjectExtent> extents;
-  if (m_len > 0) {
-    Striper::file_to_extents(cct, m_image_ctx.format_string,
-                             &m_image_ctx.layout, m_off, clip_len, 0, extents);
-  }
+void AioImageWrite::update_stats(size_t length) {
+  m_image_ctx.perfcounter->inc(l_librbd_wr);
+  m_image_ctx.perfcounter->inc(l_librbd_wr_bytes, length);
+}
 
-  for (vector<ObjectExtent>::iterator p = extents.begin();
-       p != extents.end(); ++p) {
-    ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
-                   << " from " << p->buffer_extents << dendl;
-    C_AioRequest *req_comp = new C_AioRequest(cct, m_aio_comp);
-    AioObjectRequest *req;
-
-    if (p->length == m_image_ctx.layout.fl_object_size) {
-      req = new AioObjectRemove(&m_image_ctx, p->oid.name, p->objectno, snapc,
-                                req_comp);
-    } else if (p->offset + p->length == m_image_ctx.layout.fl_object_size) {
-      req = new AioObjectTruncate(&m_image_ctx, p->oid.name, p->objectno,
-                                  p->offset, snapc, req_comp);
-    } else {
-      if(cct->_conf->rbd_skip_partial_discard) {
-        delete req_comp;
-        continue;
-      }
-      req = new AioObjectZero(&m_image_ctx, p->oid.name, p->objectno, p->offset,
-                              p->length, snapc, req_comp);
-    }
-    req->send();
+void AioImageDiscard::send_object_requests(const ObjectExtents &object_extents,
+                                           const ::SnapContext &snapc) {
+  // discard from the cache first to ensure writeback won't recreate
+  if (m_image_ctx.object_cacher != NULL) {
+    Mutex::Locker cache_locker(m_image_ctx.cache_lock);
+    m_image_ctx.object_cacher->discard_set(m_image_ctx.object_set,
+                                           object_extents);
   }
 
-  if (m_image_ctx.object_cacher) {
-    Mutex::Locker l(m_image_ctx.cache_lock);
-    m_image_ctx.object_cacher->discard_set(m_image_ctx.object_set, extents);
-  }
+  AbstractAioImageWrite::send_object_requests(object_extents, snapc);
+}
 
-  m_aio_comp->finish_adding_requests(cct);
-  m_aio_comp->put();
+void AioImageDiscard::send_object_request(const ObjectExtent &object_extent,
+                                          const ::SnapContext &snapc) {
+  CephContext *cct = m_image_ctx.cct;
+
+  C_AioRequest *req_comp = new C_AioRequest(cct, m_aio_comp);
+
+  AioObjectRequest *req;
+  if (object_extent.length == m_image_ctx.layout.fl_object_size) {
+    req = new AioObjectRemove(&m_image_ctx, object_extent.oid.name,
+                              object_extent.objectno, snapc, req_comp);
+  } else if (object_extent.offset + object_extent.length ==
+               m_image_ctx.layout.fl_object_size) {
+    req = new AioObjectTruncate(&m_image_ctx, object_extent.oid.name,
+                                object_extent.objectno, object_extent.offset,
+                                snapc, req_comp);
+  } else {
+    if(cct->_conf->rbd_skip_partial_discard) {
+      delete req_comp;
+      return;
+    }
+    req = new AioObjectZero(&m_image_ctx, object_extent.oid.name,
+                            object_extent.objectno, object_extent.offset,
+                            object_extent.length, snapc, req_comp);
+  }
+  req->send();
+}
 
+void AioImageDiscard::update_stats(size_t length) {
   m_image_ctx.perfcounter->inc(l_librbd_discard);
-  m_image_ctx.perfcounter->inc(l_librbd_discard_bytes, clip_len);
+  m_image_ctx.perfcounter->inc(l_librbd_discard_bytes, length);
 }
 
-void AioImageFlush::execute_request() {
+void AioImageFlush::send_request() {
   CephContext *cct = m_image_ctx.cct;
 
   // TODO race condition between registering op and submitting to cache
index 1d8586b201d435efddf3307a249c42c548ff1e79..db65839b5dd6cbd12f3f5364dec15532e824307a 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "include/int_types.h"
 #include "include/buffer.h"
+#include "common/snap_types.h"
+#include "osd/osd_types.h"
 #include <utility>
 #include <vector>
 
@@ -16,29 +18,35 @@ class ImageCtx;
 
 class AioImageRequest {
 public:
-  AioImageRequest(ImageCtx &image_ctx, AioCompletion *aio_comp)
-    : m_image_ctx(image_ctx), m_aio_comp(aio_comp) {}
+  typedef std::vector<std::pair<uint64_t,uint64_t> > Extents;
+
   virtual ~AioImageRequest() {}
 
-  static void read(ImageCtx *ictx, AioCompletion *c,
-                   const std::vector<std::pair<uint64_t,uint64_t> > &extents,
-                   char *buf, bufferlist *pbl, int op_flags);
-  static void read(ImageCtx *ictx, AioCompletion *c, uint64_t off, size_t len,
-                   char *buf, bufferlist *pbl, int op_flags);
-  static void write(ImageCtx *ictx, AioCompletion *c, uint64_t off, size_t len,
-                    const char *buf, int op_flags);
-  static void discard(ImageCtx *ictx, AioCompletion *c, uint64_t off,
-                      uint64_t len);
-  static void flush(ImageCtx *ictx, AioCompletion *c);
+  static void aio_read(ImageCtx *ictx, AioCompletion *c,
+                       const std::vector<std::pair<uint64_t,uint64_t> > &extents,
+                       char *buf, bufferlist *pbl, int op_flags);
+  static void aio_read(ImageCtx *ictx, AioCompletion *c, uint64_t off,
+                       size_t len, char *buf, bufferlist *pbl, int op_flags);
+  static void aio_write(ImageCtx *ictx, AioCompletion *c, uint64_t off,
+                        size_t len, const char *buf, int op_flags);
+  static void aio_discard(ImageCtx *ictx, AioCompletion *c, uint64_t off,
+                          uint64_t len);
+  static void aio_flush(ImageCtx *ictx, AioCompletion *c);
 
-  virtual bool is_write_op() const = 0;
+  virtual bool is_write_op() const {
+    return false;
+  }
 
   void send();
+
 protected:
   ImageCtx &m_image_ctx;
   AioCompletion *m_aio_comp;
 
-  virtual void execute_request() = 0;
+  AioImageRequest(ImageCtx &image_ctx, AioCompletion *aio_comp)
+    : m_image_ctx(image_ctx), m_aio_comp(aio_comp) {}
+
+  virtual void send_request() = 0;
   virtual const char *get_request_type() const = 0;
 };
 
@@ -50,69 +58,91 @@ public:
       m_op_flags(op_flags) {
     m_image_extents.push_back(std::make_pair(off, len));
   }
+
   AioImageRead(ImageCtx &image_ctx, AioCompletion *aio_comp,
-               const std::vector<std::pair<uint64_t,uint64_t> > &image_extents,
-               char *buf, bufferlist *pbl, int op_flags)
+               const Extents &image_extents, char *buf, bufferlist *pbl,
+               int op_flags)
     : AioImageRequest(image_ctx, aio_comp), m_image_extents(image_extents),
       m_buf(buf), m_pbl(pbl), m_op_flags(op_flags) {
   }
 
-  virtual bool is_write_op() const {
-    return false;
-  }
 protected:
-  virtual void execute_request();
+  virtual void send_request();
   virtual const char *get_request_type() const {
     return "aio_read";
   }
 private:
-  std::vector<std::pair<uint64_t,uint64_t> > m_image_extents;
+  Extents m_image_extents;
   char *m_buf;
   bufferlist *m_pbl;
   int m_op_flags;
 };
 
-class AioImageWrite : public AioImageRequest {
+class AbstractAioImageWrite : public AioImageRequest {
+public:
+  virtual bool is_write_op() const {
+    return true;
+  }
+
+protected:
+  typedef std::vector<ObjectExtent> ObjectExtents;
+
+  AbstractAioImageWrite(ImageCtx &image_ctx, AioCompletion *aio_comp,
+                        uint64_t off, size_t len)
+    : AioImageRequest(image_ctx, aio_comp), m_off(off), m_len(len) {
+  }
+
+  virtual void send_request();
+
+  virtual void send_object_requests(const ObjectExtents &object_extents,
+                                    const ::SnapContext &snapc);
+  virtual void send_object_request(const ObjectExtent &object_extent,
+                                   const ::SnapContext &snapc) = 0;
+  virtual void update_stats(size_t length) = 0;
+
+private:
+  uint64_t m_off;
+  size_t m_len;
+};
+
+class AioImageWrite : public AbstractAioImageWrite {
 public:
   AioImageWrite(ImageCtx &image_ctx, AioCompletion *aio_comp, uint64_t off,
                 size_t len, const char *buf, int op_flags)
-    : AioImageRequest(image_ctx, aio_comp), m_off(off), m_len(len), m_buf(buf),
+    : AbstractAioImageWrite(image_ctx, aio_comp, off, len), m_buf(buf),
       m_op_flags(op_flags) {
   }
 
-  virtual bool is_write_op() const {
-    return true;
-  }
 protected:
-  virtual void execute_request();
   virtual const char *get_request_type() const {
     return "aio_write";
   }
+
+  virtual void send_object_request(const ObjectExtent &object_extent,
+                                   const ::SnapContext &snapc);
+  virtual void update_stats(size_t length);
 private:
-  uint64_t m_off;
-  uint64_t m_len;
   const char *m_buf;
   int m_op_flags;
 };
 
-class AioImageDiscard : public AioImageRequest {
+class AioImageDiscard : public AbstractAioImageWrite {
 public:
   AioImageDiscard(ImageCtx &image_ctx, AioCompletion *aio_comp, uint64_t off,
                   uint64_t len)
-    : AioImageRequest(image_ctx, aio_comp), m_off(off), m_len(len) {
+    : AbstractAioImageWrite(image_ctx, aio_comp, off, len) {
   }
 
-  virtual bool is_write_op() const {
-    return true;
-  }
 protected:
-  virtual void execute_request();
   virtual const char *get_request_type() const {
     return "aio_discard";
   }
-private:
-  uint64_t m_off;
-  uint64_t m_len;
+
+  virtual void send_object_requests(const ObjectExtents &object_extents,
+                                    const ::SnapContext &snapc);
+  virtual void send_object_request(const ObjectExtent &object_extent,
+                                   const ::SnapContext &snapc);
+  virtual void update_stats(size_t length);
 };
 
 class AioImageFlush : public AioImageRequest {
@@ -121,11 +151,8 @@ public:
     : AioImageRequest(image_ctx, aio_comp) {
   }
 
-  virtual bool is_write_op() const {
-    return false;
-  }
 protected:
-  virtual void execute_request();
+  virtual void send_request();
   virtual const char *get_request_type() const {
     return "aio_flush";
   }
index bef86c0933e6b24e3f49b27b07cc0ed6086a8fb6..6d5fffde5a4ea8729799685f44a06c1b7001ad4c 100644 (file)
@@ -89,7 +89,7 @@ void AioImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, size_t len,
     queue(new AioImageRead(m_image_ctx, c, off, len, buf, pbl, op_flags),
           false);
   } else {
-    AioImageRequest::read(&m_image_ctx, c, off, len, buf, pbl, op_flags);
+    AioImageRequest::aio_read(&m_image_ctx, c, off, len, buf, pbl, op_flags);
   }
 }
 
@@ -107,7 +107,7 @@ void AioImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, size_t len,
     queue(new AioImageWrite(m_image_ctx, c, off, len, buf, op_flags),
           lock_required);
   } else {
-    AioImageRequest::write(&m_image_ctx, c, off, len, buf, op_flags);
+    AioImageRequest::aio_write(&m_image_ctx, c, off, len, buf, op_flags);
   }
 }
 
@@ -125,7 +125,7 @@ void AioImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off,
     queue(new AioImageDiscard(m_image_ctx, c, off, len),
           lock_required);
   } else {
-    AioImageRequest::discard(&m_image_ctx, c, off, len);
+    AioImageRequest::aio_discard(&m_image_ctx, c, off, len);
   }
 }
 
@@ -139,7 +139,7 @@ void AioImageRequestWQ::aio_flush(AioCompletion *c) {
   if (m_image_ctx.non_blocking_aio || !writes_empty()) {
     queue(new AioImageFlush(m_image_ctx, c), false);
   } else {
-    AioImageRequest::flush(&m_image_ctx, c);
+    AioImageRequest::aio_flush(&m_image_ctx, c);
   }
 }
 
index 95dda4b012eb17af71d9302bebb4797b77aadb6b..48e98371f9a5af007566ea9550cc69a171230642 100644 (file)
@@ -273,8 +273,8 @@ namespace librbd {
                           << " extents " << parent_extents
                           << dendl;
     RWLock::RLocker owner_locker(m_ictx->parent->owner_lock);
-    AioImageRequest::read(m_ictx->parent, m_parent_completion, parent_extents,
-                          NULL, &m_read_data, 0);
+    AioImageRequest::aio_read(m_ictx->parent, m_parent_completion,
+                              parent_extents, NULL, &m_read_data, 0);
   }
 
   /** write **/
index 9ac6ca6f853c4852bad810a2fc5bab9699d519af..eff12ff645aa9d027606c1eb9c601c478ac0a00e 100644 (file)
@@ -187,8 +187,8 @@ private:
                            << ", extents " << m_image_extents
                            << dendl;
     RWLock::RLocker owner_locker(m_ictx->parent->owner_lock);
-    AioImageRequest::read(m_ictx->parent, comp, m_image_extents, NULL,
-                          &m_copyup_data, 0);
+    AioImageRequest::aio_read(m_ictx->parent, comp, m_image_extents, NULL,
+                              &m_copyup_data, 0);
   }
 
   void CopyupRequest::queue_send()
index 794102b62b6367d4f757f7e484309ca9de6b1a68..a0c76070737da042281ebaf0976624542b6274f2 100644 (file)
@@ -2891,8 +2891,9 @@ reprotect_and_return_err:
       RWLock::RLocker owner_lock(m_dest->owner_lock);
       Context *ctx = new C_CopyWrite(m_throttle, m_bl);
       AioCompletion *comp = aio_create_completion_internal(ctx, rbd_ctx_cb);
-      AioImageRequest::write(m_dest, comp, m_offset, m_bl->length(),
-                             m_bl->c_str(), LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
+      AioImageRequest::aio_write(m_dest, comp, m_offset, m_bl->length(),
+                                 m_bl->c_str(),
+                                 LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
     }
   private:
     SimpleThrottle *m_throttle;
@@ -2945,7 +2946,8 @@ reprotect_and_return_err:
       bufferlist *bl = new bufferlist();
       Context *ctx = new C_CopyRead(&throttle, dest, offset, bl);
       AioCompletion *comp = aio_create_completion_internal(ctx, rbd_ctx_cb);
-      AioImageRequest::read(src, comp, offset, len, NULL, bl, fadvise_flags);
+      AioImageRequest::aio_read(src, comp, offset, len, NULL, bl,
+                                fadvise_flags);
       prog_ctx.update_progress(offset, src_size);
     }
 
@@ -3473,7 +3475,7 @@ reprotect_and_return_err:
 
       Context *ctx = new C_SafeCond(&mylock, &cond, &done, &ret);
       AioCompletion *c = aio_create_completion_internal(ctx, rbd_ctx_cb);
-      AioImageRequest::read(ictx, c, off, read_len, NULL, &bl, 0);
+      AioImageRequest::aio_read(ictx, c, off, read_len, NULL, &bl, 0);
 
       mylock.Lock();
       while (!done)