]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: prevent extent merging across shard boundaries
authorSage Weil <sage@redhat.com>
Fri, 23 Sep 2016 20:40:36 +0000 (16:40 -0400)
committerSage Weil <sage@redhat.com>
Fri, 23 Sep 2016 20:40:36 +0000 (16:40 -0400)
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 <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index 069f8a0ce100f3bc3b651915d2d1cf2dc08c957c..2d25969cc203b9f95de3e2053b4a26c839d5a837 100644 (file)
@@ -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;
 }