]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: convert AioObjectRequest/AioObjectRead classes to templates
authorJason Dillaman <dillaman@redhat.com>
Wed, 27 Jul 2016 13:07:00 +0000 (09:07 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 2 Aug 2016 13:56:21 +0000 (09:56 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioImageRequest.cc
src/librbd/AioImageRequest.h
src/librbd/AioObjectRequest.cc
src/librbd/AioObjectRequest.h
src/librbd/CopyupRequest.cc
src/librbd/CopyupRequest.h
src/librbd/Journal.h
src/librbd/internal.cc
src/librbd/operation/TrimRequest.cc
src/test/librbd/mock/MockJournal.h
src/test/librbd/test_mock_Journal.cc

index c0a2b9b24ab523ad0662d814d8fdb4878fb81847..40327aaa805d87c01972e1b150b884b37b755622 100644 (file)
@@ -78,6 +78,7 @@ struct C_FlushJournalCommit : public Context {
   }
 };
 
+template <typename ImageCtxT>
 class C_AioRead : public C_AioRequest {
 public:
   C_AioRead(AioCompletion *completion)
@@ -110,17 +111,18 @@ public:
     C_AioRequest::finish(r);
   }
 
-  void set_req(AioObjectRead *req) {
+  void set_req(AioObjectRead<ImageCtxT> *req) {
     m_req = req;
   }
 private:
-  AioObjectRead *m_req;
+  AioObjectRead<ImageCtxT> *m_req;
 };
 
+template <typename ImageCtxT>
 class C_CacheRead : public Context {
 public:
-  explicit C_CacheRead(ImageCtx *ictx, AioObjectRead *req)
-    : m_image_ctx(*ictx), m_req(req), m_enqueued(false) {}
+  explicit C_CacheRead(ImageCtxT &ictx, AioObjectRead<ImageCtxT> *req)
+    : m_image_ctx(ictx), m_req(req), m_enqueued(false) {}
 
   virtual void complete(int r) {
     if (!m_enqueued) {
@@ -139,8 +141,8 @@ protected:
   }
 
 private:
-  ImageCtx &m_image_ctx;
-  AioObjectRead *m_req;
+  ImageCtxT &m_image_ctx;
+  AioObjectRead<ImageCtxT> *m_req;
   bool m_enqueued;
 };
 
@@ -151,7 +153,7 @@ void AioImageRequest<I>::aio_read(
     I *ictx, AioCompletion *c,
     const std::vector<std::pair<uint64_t,uint64_t> > &extents,
     char *buf, bufferlist *pbl, int op_flags) {
-  AioImageRead req(*ictx, c, extents, buf, pbl, op_flags);
+  AioImageRead<I> req(*ictx, c, extents, buf, pbl, op_flags);
   req.send();
 }
 
@@ -159,7 +161,7 @@ template <typename I>
 void AioImageRequest<I>::aio_read(I *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);
+  AioImageRead<I> req(*ictx, c, off, len, buf, pbl, op_flags);
   req.send();
 }
 
@@ -167,20 +169,20 @@ template <typename I>
 void AioImageRequest<I>::aio_write(I *ictx, AioCompletion *c,
                                    uint64_t off, size_t len, const char *buf,
                                    int op_flags) {
-  AioImageWrite req(*ictx, c, off, len, buf, op_flags);
+  AioImageWrite<I> req(*ictx, c, off, len, buf, op_flags);
   req.send();
 }
 
 template <typename I>
 void AioImageRequest<I>::aio_discard(I *ictx, AioCompletion *c,
                                      uint64_t off, uint64_t len) {
-  AioImageDiscard req(*ictx, c, off, len);
+  AioImageDiscard<I> req(*ictx, c, off, len);
   req.send();
 }
 
 template <typename I>
 void AioImageRequest<I>::aio_flush(I *ictx, AioCompletion *c) {
-  AioImageFlush req(*ictx, c);
+  AioImageFlush<I> req(*ictx, c);
   req.send();
 }
 
@@ -266,18 +268,19 @@ void AioImageRead<I>::send_request() {
                      << extent.length << " from " << extent.buffer_extents
                      << dendl;
 
-      C_AioRead *req_comp = new C_AioRead(aio_comp);
-      AioObjectRead *req = new AioObjectRead(get_image_ctx(&image_ctx),
-                                             extent.oid.name,
-                                             extent.objectno, extent.offset,
-                                             extent.length,
-                                             extent.buffer_extents, snap_id,
-                                             true, req_comp, m_op_flags);
+      C_AioRead<I> *req_comp = new C_AioRead<I>(aio_comp);
+      AioObjectRead<I> *req = new AioObjectRead<I>(get_image_ctx(&image_ctx),
+                                                   extent.oid.name,
+                                                   extent.objectno,
+                                                   extent.offset,
+                                                   extent.length,
+                                                   extent.buffer_extents,
+                                                   snap_id, true, req_comp,
+                                                   m_op_flags);
       req_comp->set_req(req);
 
       if (image_ctx.object_cacher) {
-        C_CacheRead *cache_comp = new C_CacheRead(get_image_ctx(&image_ctx),
-                                                  req);
+        C_CacheRead<I> *cache_comp = new C_CacheRead<I>(image_ctx, req);
         image_ctx.aio_read_from_cache(extent.oid, extent.objectno,
                                       &req->data(), extent.length,
                                       extent.offset, cache_comp, m_op_flags);
@@ -376,7 +379,7 @@ void AbstractAioImageWrite<I>::send_object_requests(
     ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
                    << " from " << p->buffer_extents << dendl;
     C_AioRequest *req_comp = new C_AioRequest(aio_comp);
-    AioObjectRequest *request = create_object_request(*p, snapc, req_comp);
+    AioObjectRequest<> *request = create_object_request(*p, snapc, req_comp);
 
     // if journaling, stash the request for later; otherwise send
     if (request != NULL) {
@@ -447,7 +450,7 @@ void AioImageWrite<I>::send_object_requests(
 }
 
 template <typename I>
-AioObjectRequest *AioImageWrite<I>::create_object_request(
+AioObjectRequest<> *AioImageWrite<I>::create_object_request(
     const ObjectExtent &object_extent, const ::SnapContext &snapc,
     Context *on_finish) {
   I &image_ctx = this->m_image_ctx;
@@ -533,12 +536,12 @@ void AioImageDiscard<I>::send_cache_requests(const ObjectExtents &object_extents
 }
 
 template <typename I>
-AioObjectRequest *AioImageDiscard<I>::create_object_request(
+AioObjectRequest<> *AioImageDiscard<I>::create_object_request(
     const ObjectExtent &object_extent, const ::SnapContext &snapc,
     Context *on_finish) {
   I &image_ctx = this->m_image_ctx;
 
-  AioObjectRequest *req;
+  AioObjectRequest<> *req;
   if (object_extent.length == image_ctx.layout.object_size) {
     req = new AioObjectRemove(get_image_ctx(&image_ctx),
                               object_extent.oid.name,
index f1605954089dedd0e67767e87ee7c3f1383d2e94..f5ae33d6ae45b9210049d9e11aafa919289ea449 100644 (file)
@@ -15,9 +15,9 @@
 
 namespace librbd {
 
-class AioObjectRequest;
-class ImageCtx;
 class AioCompletion;
+template <typename I> class AioObjectRequest;
+class ImageCtx;
 
 template <typename ImageCtxT = ImageCtx>
 class AioImageRequest {
@@ -49,7 +49,7 @@ public:
   void fail(int r);
 
 protected:
-  typedef std::list<AioObjectRequest *> AioObjectRequests;
+  typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
 
   ImageCtxT &m_image_ctx;
   AioCompletion *m_aio_comp;
@@ -135,7 +135,7 @@ protected:
   virtual void send_object_requests(const ObjectExtents &object_extents,
                                     const ::SnapContext &snapc,
                                     AioObjectRequests *aio_object_requests);
-  virtual AioObjectRequest *create_object_request(
+  virtual AioObjectRequest<ImageCtx> *create_object_request(
       const ObjectExtent &object_extent, const ::SnapContext &snapc,
       Context *on_finish) = 0;
 
@@ -175,7 +175,7 @@ protected:
   virtual void send_object_requests(const ObjectExtents &object_extents,
                                     const ::SnapContext &snapc,
                                     AioObjectRequests *aio_object_requests);
-  virtual AioObjectRequest *create_object_request(
+  virtual AioObjectRequest<ImageCtx> *create_object_request(
       const ObjectExtent &object_extent, const ::SnapContext &snapc,
       Context *on_finish);
 
@@ -211,7 +211,7 @@ protected:
   virtual void send_cache_requests(const ObjectExtents &object_extents,
                                    uint64_t journal_tid);
 
-  virtual AioObjectRequest *create_object_request(
+  virtual AioObjectRequest<ImageCtx> *create_object_request(
       const ObjectExtent &object_extent, const ::SnapContext &snapc,
       Context *on_finish);
 
index a958ee176cb2d8d39bc939526e784f32eceadcb5..9ece245c05cf8766e81d3039b101266520f6d834 100644 (file)
 
 namespace librbd {
 
-AioObjectRequest::AioObjectRequest(ImageCtx *ictx, const std::string &oid,
-                                   uint64_t objectno, uint64_t off,
-                                   uint64_t len, librados::snap_t snap_id,
-                                   Context *completion, bool hide_enoent)
+template <typename I>
+AioObjectRequest<I>::AioObjectRequest(ImageCtx *ictx, const std::string &oid,
+                                      uint64_t objectno, uint64_t off,
+                                      uint64_t len, librados::snap_t snap_id,
+                                      Context *completion, bool hide_enoent)
   : m_ictx(ictx), m_oid(oid), m_object_no(objectno), m_object_off(off),
     m_object_len(len), m_snap_id(snap_id), m_completion(completion),
     m_hide_enoent(hide_enoent) {
@@ -43,7 +44,8 @@ AioObjectRequest::AioObjectRequest(ImageCtx *ictx, const std::string &oid,
   compute_parent_extents();
 }
 
-void AioObjectRequest::complete(int r)
+template <typename I>
+void AioObjectRequest<I>::complete(int r)
 {
   if (should_complete(r)) {
     ldout(m_ictx->cct, 20) << "complete " << this << dendl;
@@ -55,7 +57,8 @@ void AioObjectRequest::complete(int r)
   }
 }
 
-bool AioObjectRequest::compute_parent_extents() {
+template <typename I>
+bool AioObjectRequest<I>::compute_parent_extents() {
   assert(m_ictx->snap_lock.is_locked());
   assert(m_ictx->parent_lock.is_locked());
 
@@ -93,13 +96,15 @@ static inline bool is_copy_on_read(ImageCtx *ictx, librados::snap_t snap_id) {
 
 /** read **/
 
-AioObjectRead::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,
-                             Context *completion, int op_flags)
-  : AioObjectRequest(ictx, oid, objectno, offset, len, snap_id, completion,
-                     false),
+template <typename I>
+AioObjectRead<I>::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,
+                                Context *completion, int op_flags)
+  : AioObjectRequest<I>(ictx, oid, objectno, offset, len, snap_id, completion,
+                        false),
     m_buffer_extents(be), m_tried_parent(false), m_sparse(sparse),
     m_op_flags(op_flags), m_parent_completion(NULL),
     m_state(LIBRBD_AIO_READ_FLAT) {
@@ -107,38 +112,43 @@ AioObjectRead::AioObjectRead(ImageCtx *ictx, const std::string &oid,
   guard_read();
 }
 
-void AioObjectRead::guard_read()
+template <typename I>
+void AioObjectRead<I>::guard_read()
 {
-  RWLock::RLocker snap_locker(m_ictx->snap_lock);
-  RWLock::RLocker parent_locker(m_ictx->parent_lock);
+  ImageCtx *image_ctx = this->m_ictx;
+  RWLock::RLocker snap_locker(image_ctx->snap_lock);
+  RWLock::RLocker parent_locker(image_ctx->parent_lock);
 
-  if (has_parent()) {
-    ldout(m_ictx->cct, 20) << __func__ << " guarding read" << dendl;
+  if (this->has_parent()) {
+    ldout(image_ctx->cct, 20) << __func__ << " guarding read" << dendl;
     m_state = LIBRBD_AIO_READ_GUARD;
   }
 }
 
-bool AioObjectRead::should_complete(int r)
+template <typename I>
+bool AioObjectRead<I>::should_complete(int r)
 {
-  ldout(m_ictx->cct, 20) << "should_complete " << this << " " << m_oid << " "
-                         << m_object_off << "~" << m_object_len
-                         << " r = " << r << dendl;
+  ImageCtx *image_ctx = this->m_ictx;
+  ldout(image_ctx->cct, 20) << "should_complete " << this << " "
+                            << this->m_oid << " "
+                            << this->m_object_off << "~" << this->m_object_len
+                            << " r = " << r << dendl;
 
   bool finished = true;
 
   switch (m_state) {
   case LIBRBD_AIO_READ_GUARD:
-    ldout(m_ictx->cct, 20) << "should_complete " << this
-                           << " READ_CHECK_GUARD" << dendl;
+    ldout(image_ctx->cct, 20) << "should_complete " << this
+                              << " READ_CHECK_GUARD" << dendl;
 
     // This is the step to read from parent
     if (!m_tried_parent && r == -ENOENT) {
       {
-        RWLock::RLocker owner_locker(m_ictx->owner_lock);
-        RWLock::RLocker snap_locker(m_ictx->snap_lock);
-        RWLock::RLocker parent_locker(m_ictx->parent_lock);
-        if (m_ictx->parent == NULL) {
-          ldout(m_ictx->cct, 20) << "parent is gone; do nothing" << dendl;
+        RWLock::RLocker owner_locker(image_ctx->owner_lock);
+        RWLock::RLocker snap_locker(image_ctx->snap_lock);
+        RWLock::RLocker parent_locker(image_ctx->parent_lock);
+        if (image_ctx->parent == NULL) {
+          ldout(image_ctx->cct, 20) << "parent is gone; do nothing" << dendl;
           m_state = LIBRBD_AIO_READ_FLAT;
           finished = false;
           break;
@@ -146,20 +156,21 @@ bool AioObjectRead::should_complete(int r)
 
         // calculate reverse mapping onto the image
         vector<pair<uint64_t,uint64_t> > parent_extents;
-        Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, m_object_no,
-                                m_object_off, m_object_len, parent_extents);
+        Striper::extent_to_file(image_ctx->cct, &image_ctx->layout,
+                                this->m_object_no, this->m_object_off,
+                                this->m_object_len, parent_extents);
 
         uint64_t parent_overlap = 0;
         uint64_t object_overlap = 0;
-        r = m_ictx->get_parent_overlap(m_snap_id, &parent_overlap);
+        r = image_ctx->get_parent_overlap(this->m_snap_id, &parent_overlap);
         if (r == 0) {
-          object_overlap = m_ictx->prune_parent_extents(parent_extents,
-                                                        parent_overlap);
+          object_overlap = image_ctx->prune_parent_extents(parent_extents,
+                                                           parent_overlap);
         }
 
         if (object_overlap > 0) {
           m_tried_parent = true;
-          if (is_copy_on_read(m_ictx, m_snap_id)) {
+          if (is_copy_on_read(image_ctx, this->m_snap_id)) {
             m_state = LIBRBD_AIO_READ_COPYUP;
           }
 
@@ -178,8 +189,8 @@ bool AioObjectRead::should_complete(int r)
     }
     break;
   case LIBRBD_AIO_READ_COPYUP:
-    ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_COPYUP"
-                           << dendl;
+    ldout(image_ctx->cct, 20) << "should_complete " << this << " READ_COPYUP"
+                              << dendl;
     // This is the extra step for copy-on-read: kick off an asynchronous copyup.
     // It is different from copy-on-write as asynchronous copyup will finish
     // by itself so state won't go back to LIBRBD_AIO_READ_GUARD.
@@ -193,94 +204,103 @@ bool AioObjectRead::should_complete(int r)
     }
     break;
   case LIBRBD_AIO_READ_FLAT:
-    ldout(m_ictx->cct, 20) << "should_complete " << this << " READ_FLAT"
-                           << dendl;
+    ldout(image_ctx->cct, 20) << "should_complete " << this << " READ_FLAT"
+                              << dendl;
     // The read content should be deposit in m_read_data
     break;
   default:
-    lderr(m_ictx->cct) << "invalid request state: " << m_state << dendl;
+    lderr(image_ctx->cct) << "invalid request state: " << m_state << dendl;
     assert(0);
   }
 
   return finished;
 }
 
-void AioObjectRead::send() {
-  ldout(m_ictx->cct, 20) << "send " << this << " " << m_oid << " "
-                         << m_object_off << "~" << m_object_len << dendl;
+template <typename I>
+void AioObjectRead<I>::send() {
+  ImageCtx *image_ctx = this->m_ictx;
+  ldout(image_ctx->cct, 20) << "send " << this << " " << this->m_oid << " "
+                            << this->m_object_off << "~" << this->m_object_len
+                            << dendl;
 
   {
-    RWLock::RLocker snap_locker(m_ictx->snap_lock);
+    RWLock::RLocker snap_locker(image_ctx->snap_lock);
 
     // send read request to parent if the object doesn't exist locally
-    if (m_ictx->object_map != nullptr &&
-        !m_ictx->object_map->object_may_exist(m_object_no)) {
-      m_ictx->op_work_queue->queue(util::create_context_callback<
-        AioObjectRequest>(this), -ENOENT);
+    if (image_ctx->object_map != nullptr &&
+        !image_ctx->object_map->object_may_exist(this->m_object_no)) {
+      image_ctx->op_work_queue->queue(util::create_context_callback<
+        AioObjectRequest<I> >(this), -ENOENT);
       return;
     }
   }
 
   librados::ObjectReadOperation op;
-  int flags = m_ictx->get_read_flags(m_snap_id);
+  int flags = image_ctx->get_read_flags(this->m_snap_id);
   if (m_sparse) {
-    op.sparse_read(m_object_off, m_object_len, &m_ext_map, &m_read_data,
-                   NULL);
+    op.sparse_read(this->m_object_off, this->m_object_len, &m_ext_map,
+                   &m_read_data, nullptr);
   } else {
-    op.read(m_object_off, m_object_len, &m_read_data, NULL);
+    op.read(this->m_object_off, this->m_object_len, &m_read_data, nullptr);
   }
   op.set_op_flags2(m_op_flags);
 
   librados::AioCompletion *rados_completion =
     util::create_rados_ack_callback(this);
-  int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &op, flags,
-                                       NULL);
+  int r = image_ctx->data_ctx.aio_operate(this->m_oid, rados_completion, &op,
+                                          flags, nullptr);
   assert(r == 0);
 
   rados_completion->release();
 }
 
-void AioObjectRead::send_copyup()
+template <typename I>
+void AioObjectRead<I>::send_copyup()
 {
+  ImageCtx *image_ctx = this->m_ictx;
   {
-    RWLock::RLocker owner_locker(m_ictx->owner_lock);
-    RWLock::RLocker snap_locker(m_ictx->snap_lock);
-    RWLock::RLocker parent_locker(m_ictx->parent_lock);
-    if (!compute_parent_extents() ||
-        (m_ictx->exclusive_lock != nullptr &&
-         !m_ictx->exclusive_lock->is_lock_owner())) {
+    RWLock::RLocker owner_locker(image_ctx->owner_lock);
+    RWLock::RLocker snap_locker(image_ctx->snap_lock);
+    RWLock::RLocker parent_locker(image_ctx->parent_lock);
+    if (!this->compute_parent_extents() ||
+        (image_ctx->exclusive_lock != nullptr &&
+         !image_ctx->exclusive_lock->is_lock_owner())) {
       return;
     }
   }
 
-  Mutex::Locker copyup_locker(m_ictx->copyup_list_lock);
+  Mutex::Locker copyup_locker(image_ctx->copyup_list_lock);
   map<uint64_t, CopyupRequest*>::iterator it =
-    m_ictx->copyup_list.find(m_object_no);
-  if (it == m_ictx->copyup_list.end()) {
+    image_ctx->copyup_list.find(this->m_object_no);
+  if (it == image_ctx->copyup_list.end()) {
     // create and kick off a CopyupRequest
-    CopyupRequest *new_req = new CopyupRequest(m_ictx, m_oid, m_object_no,
-                                               m_parent_extents);
-    m_ictx->copyup_list[m_object_no] = new_req;
+    CopyupRequest *new_req = new CopyupRequest(image_ctx, this->m_oid,
+                                               this->m_object_no,
+                                               this->m_parent_extents);
+    image_ctx->copyup_list[this->m_object_no] = new_req;
     new_req->send();
   }
 }
 
-void AioObjectRead::read_from_parent(const Extents& parent_extents)
+template <typename I>
+void AioObjectRead<I>::read_from_parent(const Extents& parent_extents)
 {
+  ImageCtx *image_ctx = this->m_ictx;
   assert(!m_parent_completion);
-  m_parent_completion = AioCompletion::create_and_start<AioObjectRequest>(
-    this, m_ictx, AIO_TYPE_READ);
+  m_parent_completion = AioCompletion::create_and_start<AioObjectRequest<I> >(
+    this, image_ctx, AIO_TYPE_READ);
 
   // prevent the parent image from being deleted while this
   // request is still in-progress
   m_parent_completion->get();
   m_parent_completion->block();
 
-  ldout(m_ictx->cct, 20) << "read_from_parent this = " << this
-                         << " parent completion " << m_parent_completion
-                         << " extents " << parent_extents << dendl;
-  RWLock::RLocker owner_locker(m_ictx->parent->owner_lock);
-  AioImageRequest<>::aio_read(m_ictx->parent, m_parent_completion,
+  ldout(image_ctx->cct, 20) << "read_from_parent this = " << this
+                            << " parent completion " << m_parent_completion
+                            << " extents " << parent_extents
+                            << dendl;
+  RWLock::RLocker owner_locker(image_ctx->parent->owner_lock);
+  AioImageRequest<>::aio_read(image_ctx->parent, m_parent_completion,
                               parent_extents, NULL, &m_read_data, 0);
 }
 
@@ -582,3 +602,6 @@ void AioObjectTruncate::send_write() {
 }
 
 } // namespace librbd
+
+template class librbd::AioObjectRequest<librbd::ImageCtx>;
+template class librbd::AioObjectRead<librbd::ImageCtx>;
index 8e4bcfc8f024818dd1a207d44cc21d8613de1055..c32d33579631aa76f4de9dc543bab81af4ff16bd 100644 (file)
@@ -26,8 +26,8 @@ class CopyupRequest;
  * Its subclasses encapsulate logic for dealing with special cases
  * for I/O due to layering.
  */
-class AioObjectRequest
-{
+template <typename ImageCtxT = ImageCtx>
+class AioObjectRequest {
 public:
   AioObjectRequest(ImageCtx *ictx, const std::string &oid,
                    uint64_t objectno, uint64_t off, uint64_t len,
@@ -58,7 +58,8 @@ protected:
   bool m_hide_enoent;
 };
 
-class AioObjectRead : public AioObjectRequest {
+template <typename ImageCtxT = ImageCtx>
+class AioObjectRead : public AioObjectRequest<ImageCtxT> {
 public:
   typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
   typedef std::map<uint64_t, uint64_t> ExtentMap;
@@ -73,10 +74,10 @@ public:
   void guard_read();
 
   inline uint64_t get_offset() const {
-    return m_object_off;
+    return this->m_object_off;
   }
   inline uint64_t get_length() const {
-    return m_object_len;
+    return this->m_object_len;
   }
   ceph::bufferlist &data() {
     return m_read_data;
@@ -125,7 +126,7 @@ private:
   void read_from_parent(const Extents& image_extents);
 };
 
-class AbstractAioObjectWrite : public AioObjectRequest {
+class AbstractAioObjectWrite : public AioObjectRequest<> {
 public:
   AbstractAioObjectWrite(ImageCtx *ictx, const std::string &oid,
                          uint64_t object_no, uint64_t object_off,
@@ -362,4 +363,7 @@ protected:
 
 } // namespace librbd
 
+extern template class librbd::AioObjectRequest<librbd::ImageCtx>;
+extern template class librbd::AioObjectRead<librbd::ImageCtx>;
+
 #endif // CEPH_LIBRBD_AIO_OBJECT_REQUEST_H
index 84068d19eeb6b8e84da52e598a2ceb12add6f895..b95544b28494a54b794716efd71321e310e86865 100644 (file)
@@ -92,15 +92,15 @@ CopyupRequest::~CopyupRequest() {
   m_async_op.finish_op();
 }
 
-void CopyupRequest::append_request(AioObjectRequest *req) {
+void CopyupRequest::append_request(AioObjectRequest<> *req) {
   ldout(m_ictx->cct, 20) << __func__ << " " << this << ": " << req << dendl;
   m_pending_requests.push_back(req);
 }
 
 void CopyupRequest::complete_requests(int r) {
   while (!m_pending_requests.empty()) {
-    vector<AioObjectRequest *>::iterator it = m_pending_requests.begin();
-    AioObjectRequest *req = *it;
+    vector<AioObjectRequest<> *>::iterator it = m_pending_requests.begin();
+    AioObjectRequest<> *req = *it;
     ldout(m_ictx->cct, 20) << __func__ << " completing request " << req
                            << dendl;
     req->complete(r);
@@ -162,7 +162,7 @@ bool CopyupRequest::send_copyup() {
 
     // merge all pending write ops into this single RADOS op
     for (size_t i=0; i<m_pending_requests.size(); ++i) {
-      AioObjectRequest *req = m_pending_requests[i];
+      AioObjectRequest<> *req = m_pending_requests[i];
       ldout(m_ictx->cct, 20) << __func__ << " add_copyup_ops " << req
                              << dendl;
       req->add_copyup_ops(&write_op);
index 63b981fa0fc41c97f55afbdbc470f923feb5b657..62787681112b9f811980f2396a6eb549d4ac9678 100644 (file)
@@ -11,6 +11,8 @@
 namespace librbd {
 
 struct AioCompletion;
+template <typename I> class AioObjectRequest;
+struct ImageCtx;
 
 class CopyupRequest {
 public:
@@ -18,7 +20,7 @@ public:
                 vector<pair<uint64_t,uint64_t> >& image_extents);
   ~CopyupRequest();
 
-  void append_request(AioObjectRequest *req);
+  void append_request(AioObjectRequest<ImageCtx> *req);
 
   void send();
 
@@ -64,7 +66,7 @@ private:
   vector<pair<uint64_t,uint64_t> > m_image_extents;
   State m_state;
   ceph::bufferlist m_copyup_data;
-  vector<AioObjectRequest *> m_pending_requests;
+  vector<AioObjectRequest<ImageCtx> *> m_pending_requests;
   atomic_t m_pending_copyups;
 
   AsyncOperation m_async_op;
index ba4cfb5d0b152c95d4a3bcc92e1c71203cb25c38..2acb1c62deb5728cded763f6a00c8d690759a3b4 100644 (file)
@@ -31,7 +31,7 @@ namespace librados {
 
 namespace librbd {
 
-class AioObjectRequest;
+template <typename I> class AioObjectRequest;
 class ImageCtx;
 
 namespace journal { template <typename> class Replay; }
@@ -87,7 +87,7 @@ public:
   static const std::string LOCAL_MIRROR_UUID;
   static const std::string ORPHAN_MIRROR_UUID;
 
-  typedef std::list<AioObjectRequest *> AioObjectRequests;
+  typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
 
   Journal(ImageCtxT &image_ctx);
   ~Journal();
index af000b7464ba156928078eff712d3fc3d110c197..05a9a31a68b7988500608f0b866136c81bce291b 100644 (file)
@@ -3814,13 +3814,6 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
     return 0;
   }
 
-  void rbd_req_cb(completion_t cb, void *arg)
-  {
-    AioObjectRequest *req = reinterpret_cast<AioObjectRequest *>(arg);
-    AioCompletion *comp = reinterpret_cast<AioCompletion *>(cb);
-    req->complete(comp->get_return_value());
-  }
-
   struct C_RBD_Readahead : public Context {
     ImageCtx *ictx;
     object_t oid;
index 58266a4c28fd7179509ff0497c6400229537fdf8..3992fb75e21c26dd4285c90876f12cacbd2cb0d8 100644 (file)
@@ -45,8 +45,8 @@ public:
     string oid = image_ctx.get_object_name(m_object_no);
     ldout(image_ctx.cct, 10) << "removing (with copyup) " << oid << dendl;
 
-    AioObjectRequest *req = new AioObjectTrim(&image_ctx, oid, m_object_no,
-                                              m_snapc, this);
+    AioObjectRequest<> *req = new AioObjectTrim(&image_ctx, oid, m_object_no,
+                                                m_snapc, this);
     req->send();
     return 0;
   }
@@ -361,7 +361,7 @@ void TrimRequest<I>::send_clean_boundary() {
     ldout(cct, 20) << " ex " << *p << dendl;
     Context *req_comp = new C_ContextCompletion(*completion);
 
-    AioObjectRequest *req;
+    AioObjectRequest<> *req;
     if (p->offset == 0) {
       req = new AioObjectTrim(&image_ctx, p->oid.name, p->objectno, snapc,
                               req_comp);
index d0e718b24aed5143ee6511c48b9dd6762490d76f..a66347edb95832993e64eeb2407a8fe73f4bf300 100644 (file)
 
 namespace librbd {
 
-struct AioObjectRequest;
+template <typename I> struct AioObjectRequest;
+struct ImageCtx;
 
 struct MockJournal {
-  typedef std::list<AioObjectRequest *> AioObjectRequests;
+  typedef std::list<AioObjectRequest<ImageCtx> *> AioObjectRequests;
 
   static MockJournal *s_instance;
   static MockJournal *get_instance() {
index 77adac0738c246c44d646821d497ea8fde7bb6bd..1b8f0d64ce1318d4198162b13a94d3264b4f0a10 100644 (file)
@@ -305,7 +305,7 @@ public:
 
   uint64_t when_append_io_event(MockJournalImageCtx &mock_image_ctx,
                                 MockJournal &mock_journal,
-                                AioObjectRequest *object_request = nullptr) {
+                                AioObjectRequest<> *object_request = nullptr) {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     MockJournal::AioObjectRequests object_requests;
     if (object_request != nullptr) {