From 8ff0fd90788174051c095746a5ff06eb9611764e Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Thu, 5 Jul 2018 14:27:12 +0300 Subject: [PATCH] os/bluestore: fix incomplete faulty range marking when doing compression GC. Under some scenarios GC might process an extent range where some inner extents are left untouched by GC (as there is no need for that). Hence GC doesn't invaliate these inner extents with fault_range call. If untouched extents are mapped to unloaded shards it results in subsequent assertion on o->extent_map.dirty_range() call. The solution is to invalidate the whole extent range when doing GC. Fixes: https://tracker.ceph.com/issues/23540 Fixes: http://tracker.ceph.com/issues/24260 Signed-off-by: Igor Fedotov (cherry picked from commit 0f04d4484c8663767bdb60f743a8835897013b5a) --- src/os/bluestore/BlueStore.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 6fdd11b170b..ba8dd259d49 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -10413,6 +10413,7 @@ int BlueStore::_do_gc( { auto& extents_to_collect = gc.get_extents_to_collect(); + bool dirty_range_updated = false; WriteContext wctx_gc; wctx_gc.fork(wctx); // make a clone for garbage collection @@ -10429,12 +10430,17 @@ int BlueStore::_do_gc( if (*dirty_start > it->offset) { *dirty_start = it->offset; + dirty_range_updated = true; } if (*dirty_end < it->offset + it->length) { *dirty_end = it->offset + it->length; + dirty_range_updated = true; } } + if (dirty_range_updated) { + o->extent_map.fault_range(db, *dirty_start, *dirty_end); + } dout(30) << __func__ << " alloc write" << dendl; int r = _do_alloc_write(txc, c, o, &wctx_gc); @@ -10516,9 +10522,10 @@ int BlueStore::_do_write( << dendl; goto out; } + dout(20)<<__func__<<" gc range is " << std::hex << dirty_start + << "~" << dirty_end - dirty_start << std::dec << dendl; } } - o->extent_map.compress_extent_map(dirty_start, dirty_end - dirty_start); o->extent_map.dirty_range(dirty_start, dirty_end - dirty_start); -- 2.47.3