From: Sage Weil Date: Fri, 23 Sep 2016 20:40:36 +0000 (-0400) Subject: os/bluestore: prevent extent merging across shard boundaries X-Git-Tag: v11.0.1~85^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e86ad68753407b841f54644d120242dcea1cd0e4;p=ceph.git os/bluestore: prevent extent merging across shard boundaries We cannot have a single extent span a shard boundary. If we reach a shard boundary, stop merging extents. Note that it might be better to move the shard boundary, but it is awkward to force that to happen at this point. Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 069f8a0ce100..2d25969cc203 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -1888,6 +1888,20 @@ int BlueStore::ExtentMap::compress_extent_map(uint64_t offset, uint64_t length) if (p != extent_map.begin()) { --p; // start to the left of offset } + + // identify the *next* shard + auto pshard = shards.begin(); + while (pshard != shards.end() && + p->logical_offset >= pshard->offset) { + ++pshard; + } + uint64_t shard_end; + if (pshard != shards.end()) { + shard_end = pshard->offset; + } else { + shard_end = OBJECT_MAX_SIZE; + } + auto n = p; for (++n; n != extent_map.end(); p = n++) { if (n->logical_offset > offset + length) { @@ -1896,7 +1910,11 @@ int BlueStore::ExtentMap::compress_extent_map(uint64_t offset, uint64_t length) while (n != extent_map.end() && p->logical_offset + p->length == n->logical_offset && p->blob == n->blob && - p->blob_offset + p->length == n->blob_offset) { + p->blob_offset + p->length == n->blob_offset && + n->logical_offset < shard_end) { + dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length + << " next shard 0x" << shard_end << std::dec + << " merging " << *p << " and " << *n << dendl; p->length += n->length; rm(n++); ++removed; @@ -1904,6 +1922,14 @@ int BlueStore::ExtentMap::compress_extent_map(uint64_t offset, uint64_t length) if (n == extent_map.end()) { break; } + if (n->logical_offset >= shard_end) { + ++pshard; + if (pshard != shards.end()) { + shard_end = pshard->offset; + } else { + shard_end = OBJECT_MAX_SIZE; + } + } } return removed; }