]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/seastore: fix OTree read invalid extent 41741/head
authorchunmei-liu <chunmei.liu@intel.com>
Mon, 7 Jun 2021 23:48:20 +0000 (16:48 -0700)
committerchunmei-liu <chunmei.liu@intel.com>
Wed, 9 Jun 2021 22:34:16 +0000 (15:34 -0700)
Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/os/seastore/cache.h
src/test/crimson/seastore/test_transaction_manager.cc

index 0c10f2c4e86e5005b2a9417507bbc635d285b065..01b59c91c467b95f19fb2ed28a9459b82c49dcc1 100644 (file)
@@ -181,12 +181,14 @@ public:
       auto ret = TCachedExtentRef<T>(static_cast<T*>(&*iter));
       return ret->wait_io(
       ).then([ret=std::move(ret)]() mutable -> get_extent_ret<T> {
-       if (!ret->is_retired()) {
-         return get_extent_ret<T>(
-           get_extent_ertr::ready_future_marker{},
-           std::move(ret));
-       } else {
-         return crimson::ct_error::eagain::make();
+        if (ret->is_valid()) {
+          return get_extent_ret<T>(
+            get_extent_ertr::ready_future_marker{},
+            std::move(ret));
+        } else if (ret->is_retired()) {
+          ceph_abort_msg("impossible retired extent");
+        } else {
+          return crimson::ct_error::eagain::make();
        }
       });
     } else {
index 1a0d65e5e802daaf4532c1e67fc066339b7e38cc..b48edeaf5ee413385b98865177b38588c7924e1a 100644 (file)
@@ -430,6 +430,33 @@ struct transaction_manager_test_t :
     return ext;
   }
 
+  TestBlockRef try_get_extent(
+    test_transaction_t &t,
+    laddr_t addr,
+    extent_len_t len) {
+    ceph_assert(test_mappings.contains(addr, t.mapping_delta));
+    ceph_assert(test_mappings.get(addr, t.mapping_delta).desc.len == len);
+
+    using ertr = TransactionManager::read_extent_ertr;
+    using ret = ertr::future<TestBlockRef>;
+    auto ext = tm->read_extent<TestBlock>(
+      *t.t, addr, len
+    ).safe_then([](auto ext) -> ret {
+      return ertr::make_ready_future<TestBlockRef>(ext);
+    }).handle_error(
+      [](const crimson::ct_error::eagain &e) {
+       return seastar::make_ready_future<TestBlockRef>();
+      },
+      crimson::ct_error::assert_all{
+       "get_extent got invalid error"
+      }
+    ).get0();
+    if (ext) {
+      EXPECT_EQ(addr, ext->get_laddr());
+    }
+    return ext;
+  }
+
   test_block_mutator_t mutator;
   TestBlockRef mutate_extent(
     test_transaction_t &t,
@@ -897,13 +924,17 @@ TEST_F(transaction_manager_test_t, random_writes_concurrent)
       boost::make_counting_iterator(0u),
       boost::make_counting_iterator(WRITE_STREAMS),
       [&](auto) {
-       return seastar::async([&] {
-         while (writes < 300) {
-           auto t = create_transaction();
-           auto ext = get_extent(
-             t,
-             get_random_laddr(BSIZE, TOTAL),
-             BSIZE);
+        return seastar::async([&] {
+          while (writes < 300) {
+            auto t = create_transaction();
+            auto ext = try_get_extent(
+              t,
+              get_random_laddr(BSIZE, TOTAL),
+              BSIZE);
+            if (!ext){
+              failures++;
+              continue;
+            }
            auto mut = mutate_extent(t, ext);
            auto success = try_submit_transaction(std::move(t));
            writes += success;