From: Sage Weil Date: Sun, 6 Aug 2017 14:31:49 +0000 (-0400) Subject: os/bluestore: _do_remove: dirty shard individually as each blob is unshared X-Git-Tag: v12.1.3~52^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F16822%2Fhead;p=ceph.git os/bluestore: _do_remove: dirty shard individually as each blob is unshared Two problems with old code: 1- dirty_shard range is inclusive, so we might dirty the shard after b_end 2- we might unshare blobs in two shards with an unloaded shard in between, which would mean dirtying a shard that isn't loaded. Fix by ensuring the shard for each unshared blob is dirty individually. Fixes: http://tracker.ceph.com/issues/20849 Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index e28f6e757fae..48b701e8dfe8 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -10504,8 +10504,6 @@ int BlueStore::_do_remove( return 0; } - uint32_t b_start = OBJECT_MAX_SIZE; - uint32_t b_end = 0; for (auto& e : h->extent_map.extent_map) { const bluestore_blob_t& b = e.blob->get_blob(); SharedBlob *sb = e.blob->shared_blob.get(); @@ -10515,17 +10513,9 @@ int BlueStore::_do_remove( dout(20) << __func__ << " unsharing " << e << dendl; bluestore_blob_t& blob = e.blob->dirty_blob(); blob.clear_flag(bluestore_blob_t::FLAG_SHARED); - if (e.logical_offset < b_start) { - b_start = e.logical_offset; - } - if (e.logical_end() > b_end) { - b_end = e.logical_end(); - } + h->extent_map.dirty_range(e.logical_offset, 1); } } - - assert(b_end > b_start); - h->extent_map.dirty_range(b_start, b_end - b_start); txc->write_onode(h); return 0;