]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: consolidate all object discard-related logic into single state machine
authorJason Dillaman <dillaman@redhat.com>
Thu, 9 Nov 2017 15:24:08 +0000 (10:24 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 1 Feb 2018 16:16:26 +0000 (11:16 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 318797f59adcedcc386e01f1975011e0086434ac)

src/librbd/io/ImageRequest.cc
src/librbd/io/ObjectRequest.cc
src/librbd/io/ObjectRequest.h
src/librbd/operation/TrimRequest.cc
src/test/librbd/io/test_mock_ImageRequest.cc
src/test/librbd/operation/test_mock_TrimRequest.cc
src/test/librbd/test_mock_Journal.cc

index 0d68094a5c79c2e17ee656f21420b9f93ff2df35..883bdd758dde02708af3ff9de78f79dc4b1632a8 100644 (file)
@@ -642,22 +642,10 @@ ObjectRequestHandle *ImageDiscardRequest<I>::create_object_request(
     Context *on_finish) {
   I &image_ctx = this->m_image_ctx;
 
-  ObjectRequest<I> *req;
-  if (object_extent.length == image_ctx.layout.object_size) {
-    req = ObjectRequest<I>::create_remove(
-      &image_ctx, object_extent.oid.name, object_extent.objectno, snapc,
-      this->m_trace, on_finish);
-  } else if (object_extent.offset + object_extent.length ==
-               image_ctx.layout.object_size) {
-    req = ObjectRequest<I>::create_truncate(
-      &image_ctx, object_extent.oid.name, object_extent.objectno,
-      object_extent.offset, snapc, this->m_trace, on_finish);
-  } else {
-    req = ObjectRequest<I>::create_zero(
-      &image_ctx, object_extent.oid.name, object_extent.objectno,
-      object_extent.offset, object_extent.length, snapc,
-      this->m_trace, on_finish);
-  }
+  auto req = ObjectRequest<I>::create_discard(
+    &image_ctx, object_extent.oid.name, object_extent.objectno,
+    object_extent.offset, object_extent.length, snapc, true, true,
+    this->m_trace, on_finish);
   return req;
 }
 
index b74b73d02f00f9cf5ae98e513258e3bfc49d7928..2d17793ba80f11f310a67d9cbf9ea1da0c2f60a6 100644 (file)
@@ -44,38 +44,6 @@ inline bool is_copy_on_read(I *ictx, librados::snap_t snap_id) {
 
 } // anonymous namespace
 
-template <typename I>
-ObjectRequest<I>*
-ObjectRequest<I>::create_remove(I *ictx, const std::string &oid,
-                                uint64_t object_no,
-                                const ::SnapContext &snapc,
-                               const ZTracer::Trace &parent_trace,
-                                Context *completion) {
-  return new ObjectRemoveRequest<I>(ictx, oid, object_no, snapc, parent_trace,
-                                    completion);
-}
-
-template <typename I>
-ObjectRequest<I>*
-ObjectRequest<I>::create_truncate(I *ictx, const std::string &oid,
-                                  uint64_t object_no, uint64_t object_off,
-                                  const ::SnapContext &snapc,
-                                  const ZTracer::Trace &parent_trace,
-                                 Context *completion) {
-  return new ObjectTruncateRequest<I>(ictx, oid, object_no, object_off, snapc,
-                                      parent_trace, completion);
-}
-
-template <typename I>
-ObjectRequest<I>*
-ObjectRequest<I>::create_trim(I *ictx, const std::string &oid,
-                              uint64_t object_no, const ::SnapContext &snapc,
-                              bool post_object_map_update,
-                              Context *completion) {
-  return new ObjectTrimRequest<I>(ictx, oid, object_no, snapc,
-                                  post_object_map_update, completion);
-}
-
 template <typename I>
 ObjectRequest<I>*
 ObjectRequest<I>::create_write(I *ictx, const std::string &oid,
@@ -90,14 +58,18 @@ ObjectRequest<I>::create_write(I *ictx, const std::string &oid,
 
 template <typename I>
 ObjectRequest<I>*
-ObjectRequest<I>::create_zero(I *ictx, const std::string &oid,
-                              uint64_t object_no, uint64_t object_off,
-                              uint64_t object_len,
-                              const ::SnapContext &snapc,
-                             const ZTracer::Trace &parent_trace,
-                              Context *completion) {
-  return new ObjectZeroRequest<I>(ictx, oid, object_no, object_off, object_len,
-                                  snapc, parent_trace, completion);
+ObjectRequest<I>::create_discard(I *ictx, const std::string &oid,
+                                 uint64_t object_no, uint64_t object_off,
+                                 uint64_t object_len,
+                                 const ::SnapContext &snapc,
+                                 bool disable_clone_remove,
+                                 bool update_object_map,
+                                 const ZTracer::Trace &parent_trace,
+                                 Context *completion) {
+  return new ObjectDiscardRequest<I>(ictx, oid, object_no, object_off,
+                                     object_len, snapc, disable_clone_remove,
+                                     update_object_map, parent_trace,
+                                     completion);
 }
 
 template <typename I>
@@ -751,55 +723,23 @@ void ObjectWriteRequest<I>::send_write() {
 }
 
 template <typename I>
-void ObjectRemoveRequest<I>::guard_write() {
-  // do nothing to disable write guard only if deep-copyup not required
-  I *image_ctx = this->m_ictx;
-  RWLock::RLocker snap_locker(image_ctx->snap_lock);
-  if (!image_ctx->snaps.empty()) {
-    AbstractObjectWriteRequest<I>::guard_write();
-  }
-}
-
-template <typename I>
-void ObjectRemoveRequest<I>::send_write() {
-  I *image_ctx = this->m_ictx;
-  ldout(image_ctx->cct, 20) << this->m_oid << " remove " << " object exist "
-                            << this->m_object_may_exist << dendl;
-  if (!this->m_object_may_exist && !this->has_parent()) {
-    this->m_state = AbstractObjectWriteRequest<I>::LIBRBD_AIO_WRITE_FLAT;
-    Context *ctx = util::create_context_callback<ObjectRequest<I>>(this);
-    image_ctx->op_work_queue->queue(ctx, 0);
-  } else {
-    this->send_pre_object_map_update();
-  }
-}
-
-template <typename I>
-void ObjectTruncateRequest<I>::send_write() {
+void ObjectDiscardRequest<I>::send_write() {
   I *image_ctx = this->m_ictx;
-  ldout(image_ctx->cct, 20) << this->m_oid << " truncate " << this->m_object_off
-                            << " object exist " << this->m_object_may_exist
+  ldout(image_ctx->cct, 20) << this->m_oid << " " << get_op_type() << " "
+                            << this->m_object_off << "~"
+                            << this->m_object_len << ", "
+                            << "object exist " << this->m_object_may_exist
                             << dendl;
-  if (!this->m_object_may_exist && !this->has_parent()) {
-    this->m_state = AbstractObjectWriteRequest<I>::LIBRBD_AIO_WRITE_FLAT;
-    Context *ctx = util::create_context_callback<ObjectRequest<I>>(this);
-    image_ctx->op_work_queue->queue(ctx, 0);
-  } else {
-    AbstractObjectWriteRequest<I>::send_write();
-  }
-}
 
-template <typename I>
-void ObjectZeroRequest<I>::send_write() {
-  I *image_ctx = this->m_ictx;
-  ldout(image_ctx->cct, 20) << this->m_oid << " zero "
-                            << this->m_object_off << "~" << this->m_object_len
-                            << " object exist " << this->m_object_may_exist
-                            << dendl;
   if (!this->m_object_may_exist && !this->has_parent()) {
+    // optimization: nothing to discard
     this->m_state = AbstractObjectWriteRequest<I>::LIBRBD_AIO_WRITE_FLAT;
     Context *ctx = util::create_context_callback<ObjectRequest<I>>(this);
     image_ctx->op_work_queue->queue(ctx, 0);
+  } else if (m_discard_action == DISCARD_ACTION_REMOVE ||
+             m_discard_action == DISCARD_ACTION_REMOVE_TRUNCATE) {
+    // optimization: skip the copyup path for removals
+    this->send_pre_object_map_update();
   } else {
     AbstractObjectWriteRequest<I>::send_write();
   }
@@ -900,9 +840,6 @@ template class librbd::io::ObjectRequest<librbd::ImageCtx>;
 template class librbd::io::ObjectReadRequest<librbd::ImageCtx>;
 template class librbd::io::AbstractObjectWriteRequest<librbd::ImageCtx>;
 template class librbd::io::ObjectWriteRequest<librbd::ImageCtx>;
-template class librbd::io::ObjectRemoveRequest<librbd::ImageCtx>;
-template class librbd::io::ObjectTrimRequest<librbd::ImageCtx>;
-template class librbd::io::ObjectTruncateRequest<librbd::ImageCtx>;
-template class librbd::io::ObjectZeroRequest<librbd::ImageCtx>;
+template class librbd::io::ObjectDiscardRequest<librbd::ImageCtx>;
 template class librbd::io::ObjectWriteSameRequest<librbd::ImageCtx>;
 template class librbd::io::ObjectCompareAndWriteRequest<librbd::ImageCtx>;
index b36ac0b0e527b65a09be23f04dc02c015634a106..f8d6945fc36bf581323dbf38cf4ce9d9359bf178 100644 (file)
@@ -44,24 +44,6 @@ struct ObjectRequestHandle {
 template <typename ImageCtxT = ImageCtx>
 class ObjectRequest : public ObjectRequestHandle {
 public:
-  static ObjectRequest* create_remove(ImageCtxT *ictx,
-                                      const std::string &oid,
-                                      uint64_t object_no,
-                                      const ::SnapContext &snapc,
-                                     const ZTracer::Trace &parent_trace,
-                                      Context *completion);
-  static ObjectRequest* create_truncate(ImageCtxT *ictx,
-                                        const std::string &oid,
-                                        uint64_t object_no,
-                                        uint64_t object_off,
-                                        const ::SnapContext &snapc,
-                                       const ZTracer::Trace &parent_trace,
-                                        Context *completion);
-  static ObjectRequest* create_trim(ImageCtxT *ictx, const std::string &oid,
-                                    uint64_t object_no,
-                                    const ::SnapContext &snapc,
-                                    bool post_object_map_update,
-                                    Context *completion);
   static ObjectRequest* create_write(ImageCtxT *ictx, const std::string &oid,
                                      uint64_t object_no,
                                      uint64_t object_off,
@@ -69,12 +51,14 @@ public:
                                      const ::SnapContext &snapc, int op_flags,
                                     const ZTracer::Trace &parent_trace,
                                      Context *completion);
-  static ObjectRequest* create_zero(ImageCtxT *ictx, const std::string &oid,
-                                    uint64_t object_no, uint64_t object_off,
-                                    uint64_t object_len,
-                                    const ::SnapContext &snapc,
-                                   const ZTracer::Trace &parent_trace,
-                                    Context *completion);
+  static ObjectRequest* create_discard(ImageCtxT *ictx, const std::string &oid,
+                                       uint64_t object_no, uint64_t object_off,
+                                       uint64_t object_len,
+                                       const ::SnapContext &snapc,
+                                       bool disable_clone_remove,
+                                       bool update_object_map,
+                                       const ZTracer::Trace &parent_trace,
+                                       Context *completion);
   static ObjectRequest* create_writesame(ImageCtxT *ictx,
                                          const std::string &oid,
                                          uint64_t object_no,
@@ -356,154 +340,96 @@ private:
 };
 
 template <typename ImageCtxT = ImageCtx>
-class ObjectRemoveRequest : public AbstractObjectWriteRequest<ImageCtxT> {
+class ObjectDiscardRequest : public AbstractObjectWriteRequest<ImageCtxT> {
 public:
-  ObjectRemoveRequest(ImageCtxT *ictx, const std::string &oid,
-                      uint64_t object_no, const ::SnapContext &snapc,
-                     const ZTracer::Trace &parent_trace, Context *completion)
-    : AbstractObjectWriteRequest<ImageCtxT>(ictx, oid, object_no, 0, 0, snapc,
-                                            true, "remove", parent_trace,
-                                            completion) {
-    if (this->has_parent()) {
-      m_object_state = OBJECT_EXISTS;
+  ObjectDiscardRequest(ImageCtxT *ictx, const std::string &oid,
+                       uint64_t object_no, uint64_t object_off,
+                       uint64_t object_len, const ::SnapContext &snapc,
+                       bool disable_clone_remove, bool update_object_map,
+                       const ZTracer::Trace &parent_trace, Context *completion)
+    : AbstractObjectWriteRequest<ImageCtxT>(ictx, oid, object_no, object_off,
+                                            object_len, snapc, true, "discard",
+                                            parent_trace, completion),
+      m_update_object_map(update_object_map) {
+    if (object_off == 0 && object_len == ictx->layout.object_size) {
+      if (disable_clone_remove && this->has_parent()) {
+        // need to hide the parent object instead of child object
+        m_discard_action = DISCARD_ACTION_REMOVE_TRUNCATE;
+        this->m_object_len = 0;
+      } else {
+        m_discard_action = DISCARD_ACTION_REMOVE;
+      }
+      this->m_guard = (!snapc.snaps.empty());
+    } else if (object_off + object_len == ictx->layout.object_size) {
+      m_discard_action = DISCARD_ACTION_TRUNCATE;
     } else {
-      m_object_state = OBJECT_PENDING;
+      m_discard_action = DISCARD_ACTION_ZERO;
     }
   }
 
   const char* get_op_type() const override {
-    if (this->has_parent()) {
-      return "remove (trunc)";
+    switch (m_discard_action) {
+    case DISCARD_ACTION_REMOVE:
+      return "remove";
+    case DISCARD_ACTION_REMOVE_TRUNCATE:
+      return "remove (truncate)";
+    case DISCARD_ACTION_TRUNCATE:
+      return "truncate";
+    case DISCARD_ACTION_ZERO:
+      return "zero";
     }
-    return "remove";
+    assert(false);
+    return nullptr;
   }
 
   uint8_t get_pre_write_object_map_state() const override {
-    return m_object_state;
+    if (m_discard_action == DISCARD_ACTION_REMOVE) {
+      return OBJECT_PENDING;
+    }
+    return OBJECT_EXISTS;
   }
 
 protected:
   void add_write_hint(librados::ObjectWriteOperation *wr) override {
-    // no hint for remove
+    // no hint for discard
   }
 
   void add_write_ops(librados::ObjectWriteOperation *wr) override {
-    if (this->has_parent()) {
-      wr->truncate(0);
-    } else {
+    switch (m_discard_action) {
+    case DISCARD_ACTION_REMOVE:
       wr->remove();
+      break;
+    case DISCARD_ACTION_REMOVE_TRUNCATE:
+    case DISCARD_ACTION_TRUNCATE:
+      wr->truncate(this->m_object_off);
+      break;
+    case DISCARD_ACTION_ZERO:
+      wr->zero(this->m_object_off, this->m_object_len);
+      break;
+    default:
+      assert(false);
+      break;
     }
   }
 
   bool post_object_map_update() override {
-    if (m_object_state == OBJECT_EXISTS) {
-      return false;
-    }
-    return true;
+    // trim operation updates the object map in batches
+    return (m_update_object_map && m_discard_action == DISCARD_ACTION_REMOVE);
   }
 
-  void guard_write() override;
   void send_write() override;
 
 private:
-  uint8_t m_object_state;
-};
-
-template <typename ImageCtxT = ImageCtx>
-class ObjectTrimRequest : public AbstractObjectWriteRequest<ImageCtxT> {
-public:
-  // we'd need to only conditionally specify if a post object map
-  // update is needed. pre update is decided as usual (by checking
-  // the state of the object in the map).
-  ObjectTrimRequest(ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
-                    const ::SnapContext &snapc, bool post_object_map_update,
-                   Context *completion)
-    : AbstractObjectWriteRequest<ImageCtxT>(ictx, oid, object_no, 0, 0, snapc,
-                                            true, "trim", {}, completion),
-      m_post_object_map_update(post_object_map_update) {
-  }
-
-  const char* get_op_type() const override {
-    return "remove (trim)";
-  }
-
-  uint8_t get_pre_write_object_map_state() const override {
-    return OBJECT_PENDING;
-  }
-
-protected:
-  void add_write_hint(librados::ObjectWriteOperation *wr) override {
-    // no hint for remove
-  }
-
-  void add_write_ops(librados::ObjectWriteOperation *wr) override {
-    wr->remove();
-  }
-
-  bool post_object_map_update() override {
-    return m_post_object_map_update;
-  }
-
-private:
-  bool m_post_object_map_update;
-};
-
-template <typename ImageCtxT = ImageCtx>
-class ObjectTruncateRequest : public AbstractObjectWriteRequest<ImageCtxT> {
-public:
-  ObjectTruncateRequest(ImageCtxT *ictx, const std::string &oid,
-                        uint64_t object_no, uint64_t object_off,
-                        const ::SnapContext &snapc,
-                       const ZTracer::Trace &parent_trace, Context *completion)
-    : AbstractObjectWriteRequest<ImageCtxT>(ictx, oid, object_no, object_off, 0,
-                                            snapc, true, "truncate",
-                                            parent_trace, completion) {
-  }
-
-  const char* get_op_type() const override {
-    return "truncate";
-  }
-
-  uint8_t get_pre_write_object_map_state() const override {
-    if (!this->m_object_may_exist && !this->has_parent())
-      return OBJECT_NONEXISTENT;
-    return OBJECT_EXISTS;
-  }
-
-protected:
-  void add_write_hint(librados::ObjectWriteOperation *wr) override {
-    // no hint for truncate
-  }
-
-  void add_write_ops(librados::ObjectWriteOperation *wr) override {
-    wr->truncate(this->m_object_off);
-  }
-
-  void send_write() override;
-};
-
-template <typename ImageCtxT = ImageCtx>
-class ObjectZeroRequest : public AbstractObjectWriteRequest<ImageCtxT> {
-public:
-  ObjectZeroRequest(ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
-                    uint64_t object_off, uint64_t object_len,
-                    const ::SnapContext &snapc,
-                   const ZTracer::Trace &parent_trace, Context *completion)
-    : AbstractObjectWriteRequest<ImageCtxT>(ictx, oid, object_no, object_off,
-                                            object_len, snapc, true, "zero",
-                                            parent_trace, completion) {
-  }
-
-  const char* get_op_type() const override {
-    return "zero";
-  }
+  enum DiscardAction {
+    DISCARD_ACTION_REMOVE,
+    DISCARD_ACTION_REMOVE_TRUNCATE,
+    DISCARD_ACTION_TRUNCATE,
+    DISCARD_ACTION_ZERO
+  };
 
-protected:
-  void add_write_ops(librados::ObjectWriteOperation *wr) override {
-    wr->zero(this->m_object_off, this->m_object_len);
-  }
+  DiscardAction m_discard_action;
+  bool m_update_object_map;
 
-  void send_write() override;
 };
 
 template <typename ImageCtxT = ImageCtx>
@@ -580,10 +506,7 @@ extern template class librbd::io::ObjectRequest<librbd::ImageCtx>;
 extern template class librbd::io::ObjectReadRequest<librbd::ImageCtx>;
 extern template class librbd::io::AbstractObjectWriteRequest<librbd::ImageCtx>;
 extern template class librbd::io::ObjectWriteRequest<librbd::ImageCtx>;
-extern template class librbd::io::ObjectRemoveRequest<librbd::ImageCtx>;
-extern template class librbd::io::ObjectTrimRequest<librbd::ImageCtx>;
-extern template class librbd::io::ObjectTruncateRequest<librbd::ImageCtx>;
-extern template class librbd::io::ObjectZeroRequest<librbd::ImageCtx>;
+extern template class librbd::io::ObjectDiscardRequest<librbd::ImageCtx>;
 extern template class librbd::io::ObjectWriteSameRequest<librbd::ImageCtx>;
 extern template class librbd::io::ObjectCompareAndWriteRequest<librbd::ImageCtx>;
 
index 28f2deb1af84f9d9f1137fe6faddf3348089f862..4ae63260334f6b56d132dee6ea7d0675081a26a0 100644 (file)
@@ -45,8 +45,9 @@ public:
     string oid = image_ctx.get_object_name(m_object_no);
     ldout(image_ctx.cct, 10) << "removing (with copyup) " << oid << dendl;
 
-    auto req = io::ObjectRequest<I>::create_trim(&image_ctx, oid, m_object_no,
-                                                 m_snapc, false, this);
+    auto req = io::ObjectRequest<I>::create_discard(
+      &image_ctx, oid, m_object_no, 0, image_ctx.layout.object_size, m_snapc,
+      false, false, {}, this);
     req->send();
     return 0;
   }
@@ -338,16 +339,14 @@ void TrimRequest<I>::send_clean_boundary() {
     ldout(cct, 20) << " ex " << *p << dendl;
     Context *req_comp = new C_ContextCompletion(*completion);
 
-    io::ObjectRequest<I> *req;
     if (p->offset == 0) {
-      req = io::ObjectRequest<I>::create_trim(&image_ctx, p->oid.name,
-                                              p->objectno, snapc, true,
-                                              req_comp);
-    } else {
-      req = io::ObjectRequest<I>::create_truncate(&image_ctx, p->oid.name,
-                                                  p->objectno, p->offset, snapc,
-                                                  {}, req_comp);
+      // treat as a full object delete on the boundary
+      p->length = image_ctx.layout.object_size;
     }
+    auto req = io::ObjectRequest<I>::create_discard(&image_ctx, p->oid.name,
+                                                    p->objectno, p->offset,
+                                                    p->length, snapc, false,
+                                                    true, {}, req_comp);
     req->send();
   }
   completion->finish_adding_requests();
index 7925ce928f45c08279423c32d4f11e684bb256d4..bd1ff6795309165bac1fc30057db9493db74ecfb 100644 (file)
@@ -34,29 +34,6 @@ struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
   static ObjectRequest* s_instance;
   Context *on_finish = nullptr;
 
-  static ObjectRequest* create_remove(librbd::MockTestImageCtx *ictx,
-                                      const std::string &oid,
-                                      uint64_t object_no,
-                                      const ::SnapContext &snapc,
-                                      const ZTracer::Trace &parent_trace,
-                                      Context *completion) {
-    assert(s_instance != nullptr);
-    s_instance->on_finish = completion;
-    return s_instance;
-  }
-
-  static ObjectRequest* create_truncate(librbd::MockTestImageCtx *ictx,
-                                        const std::string &oid,
-                                        uint64_t object_no,
-                                        uint64_t object_off,
-                                        const ::SnapContext &snapc,
-                                        const ZTracer::Trace &parent_trace,
-                                        Context *completion) {
-    assert(s_instance != nullptr);
-    s_instance->on_finish = completion;
-    return s_instance;
-  }
-
   static ObjectRequest* create_write(librbd::MockTestImageCtx *ictx,
                                      const std::string &oid,
                                      uint64_t object_no,
@@ -70,14 +47,18 @@ struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
     return s_instance;
   }
 
-  static ObjectRequest* create_zero(librbd::MockTestImageCtx *ictx,
-                                    const std::string &oid,
-                                    uint64_t object_no, uint64_t object_off,
-                                    uint64_t object_len,
-                                    const ::SnapContext &snapc,
-                                    const ZTracer::Trace &parent_trace,
-                                    Context *completion) {
+  static ObjectRequest* create_discard(librbd::MockTestImageCtx *ictx,
+                                       const std::string &oid,
+                                       uint64_t object_no, uint64_t object_off,
+                                       uint64_t object_len,
+                                       const ::SnapContext &snapc,
+                                       bool disable_remove_on_clone,
+                                       bool update_object_map,
+                                       const ZTracer::Trace &parent_trace,
+                                       Context *completion) {
     assert(s_instance != nullptr);
+    EXPECT_TRUE(disable_remove_on_clone);
+    EXPECT_TRUE(update_object_map);
     s_instance->on_finish = completion;
     return s_instance;
   }
index 7a8cb43e80cfbb22193e47531e2e9166344703ad..f998901c31dcfcaa283e6e7db8b7449a3d31b5ac 100644 (file)
@@ -70,28 +70,20 @@ struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
   static ObjectRequest* s_instance;
   Context *on_finish = nullptr;
 
-  static ObjectRequest* create_truncate(librbd::MockTestImageCtx *ictx,
-                                        const std::string &oid,
-                                        uint64_t object_no,
-                                        uint64_t object_off,
-                                        const ::SnapContext &snapc,
-                                        const ZTracer::Trace &parent_trace,
-                                        Context *completion) {
+  static ObjectRequest* create_discard(librbd::MockTestImageCtx *ictx,
+                                       const std::string &oid,
+                                       uint64_t object_no,
+                                       uint64_t object_off,
+                                       uint64_t object_len,
+                                       const ::SnapContext &snapc,
+                                       bool disable_remove_on_clone,
+                                       bool update_object_map,
+                                       const ZTracer::Trace &parent_trace,
+                                       Context *completion) {
     assert(s_instance != nullptr);
+    EXPECT_FALSE(disable_remove_on_clone);
     s_instance->on_finish = completion;
-    s_instance->construct_truncate();
-    return s_instance;
-  }
-
-  static ObjectRequest* create_trim(librbd::MockTestImageCtx *ictx,
-                                    const std::string &oid,
-                                    uint64_t object_no,
-                                    const ::SnapContext &snapc,
-                                    bool post_object_map_update,
-                                    Context *completion) {
-    assert(s_instance != nullptr);
-    s_instance->on_finish = completion;
-    s_instance->construct_trim();
+    s_instance->construct(object_off, object_len, update_object_map);
     return s_instance;
   }
 
@@ -99,8 +91,7 @@ struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
     s_instance = this;
   }
 
-  MOCK_METHOD0(construct_truncate, void());
-  MOCK_METHOD0(construct_trim, void());
+  MOCK_METHOD3(construct, void(uint64_t, uint64_t, bool));
   MOCK_METHOD0(send, void());
   MOCK_METHOD1(complete, void(int));
 };
@@ -203,19 +194,12 @@ public:
       .WillOnce(Return(ret_val));
   }
 
-  void expect_object_trim(MockImageCtx &mock_image_ctx,
-                          MockObjectRequest &mock_object_request, int ret_val) {
-    EXPECT_CALL(mock_object_request, construct_trim());
-    EXPECT_CALL(mock_object_request, send())
-      .WillOnce(Invoke([&mock_image_ctx, &mock_object_request, ret_val]() {
-                         mock_image_ctx.op_work_queue->queue(mock_object_request.on_finish, ret_val);
-                       }));
-  }
-
-  void expect_object_truncate(MockImageCtx &mock_image_ctx,
-                              MockObjectRequest &mock_object_request,
-                              int ret_val) {
-    EXPECT_CALL(mock_object_request, construct_truncate());
+  void expect_object_discard(MockImageCtx &mock_image_ctx,
+                             MockObjectRequest &mock_object_request,
+                             uint64_t offset, uint64_t length,
+                             bool update_object_map, int ret_val) {
+    EXPECT_CALL(mock_object_request, construct(offset, length,
+                                               update_object_map));
     EXPECT_CALL(mock_object_request, send())
       .WillOnce(Invoke([&mock_image_ctx, &mock_object_request, ret_val]() {
                          mock_image_ctx.op_work_queue->queue(mock_object_request.on_finish, ret_val);
@@ -304,7 +288,8 @@ TEST_F(TestMockOperationTrimRequest, SuccessCopyUp) {
   expect_get_object_name(mock_image_ctx, 0, "object0");
 
   MockObjectRequest mock_object_request;
-  expect_object_trim(mock_image_ctx, mock_object_request, 0);
+  expect_object_discard(mock_image_ctx, mock_object_request, 0,
+                        ictx->get_object_size(), false, 0);
 
   // remove
   expect_object_may_exist(mock_image_ctx, 1, true);
@@ -345,7 +330,8 @@ TEST_F(TestMockOperationTrimRequest, SuccessBoundary) {
 
   // boundary
   MockObjectRequest mock_object_request;
-  expect_object_truncate(mock_image_ctx, mock_object_request, 0);
+  expect_object_discard(mock_image_ctx, mock_object_request, 1,
+                        ictx->get_object_size() - 1, true, 0);
 
   C_SaferCond cond_ctx;
   librbd::NoOpProgressContext progress_ctx;
@@ -447,7 +433,8 @@ TEST_F(TestMockOperationTrimRequest, CopyUpError) {
   expect_get_object_name(mock_image_ctx, 0, "object0");
 
   MockObjectRequest mock_object_request;
-  expect_object_trim(mock_image_ctx, mock_object_request, -EINVAL);
+  expect_object_discard(mock_image_ctx, mock_object_request, 0,
+                        ictx->get_object_size(), false, -EINVAL);
 
   C_SaferCond cond_ctx;
   librbd::NoOpProgressContext progress_ctx;
@@ -479,7 +466,8 @@ TEST_F(TestMockOperationTrimRequest, BoundaryError) {
 
   // boundary
   MockObjectRequest mock_object_request;
-  expect_object_truncate(mock_image_ctx, mock_object_request, -EINVAL);
+  expect_object_discard(mock_image_ctx, mock_object_request, 1,
+                        ictx->get_object_size() - 1, true, -EINVAL);
 
   C_SaferCond cond_ctx;
   librbd::NoOpProgressContext progress_ctx;
index f2d32c1eb2daeadd71688a6e55829ddd5367ff2c..d154284d98c60be4cc6c2e8b8eb7926b5810405c 100644 (file)
@@ -1019,8 +1019,9 @@ TEST_F(TestMockJournal, EventCommitError) {
   };
 
   C_SaferCond object_request_ctx;
-  auto object_request = new io::ObjectRemoveRequest<>(
-    ictx, "oid", 0, {}, {}, &object_request_ctx);
+  auto object_request = new io::ObjectDiscardRequest<>(
+    ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
+    &object_request_ctx);
 
   ::journal::MockFuture mock_future;
   Context *on_journal_safe;
@@ -1060,8 +1061,9 @@ TEST_F(TestMockJournal, EventCommitErrorWithPendingWriteback) {
   };
 
   C_SaferCond object_request_ctx;
-  auto object_request = new io::ObjectRemoveRequest<>(
-    ictx, "oid", 0, {}, {}, &object_request_ctx);
+  auto object_request = new io::ObjectDiscardRequest<>(
+    ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
+    &object_request_ctx);
 
   ::journal::MockFuture mock_future;
   Context *on_journal_safe;