]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/omap_manager: count key length in the overwrite gap 70180/head
authorMatan Breizman <mbreizma@redhat.com>
Sun, 26 Jul 2026 07:31:41 +0000 (07:31 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Sun, 26 Jul 2026 07:36:42 +0000 (07:36 +0000)
ow_gap_from_last_entry() returns how much the node grows when the tail entry
is overwritten. However, it compared *value* lengths only.

overwriting pg-log key (31B) is longer than a _fastinfo key (9B) -
So the growth was under-counted by 22 bytes.

Also assert in _append()/_overwrite() that the write stays within capacity() to
avoid similar issues.

Signed-off-by: Matan Breizman <mbreizma@redhat.com>
src/crimson/os/seastore/omap_manager/log/log_node.cc
src/crimson/os/seastore/omap_manager/log/log_node.h

index f7571fe75f1c0e015ae181e50f4de4af89aa72c1..e0d6f173972fcb0ba8a9fa5f29d513e123b3fd03 100644 (file)
@@ -346,8 +346,10 @@ int LogNode::ow_gap_from_last_entry(const size_t key, const size_t val) {
   if (p) {
     auto ret = p->get_latest_write_delta();
     if (ret && (*ret).key == get_ow_key()) {
-      if ((*ret).val.length() < val) {
-       gap = val - (*ret).val.length();
+      auto old_size = get_entry_size((*ret).key.size(), (*ret).val.length());
+      auto new_size = get_entry_size(key, val);
+      if (new_size > old_size) {
+        gap = new_size - old_size;
       }
     } else {
       gap = _ow_gap_from_last_entry(key, val);
index 5ce65be0c519b33f8ffb49bb1636fda4179070c9..6a499df0780be7a7ad131707fc7bf09106c1be86 100644 (file)
@@ -664,8 +664,10 @@ public:
   void _append(const std::string &key, const ceph::bufferlist &val) {
     iterator prev_iter(this, get_last_pos());
     auto last = prev_iter->get_node_key();
-    iterator next_iter(this, get_size() == 0 ? get_last_pos() :
-      get_last_pos() + get_entry_size(last.key_len, last.val_len));
+    uint32_t pos = get_size() == 0 ? get_last_pos() :
+      get_last_pos() + get_entry_size(last.key_len, last.val_len);
+    assert(pos + get_entry_size(key.size(), val.length()) <= capacity());
+    iterator next_iter(this, pos);
     next_iter.set_node_key(log_key_t(key.size(), val.length()));
     next_iter.set_node_val(key, val);
     if (get_size() >= 1) {
@@ -687,6 +689,8 @@ public:
   }
 
   void _overwrite(const std::string &key, const ceph::bufferlist &val) {
+    assert(get_last_pos() + get_entry_size(key.size(), val.length())
+      <= capacity());
     iterator iter(this, get_last_pos());
     iter.set_node_key(log_key_t(key.size(), val.length()));
     iter.set_node_val(key, val);