From: Yingxin Cheng Date: Fri, 18 Sep 2020 08:55:03 +0000 (+0800) Subject: crimson/seastore: fix potential non-repeatable-read from RootBlock X-Git-Tag: v16.1.0~1024^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F37271%2Fhead;p=ceph.git crimson/seastore: fix potential non-repeatable-read from RootBlock Load root block into the transaction when read it. Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index ba49f532fffd..e5b98c337efa 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -99,6 +99,8 @@ CachedExtentRef Cache::duplicate_for_write( auto ret = i->duplicate_for_write(); if (ret->get_type() == extent_types_t::ROOT) { + // root must be loaded before mutate + assert(t.root == i); t.root = ret->cast(); } else { ret->last_committed_crc = i->last_committed_crc; @@ -246,8 +248,10 @@ void Cache::init() { Cache::mkfs_ertr::future<> Cache::mkfs(Transaction &t) { - duplicate_for_write(t, root); - return mkfs_ertr::now(); + return get_root(t).safe_then([this, &t](auto croot) { + duplicate_for_write(t, croot); + return mkfs_ertr::now(); + }); } Cache::close_ertr::future<> Cache::close() @@ -299,7 +303,8 @@ Cache::get_root_ret Cache::get_root(Transaction &t) t.root); } else { auto ret = root; - return ret->wait_io().then([ret] { + return ret->wait_io().then([ret, &t] { + t.root = ret; return get_root_ret( get_root_ertr::ready_future_marker{}, ret); diff --git a/src/crimson/os/seastore/transaction.h b/src/crimson/os/seastore/transaction.h index 8a01c99b7dee..60d295820ebb 100644 --- a/src/crimson/os/seastore/transaction.h +++ b/src/crimson/os/seastore/transaction.h @@ -19,7 +19,7 @@ namespace crimson::os::seastore { class Transaction { friend class Cache; - RootBlockRef root; ///< ref to root if mutated by transaction + RootBlockRef root; ///< ref to root if read or written by transaction segment_off_t offset = 0; ///< relative offset of next block