From: Mykola Golub Date: Thu, 30 Jun 2016 11:30:08 +0000 (+0300) Subject: librbd: discard hangs when 'rbd_skip_partial_discard' is enabled X-Git-Tag: v10.2.3~48^2~18 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d0c0c2fce39091915428e815bc6aee265ac9e351;p=ceph.git librbd: discard hangs when 'rbd_skip_partial_discard' is enabled Fixes: http://tracker.ceph.com/issues/16386 Signed-off-by: Mykola Golub (cherry picked from commit dc41731fbfd73d9fbb63d3ff360d4c5dd62deaf1) --- diff --git a/src/librbd/AioImageRequest.cc b/src/librbd/AioImageRequest.cc index a01a3d85d474..01e7689ee9d4 100644 --- a/src/librbd/AioImageRequest.cc +++ b/src/librbd/AioImageRequest.cc @@ -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); diff --git a/src/librbd/AioImageRequest.h b/src/librbd/AioImageRequest.h index 0ddbbaf74e4a..b95b5f9e741e 100644 --- a/src/librbd/AioImageRequest.h +++ b/src/librbd/AioImageRequest.h @@ -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);