From dc41731fbfd73d9fbb63d3ff360d4c5dd62deaf1 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Thu, 30 Jun 2016 14:30:08 +0300 Subject: [PATCH] librbd: discard hangs when 'rbd_skip_partial_discard' is enabled Fixes: http://tracker.ceph.com/issues/16386 Signed-off-by: Mykola Golub --- src/librbd/AioImageRequest.cc | 26 ++++++++++++++++++++------ src/librbd/AioImageRequest.h | 3 +++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/librbd/AioImageRequest.cc b/src/librbd/AioImageRequest.cc index 7292978dba550..0c5a916cde04d 100644 --- a/src/librbd/AioImageRequest.cc +++ b/src/librbd/AioImageRequest.cc @@ -264,6 +264,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( @@ -392,6 +394,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); @@ -415,8 +435,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, @@ -427,10 +445,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); diff --git a/src/librbd/AioImageRequest.h b/src/librbd/AioImageRequest.h index c3987a873105e..b3fc754f889aa 100644 --- a/src/librbd/AioImageRequest.h +++ b/src/librbd/AioImageRequest.h @@ -113,6 +113,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; } @@ -179,6 +181,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); -- 2.39.5