From: Jason Dillaman Date: Wed, 4 Apr 2018 15:48:56 +0000 (-0400) Subject: librbd: discard should wait for in-flight cache writeback to complete X-Git-Tag: v13.1.0~372^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F21248%2Fhead;p=ceph.git librbd: discard should wait for in-flight cache writeback to complete Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/cache/ObjectCacherObjectDispatch.cc b/src/librbd/cache/ObjectCacherObjectDispatch.cc index 8531a190ba13..3a5ac40e7528 100644 --- a/src/librbd/cache/ObjectCacherObjectDispatch.cc +++ b/src/librbd/cache/ObjectCacherObjectDispatch.cc @@ -215,13 +215,14 @@ bool ObjectCacherObjectDispatch::discard( ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~" << object_len << dendl; - // discard the cache state after changes are committed to disk + ObjectExtents object_extents; + object_extents.emplace_back(oid, object_no, object_off, object_len, 0); + + // discard the cache state after changes are committed to disk (and to + // prevent races w/ readahead) auto ctx = *on_finish; *on_finish = new FunctionContext( - [this, oid, object_no, object_off, object_len, ctx](int r) { - ObjectExtents object_extents; - object_extents.emplace_back(oid, object_no, object_off, object_len, 0); - + [this, object_extents, ctx](int r) { m_cache_lock.Lock(); m_object_cacher->discard_set(m_object_set, object_extents); m_cache_lock.Unlock(); @@ -229,9 +230,19 @@ bool ObjectCacherObjectDispatch::discard( ctx->complete(r); }); - // pass-through the discard request since ObjectCacher won't - // writeback discards. - return false; + // ensure we aren't holding the cache lock post-write + on_dispatched = util::create_async_context_callback(*m_image_ctx, + on_dispatched); + + *dispatch_result = io::DISPATCH_RESULT_CONTINUE; + + // ensure any in-flight writeback is complete before advancing + // the discard request + m_cache_lock.Lock(); + m_object_cacher->discard_writeback(m_object_set, object_extents, + on_dispatched); + m_cache_lock.Unlock(); + return true; } template