]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: discard hangs when 'rbd_skip_partial_discard' is enabled
authorMykola Golub <mgolub@mirantis.com>
Thu, 30 Jun 2016 11:30:08 +0000 (14:30 +0300)
committerMykola Golub <mgolub@mirantis.com>
Fri, 19 Aug 2016 19:59:06 +0000 (22:59 +0300)
Fixes: http://tracker.ceph.com/issues/16386
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
(cherry picked from commit dc41731fbfd73d9fbb63d3ff360d4c5dd62deaf1)

src/librbd/AioImageRequest.cc
src/librbd/AioImageRequest.h

index a01a3d85d474c1c55336b3efcf97e5713df19cd1..01e7689ee9d412c150cd5d897417b30483b5b0c5 100644 (file)
@@ -255,6 +255,8 @@ void AbstractAioImageWrite::send_request() {
                   !m_image_ctx.journal->is_journal_replaying());
   }
 
+  prune_object_extents(object_extents);
+
   if (!object_extents.empty()) {
     uint64_t journal_tid = 0;
     m_aio_comp->set_request_count(
@@ -383,6 +385,24 @@ uint64_t AioImageDiscard::append_journal_event(
   return tid;
 }
 
+void AioImageDiscard::prune_object_extents(ObjectExtents &object_extents) {
+  CephContext *cct = m_image_ctx.cct;
+  if (!cct->_conf->rbd_skip_partial_discard) {
+    return;
+  }
+
+  for (auto p = object_extents.begin(); p != object_extents.end(); ) {
+    if (p->offset + p->length < m_image_ctx.layout.object_size) {
+      ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~"
+                    << p->length << " from " << p->buffer_extents
+                    << ": skip partial discard" << dendl;
+      p = object_extents.erase(p);
+    } else {
+      ++p;
+    }
+  }
+}
+
 uint32_t AioImageDiscard::get_cache_request_count(bool journaling) const {
   // extra completion request is required for tracking journal commit
   return (m_image_ctx.object_cacher != nullptr && journaling ? 1 : 0);
@@ -406,8 +426,6 @@ void AioImageDiscard::send_cache_requests(const ObjectExtents &object_extents,
 AioObjectRequest *AioImageDiscard::create_object_request(
     const ObjectExtent &object_extent, const ::SnapContext &snapc,
     Context *on_finish) {
-  CephContext *cct = m_image_ctx.cct;
-
   AioObjectRequest *req;
   if (object_extent.length == m_image_ctx.layout.object_size) {
     req = new AioObjectRemove(&m_image_ctx, object_extent.oid.name,
@@ -418,10 +436,6 @@ AioObjectRequest *AioImageDiscard::create_object_request(
                                 object_extent.objectno, object_extent.offset,
                                 snapc, on_finish);
   } else {
-    if(cct->_conf->rbd_skip_partial_discard) {
-      delete on_finish;
-      return NULL;
-    }
     req = new AioObjectZero(&m_image_ctx, object_extent.oid.name,
                             object_extent.objectno, object_extent.offset,
                             object_extent.length, snapc, on_finish);
index 0ddbbaf74e4a81a2a108a9db81260b77d61d4dd2..b95b5f9e741ec1dec2be4eebc2b2b19d0a312c9a 100644 (file)
@@ -116,6 +116,8 @@ protected:
 
   virtual void send_request();
 
+  virtual void prune_object_extents(ObjectExtents &object_extents) {
+  }
   virtual uint32_t get_cache_request_count(bool journaling) const {
     return 0;
   }
@@ -188,6 +190,7 @@ protected:
     return "aio_discard";
   }
 
+  virtual void prune_object_extents(ObjectExtents &object_extents) override;
   virtual uint32_t get_cache_request_count(bool journaling) const override;
   virtual void send_cache_requests(const ObjectExtents &object_extents,
                                    uint64_t journal_tid);