]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: don't set INVALID extents to CLEAN when reading 50602/head
authorXuehan Xu <xxhdx1985126@gmail.com>
Tue, 21 Mar 2023 05:52:43 +0000 (05:52 +0000)
committerXuehan Xu <xxhdx1985126@gmail.com>
Tue, 21 Mar 2023 06:01:35 +0000 (06:01 +0000)
extents

CLEAN_PENDING extents may be invalidated before read completes:

1. transaction A retired an laddr, which lead to a RetirePlaceHolder in
   Cache
2. transaction B try to read that extent, and replace A's
   RetirePlaceHolder with it;
3. transaction A commits and invalidate that extent;
4. transaction B complete reading that extent;

In this case, we shouldn't set the extent's state to CLEAN

Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
src/crimson/os/seastore/cache.h

index 575d148408f6583baf3bc53bd4809b0ed335e6ba..253836276675d406ac0ad866e48ebc66dc15b75a 100644 (file)
@@ -1321,11 +1321,15 @@ private:
     ).safe_then(
       [extent=std::move(extent)]() mutable {
         LOG_PREFIX(Cache::read_extent);
-        extent->state = CachedExtent::extent_state_t::CLEAN;
-        /* TODO: crc should be checked against LBA manager */
-        extent->last_committed_crc = extent->get_crc32c();
-
-        extent->on_clean_read();
+       if (likely(extent->state == CachedExtent::extent_state_t::CLEAN_PENDING)) {
+         extent->state = CachedExtent::extent_state_t::CLEAN;
+         /* TODO: crc should be checked against LBA manager */
+         extent->last_committed_crc = extent->get_crc32c();
+
+         extent->on_clean_read();
+       } else {
+         ceph_assert(!extent->is_valid());
+       }
         extent->complete_io();
         SUBDEBUG(seastore_cache, "read extent done -- {}", *extent);
         return get_extent_ertr::make_ready_future<TCachedExtentRef<T>>(