]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: fix data inconsistency during ool writes 59720/head
authormyoungwon oh <ohmyoungwon@gmail.com>
Wed, 11 Sep 2024 06:04:30 +0000 (06:04 +0000)
committermyoungwon oh <ohmyoungwon@gmail.com>
Fri, 27 Sep 2024 07:44:25 +0000 (07:44 +0000)
In RBM, seastore issues ool writes with allocated address.
If a transaction conflict occurs at this point, the allocated address is freed,
allowing the address to be reused.
However, data inconsistency can occur if seastore issues ool writes with
freed address before the preceding ool write has not been complete.

To fix this issue, this commit frees the allocated address after ool writes is
don in the event of the transaction conflict after ool write is issued.

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
src/crimson/os/seastore/cache.cc
src/crimson/os/seastore/extent_placement_manager.cc
src/crimson/os/seastore/transaction.h

index cf8d3c0891d7f3a143cc592914bee1ebb85fcef2..5dcb7514ee1ab708ce207b9683e67f859799daf0 100644 (file)
@@ -990,8 +990,12 @@ void Cache::mark_transaction_conflicted(
     }
     efforts.mutate_delta_bytes += delta_stat.bytes;
 
-    for (auto &i: t.pre_alloc_list) {
-      epm.mark_space_free(i->get_paddr(), i->get_length());
+    if (t.get_pending_ool()) {
+      t.get_pending_ool()->is_conflicted = true;
+    } else {
+      for (auto &i: t.pre_alloc_list) {
+       epm.mark_space_free(i->get_paddr(), i->get_length());
+      }
     }
 
     auto& ool_stats = t.get_ool_write_stats();
index 34ac199eed8dd9154a2bebd256ef37a9fc8dd122..0458fbfed748051ee16de3f7517ca0bdc62a9ca0 100644 (file)
@@ -987,7 +987,19 @@ RandomBlockOolWriter::alloc_write_ool_extents(
     return alloc_write_iertr::now();
   }
   return seastar::with_gate(write_guard, [this, &t, &extents] {
-    return do_write(t, extents);
+    seastar::lw_shared_ptr<rbm_pending_ool_t> ptr =
+      seastar::make_lw_shared<rbm_pending_ool_t>();
+    ptr->pending_extents = t.get_pre_alloc_list();
+    assert(!t.is_conflicted());
+    t.set_pending_ool(ptr);
+    return do_write(t, extents
+    ).finally([this, ptr=ptr] {
+      if (ptr->is_conflicted) {
+       for (auto &e : ptr->pending_extents) {
+         rb_cleaner->mark_space_free(e->get_paddr(), e->get_length());
+       }
+      }
+    });
   });
 }
 
index 52515937a9e594dfa41c10edb2b5a0fdca1d466e..5d8ad00ba228bd9b3644ffac1226f24b62427bf4 100644 (file)
@@ -80,6 +80,11 @@ struct rewrite_stats_t {
   }
 };
 
+struct rbm_pending_ool_t {
+  bool is_conflicted = false;
+  std::list<CachedExtentRef> pending_extents;
+};
+
 /**
  * Transaction
  *
@@ -554,6 +559,18 @@ public:
     return static_cast<T&>(*view);
   }
 
+  void set_pending_ool(seastar::lw_shared_ptr<rbm_pending_ool_t> ptr) {
+    pending_ool = ptr;
+  }
+
+  seastar::lw_shared_ptr<rbm_pending_ool_t> get_pending_ool() {
+    return pending_ool;
+  }
+
+  const auto& get_pre_alloc_list() {
+    return pre_alloc_list;
+  }
+
 private:
   friend class Cache;
   friend Ref make_test_transaction();
@@ -650,6 +667,8 @@ private:
   const src_t src;
 
   transaction_id_t trans_id = TRANS_ID_NULL;
+
+  seastar::lw_shared_ptr<rbm_pending_ool_t> pending_ool;
 };
 using TransactionRef = Transaction::Ref;