From: Sage Weil Date: Thu, 13 Oct 2016 13:42:17 +0000 (-0400) Subject: os/bluestore: force reshard if new extent spans shard boundary X-Git-Tag: v11.1.0~655^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F11451%2Fhead;p=ceph.git os/bluestore: force reshard if new extent spans shard boundary A new write may create a new lextent that spans an existing shard boundary. If that happens, set a flag so that we force a reshard when the onode is written. Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 57c6fbbd3a42..6d0cf5b67a09 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -1485,6 +1485,7 @@ BlueStore::ExtentMap::ExtentMap(Onode *o) bool BlueStore::ExtentMap::update(Onode *o, KeyValueDB::Transaction t, bool force) { + assert(!needs_reshard); if (o->onode.extent_map_shards.empty()) { if (inline_bl.length() == 0) { unsigned n; @@ -1539,6 +1540,8 @@ bool BlueStore::ExtentMap::update(Onode *o, KeyValueDB::Transaction t, void BlueStore::ExtentMap::reshard(Onode *o, uint64_t min_alloc_size) { + needs_reshard = false; + // un-span all blobs auto p = spanning_blob_map.begin(); while (p != spanning_blob_map.end()) { @@ -2088,6 +2091,9 @@ BlueStore::Extent *BlueStore::ExtentMap::set_lextent( b->ref_map.get(offset, length); Extent *le = new Extent(logical_offset, offset, length, blob_depth, b); extent_map.insert(*le); + if (!needs_reshard && spans_shard(offset, length)) { + needs_reshard = true; + } return le; } @@ -6128,7 +6134,10 @@ void BlueStore::_txc_write_nodes(TransContext *txc, KeyValueDB::Transaction t) // finalize onodes for (auto o : txc->onodes) { // finalize extent_map shards - bool reshard = o->extent_map.update(o.get(), t, false); + bool reshard = o->extent_map.needs_reshard; + if (!reshard) { + reshard = o->extent_map.update(o.get(), t, false); + } if (reshard) { dout(20) << __func__ << " resharding extents for " << o->oid << dendl; for (auto &s : o->extent_map.shards) { @@ -7261,7 +7270,8 @@ void BlueStore::_do_write_small( b->dirty_blob().calc_csum(b_off, padded); dout(20) << __func__ << " lex old " << *ep << dendl; Extent *le = o->extent_map.set_lextent(offset, b_off + head_pad, length, - wctx->blob_depth, b, &wctx->old_extents); + wctx->blob_depth, b, + &wctx->old_extents); b->dirty_blob().mark_used(le->blob_offset, le->length); txc->statfs_delta.stored() += le->length; dout(20) << __func__ << " lex " << *le << dendl; diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 16aaaea85fe0..689b37939a38 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -579,6 +579,8 @@ public: bufferlist inline_bl; ///< cached encoded map, if unsharded; empty=>dirty + bool needs_reshard = false; ///< true if we must reshard + ExtentMap(Onode *o); ~ExtentMap() { extent_map.clear_and_dispose([&](Extent *e) { delete e; }); @@ -627,6 +629,22 @@ public: return -1; // not found } + /// check if a range spans a shard + bool spans_shard(uint32_t offset, uint32_t length) { + if (shards.empty()) { + return false; + } + int s = seek_shard(offset); + assert(s >= 0); + if (s == shards.size() - 1) { + return false; // last shard + } + if (offset + length <= shards[s+1].offset) { + return false; + } + return true; + } + /// ensure that a range of the map is loaded void fault_range(KeyValueDB *db, uint32_t offset, uint32_t length);