]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/operation/TrimRequest.cc
update sources to 12.2.2
[ceph.git] / ceph / src / librbd / operation / TrimRequest.cc
index 46ec967b5eddcb3bf8d6aa0db32ce42e82516a3c..28f2deb1af84f9d9f1137fe6faddf3348089f862 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;
 
-    auto req = new io::ObjectTrimRequest(&image_ctx, oid, m_object_no,
-                                         m_snapc, false, this);
+    auto req = io::ObjectRequest<I>::create_trim(&image_ctx, oid, m_object_no,
+                                                 m_snapc, false, this);
     req->send();
     return 0;
   }
@@ -58,7 +58,7 @@ private:
 template <typename I>
 class C_RemoveObject : public C_AsyncObjectThrottle<I> {
 public:
-  C_RemoveObject(AsyncObjectThrottle<I> &throttle, ImageCtx *image_ctx,
+  C_RemoveObject(AsyncObjectThrottle<I> &throttle, I *image_ctx,
                  uint64_t object_no)
     : C_AsyncObjectThrottle<I>(throttle, *image_ctx), m_object_no(object_no)
   {
@@ -105,6 +105,7 @@ TrimRequest<I>::TrimRequest(I &image_ctx, Context *on_finish,
   m_delete_off = MIN(new_num_periods * period, original_size);
   // first object we can delete free and clear
   m_delete_start = new_num_periods * image_ctx.get_stripe_count();
+  m_delete_start_min = m_delete_start;
   m_num_objects = Striper::get_num_objects(image_ctx.layout, original_size);
 
   CephContext *cct = image_ctx.cct;
@@ -131,33 +132,23 @@ bool TrimRequest<I>::should_complete(int r)
 
   RWLock::RLocker owner_lock(image_ctx.owner_lock);
   switch (m_state) {
-  case STATE_PRE_COPYUP:
-    ldout(cct, 5) << " PRE_COPYUP" << dendl;
+  case STATE_PRE_TRIM:
+    ldout(cct, 5) << " PRE_TRIM" << dendl;
     send_copyup_objects();
     break;
 
   case STATE_COPYUP_OBJECTS:
     ldout(cct, 5) << " COPYUP_OBJECTS" << dendl;
-    send_post_copyup();
-    break;
-
-  case STATE_POST_COPYUP:
-    ldout(cct, 5) << " POST_COPYUP" << dendl;
-    send_pre_remove();
-    break;
-
-  case STATE_PRE_REMOVE:
-    ldout(cct, 5) << " PRE_REMOVE" << dendl;
     send_remove_objects();
     break;
 
   case STATE_REMOVE_OBJECTS:
     ldout(cct, 5) << " REMOVE_OBJECTS" << dendl;
-    send_post_remove();
+    send_post_trim();
     break;
 
-  case STATE_POST_REMOVE:
-    ldout(cct, 5) << " POST_OBJECTS" << dendl;
+  case STATE_POST_TRIM:
+    ldout(cct, 5) << " POST_TRIM" << dendl;
     send_clean_boundary();
     break;
 
@@ -180,198 +171,132 @@ bool TrimRequest<I>::should_complete(int r)
 
 template <typename I>
 void TrimRequest<I>::send() {
-  send_pre_copyup();
+  send_pre_trim();
 }
 
 template<typename I>
-void TrimRequest<I>::send_copyup_objects() {
+void TrimRequest<I>::send_pre_trim() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
 
-  ldout(image_ctx.cct, 5) << this << " send_copyup_objects: "
-                          << " start object=" << m_copyup_start << ", "
-                          << " end object=" << m_copyup_end << dendl;
-  m_state = STATE_COPYUP_OBJECTS;
+  if (m_delete_start >= m_num_objects) {
+    send_clean_boundary();
+    return;
+  }
 
-  ::SnapContext snapc;
   {
     RWLock::RLocker snap_locker(image_ctx.snap_lock);
-    RWLock::RLocker parent_locker(image_ctx.parent_lock);
-    snapc = image_ctx.snapc;
-  }
-
-  Context *ctx = this->create_callback_context();
-  typename AsyncObjectThrottle<I>::ContextFactory context_factory(
-    boost::lambda::bind(boost::lambda::new_ptr<C_CopyupObject<I> >(),
-      boost::lambda::_1, &image_ctx, snapc, boost::lambda::_2));
-  AsyncObjectThrottle<I> *throttle = new AsyncObjectThrottle<I>(
-    this, image_ctx, context_factory, ctx, &m_prog_ctx, m_copyup_start,
-    m_copyup_end);
-  throttle->start_ops(image_ctx.concurrent_management_ops);
-}
+    if (image_ctx.object_map != nullptr) {
+      ldout(image_ctx.cct, 5) << this << " send_pre_trim: "
+                              << " delete_start_min=" << m_delete_start_min
+                              << " num_objects=" << m_num_objects << dendl;
+      m_state = STATE_PRE_TRIM;
 
-template <typename I>
-void TrimRequest<I>::send_remove_objects() {
-  I &image_ctx = this->m_image_ctx;
-  assert(image_ctx.owner_lock.is_locked());
+      assert(image_ctx.exclusive_lock->is_lock_owner());
 
-  ldout(image_ctx.cct, 5) << this << " send_remove_objects: "
-                           << " delete_start=" << m_delete_start
-                           << " num_objects=" << m_num_objects << dendl;
-  m_state = STATE_REMOVE_OBJECTS;
+      RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
+      if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
+            CEPH_NOSNAP, m_delete_start_min, m_num_objects, OBJECT_PENDING,
+            OBJECT_EXISTS, {}, this)) {
+        return;
+      }
+    }
+  }
 
-  Context *ctx = this->create_callback_context();
-  typename AsyncObjectThrottle<I>::ContextFactory context_factory(
-    boost::lambda::bind(boost::lambda::new_ptr<C_RemoveObject<I> >(),
-      boost::lambda::_1, &image_ctx, boost::lambda::_2));
-  AsyncObjectThrottle<I> *throttle = new AsyncObjectThrottle<I>(
-    this, image_ctx, context_factory, ctx, &m_prog_ctx, m_delete_start,
-    m_num_objects);
-  throttle->start_ops(image_ctx.concurrent_management_ops);
+  send_copyup_objects();
 }
 
 template<typename I>
-void TrimRequest<I>::send_pre_copyup() {
+void TrimRequest<I>::send_copyup_objects() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
 
-  if (m_delete_start >= m_num_objects) {
-    send_clean_boundary();
-    return;
-  }
-
+  ::SnapContext snapc;
   bool has_snapshots;
   uint64_t parent_overlap;
   {
     RWLock::RLocker snap_locker(image_ctx.snap_lock);
     RWLock::RLocker parent_locker(image_ctx.parent_lock);
 
+    snapc = image_ctx.snapc;
     has_snapshots = !image_ctx.snaps.empty();
     int r = image_ctx.get_parent_overlap(CEPH_NOSNAP, &parent_overlap);
     assert(r == 0);
   }
 
   // copyup is only required for portion of image that overlaps parent
-  m_copyup_end = Striper::get_num_objects(image_ctx.layout, parent_overlap);
+  uint64_t copyup_end = Striper::get_num_objects(image_ctx.layout,
+                                                 parent_overlap);
 
   // TODO: protect against concurrent shrink and snap create?
   // skip to remove if no copyup is required.
-  if (m_copyup_end <= m_delete_start || !has_snapshots) {
-    send_pre_remove();
+  if (copyup_end <= m_delete_start || !has_snapshots) {
+    send_remove_objects();
     return;
   }
 
-  m_copyup_start = m_delete_start;
-  m_delete_start = m_copyup_end;
-
-  {
-    RWLock::RLocker snap_locker(image_ctx.snap_lock);
-    if (image_ctx.object_map != nullptr) {
-      ldout(image_ctx.cct, 5) << this << " send_pre_copyup: "
-                              << " copyup_start=" << m_copyup_start
-                              << " copyup_end=" << m_copyup_end << dendl;
-      m_state = STATE_PRE_COPYUP;
-
-      assert(image_ctx.exclusive_lock->is_lock_owner());
+  uint64_t copyup_start = m_delete_start;
+  m_delete_start = copyup_end;
 
-      RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
-      if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
-            CEPH_NOSNAP, m_copyup_start, m_copyup_end, OBJECT_PENDING,
-            OBJECT_EXISTS, {}, this)) {
-        return;
-      }
-    }
-  }
+  ldout(image_ctx.cct, 5) << this << " send_copyup_objects: "
+                          << " start object=" << copyup_start << ", "
+                          << " end object=" << copyup_end << dendl;
+  m_state = STATE_COPYUP_OBJECTS;
 
-  send_copyup_objects();
+  Context *ctx = this->create_callback_context();
+  typename AsyncObjectThrottle<I>::ContextFactory context_factory(
+    boost::lambda::bind(boost::lambda::new_ptr<C_CopyupObject<I> >(),
+      boost::lambda::_1, &image_ctx, snapc, boost::lambda::_2));
+  AsyncObjectThrottle<I> *throttle = new AsyncObjectThrottle<I>(
+    this, image_ctx, context_factory, ctx, &m_prog_ctx, copyup_start,
+    copyup_end);
+  throttle->start_ops(image_ctx.concurrent_management_ops);
 }
 
 template <typename I>
-void TrimRequest<I>::send_pre_remove() {
+void TrimRequest<I>::send_remove_objects() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
-  if (m_delete_start >= m_num_objects) {
-    send_clean_boundary();
-    return;
-  }
-
-  {
-    RWLock::RLocker snap_locker(image_ctx.snap_lock);
-    if (image_ctx.object_map != nullptr) {
-      ldout(image_ctx.cct, 5) << this << " send_pre_remove: "
-                               << " delete_start=" << m_delete_start
-                               << " num_objects=" << m_num_objects << dendl;
-      m_state = STATE_PRE_REMOVE;
-
-      assert(image_ctx.exclusive_lock->is_lock_owner());
 
-      // flag the objects as pending deletion
-      RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
-      if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
-            CEPH_NOSNAP, m_delete_start, m_num_objects, OBJECT_PENDING,
-            OBJECT_EXISTS, {}, this)) {
-        return;
-      }
-    }
-  }
+  ldout(image_ctx.cct, 5) << this << " send_remove_objects: "
+                           << " delete_start=" << m_delete_start
+                           << " num_objects=" << m_num_objects << dendl;
+  m_state = STATE_REMOVE_OBJECTS;
 
