]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Writer, fix find_mutable_blob
authorAdam Kupczyk <akupczyk@ibm.com>
Thu, 25 Jul 2024 07:41:46 +0000 (07:41 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Wed, 7 Aug 2024 10:55:46 +0000 (10:55 +0000)
1) Algorithm assumed that blob->blob_start() is aligned to csum size.
It is true for blobs created by write_v2, but write_v1 can generate
blob like: begin = 0x9000, size = 0x6000, csum = 0x2000.
2) Blobs with unused were selected even if those need to be expanded.
This is illegal since we cannot expand unused.

Fixed blob selection algorithm.

Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
src/os/bluestore/Writer.cc

index 1ff84ecdeab7b3f60dbd4e8bcc83709397a74add..4b9733470b13bb37f490d456898ca2224ebe3390 100644 (file)
@@ -243,9 +243,14 @@ inline BlueStore::extent_map_t::iterator BlueStore::Writer::_find_mutable_blob_l
     auto bblob = it->blob->get_blob();
     if (!bblob.is_mutable()) continue;
     if (bblob.has_csum()) {
-      uint32_t mask = mapmust_begin | mapmust_end;
+      uint32_t mask = (mapmust_begin - it->blob_start()) |
+        (mapmust_end - it->blob_start());
       if (p2phase(mask, bblob.get_csum_chunk_size()) != 0) continue;
     }
+    if (bblob.has_unused()) {
+      // very difficult to expand blob with unused (our unused logic is ekhm)
+      if (it->blob_end() <= mapmust_end) continue;
+    }
     return it;
   } while (it != map.begin());
   return map.end();
@@ -267,12 +272,16 @@ inline BlueStore::extent_map_t::iterator BlueStore::Writer::_find_mutable_blob_r
     auto bblob = it->blob->get_blob();
     if (!bblob.is_mutable()) continue;
     if (bblob.has_csum()) {
-      uint32_t mask = mapmust_begin | mapmust_end;
+      uint32_t mask = (mapmust_begin - it->blob_start()) |
+        (mapmust_end - it->blob_start());
       if (p2phase(mask, bblob.get_csum_chunk_size()) != 0) continue;
     }
+    if (bblob.has_unused()) {
+      // very difficult to expand blob with unused (our unused logic is ekhm)
+      if (it->blob_end() <= mapmust_end) continue;
+    }
     return it;
     break;
-    //++it;
   };
   return map.end();
 }