Skip to content

Commit

Permalink
os/bluestore: force reshard if new extent spans shard boundary
Browse files Browse the repository at this point in the history
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 <sage@redhat.com>
  • Loading branch information
liewegas committed Oct 13, 2016
1 parent 1906ac9 commit c908cae
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/os/bluestore/BlueStore.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions src/os/bluestore/BlueStore.h
Expand Up @@ -579,6 +579,8 @@ class BlueStore : public ObjectStore,

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; });
Expand Down Expand Up @@ -627,6 +629,22 @@ class BlueStore : public ObjectStore,
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);
Expand Down

0 comments on commit c908cae

Please sign in to comment.