-  // no object map update required
-  send_remove_objects();
+  Context *ctx = this->create_callback_context();
+  typename AsyncObjectThrottle<I>::ContextFactory context_factory(
+    boost::lambda::bind(boost::lambda::new_ptr<C_RemoveObject<I> >(),
+      boost::lambda::_1, &image_ctx, boost::lambda::_2));
+  AsyncObjectThrottle<I> *throttle = new AsyncObjectThrottle<I>(
+    this, image_ctx, context_factory, ctx, &m_prog_ctx, m_delete_start,
+    m_num_objects);
+  throttle->start_ops(image_ctx.concurrent_management_ops);
 }
 
 template<typename I>
-void TrimRequest<I>::send_post_copyup() {
-  I &image_ctx = this->m_image_ctx;
-  assert(image_ctx.owner_lock.is_locked());
-
-  {
-    RWLock::RLocker snap_locker(image_ctx.snap_lock);
-    if (image_ctx.object_map != nullptr) {
-      ldout(image_ctx.cct, 5) << this << " send_post_copyup:"
-                              << " copyup_start=" << m_copyup_start
-                              << " copyup_end=" << m_copyup_end << dendl;
-      m_state = STATE_POST_COPYUP;
-
-      assert(image_ctx.exclusive_lock->is_lock_owner());
-
-      RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
-      if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
-            CEPH_NOSNAP, m_copyup_start, m_copyup_end, OBJECT_NONEXISTENT,
-            OBJECT_PENDING, {}, this)) {
-        return;
-      }
-    }
-  }
-
-  send_pre_remove();
-}
-
-template <typename I>
-void TrimRequest<I>::send_post_remove() {
+void TrimRequest<I>::send_post_trim() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
 
   {
     RWLock::RLocker snap_locker(image_ctx.snap_lock);
     if (image_ctx.object_map != nullptr) {
-      ldout(image_ctx.cct, 5) << this << " send_post_remove: "
-                               << " delete_start=" << m_delete_start
-                               << " num_objects=" << m_num_objects << dendl;
-      m_state = STATE_POST_REMOVE;
+      ldout(image_ctx.cct, 5) << this << " send_post_trim:"
+                              << " delete_start_min=" << m_delete_start_min
+                              << " num_objects=" << m_num_objects << dendl;
+      m_state = STATE_POST_TRIM;
 
       assert(image_ctx.exclusive_lock->is_lock_owner());
 
-      // flag the pending objects as removed
       RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
       if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
-            CEPH_NOSNAP, m_delete_start, m_num_objects, OBJECT_NONEXISTENT,
+            CEPH_NOSNAP, m_delete_start_min, m_num_objects, OBJECT_NONEXISTENT,
             OBJECT_PENDING, {}, this)) {
         return;
       }
     }
   }
 
-  // no object map update required
   send_clean_boundary();
 }
 
@@ -413,13 +338,15 @@ void TrimRequest<I>::send_clean_boundary() {
     ldout(cct, 20) << " ex " << *p << dendl;
     Context *req_comp = new C_ContextCompletion(*completion);
 
-    io::ObjectRequest<> *req;
+    io::ObjectRequest<I> *req;
     if (p->offset == 0) {
-      req = new io::ObjectTrimRequest(&image_ctx, p->oid.name, p->objectno,
-                                      snapc, true, req_comp);
+      req = io::ObjectRequest<I>::create_trim(&image_ctx, p->oid.name,
+                                              p->objectno, snapc, true,
+                                              req_comp);
     } else {
-      req = new io::ObjectTruncateRequest(&image_ctx, p->oid.name, p->objectno,
-                                          p->offset, snapc, {}, req_comp);
+      req = io::ObjectRequest<I>::create_truncate(&image_ctx, p->oid.name,
+                                                  p->objectno, p->offset, snapc,
+                                                  {}, req_comp);
     }
     req->send();
   }