From: Samuel Just Date: Sat, 10 Apr 2021 01:02:57 +0000 (-0700) Subject: crimson/os/seastore/transaction_manager: add zero region reservation X-Git-Tag: v17.1.0~2198^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=80f7b59942e394ca513d878cd6f945a58520a92e;p=ceph.git crimson/os/seastore/transaction_manager: add zero region reservation Add logical mappings for zero regions for use in reserving contiguous sections of laddr space. Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/seastore_types.cc b/src/crimson/os/seastore/seastore_types.cc index 1c838ef0bd6c..f5a5debbb6c0 100644 --- a/src/crimson/os/seastore/seastore_types.cc +++ b/src/crimson/os/seastore/seastore_types.cc @@ -13,6 +13,8 @@ std::ostream &segment_to_stream(std::ostream &out, const segment_id_t &t) return out << "BLOCK_REL_SEG"; else if (t == RECORD_REL_SEG_ID) return out << "RECORD_REL_SEG"; + else if (t == ZERO_SEG_ID) + return out << "ZERO_SEG"; else if (t == FAKE_SEG_ID) return out << "FAKE_SEG"; else diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index b56b51450e8d..d6c78a400a3f 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -43,11 +43,16 @@ constexpr segment_id_t RECORD_REL_SEG_ID = std::numeric_limits::max() - 2; constexpr segment_id_t BLOCK_REL_SEG_ID = std::numeric_limits::max() - 3; - // for tests which generate fake paddrs constexpr segment_id_t FAKE_SEG_ID = std::numeric_limits::max() - 4; +/* Used to denote references to notional zero filled segment, mainly + * in denoting reserved laddr ranges for unallocated object data. + */ +constexpr segment_id_t ZERO_SEG_ID = + std::numeric_limits::max() - 5; + std::ostream &segment_to_stream(std::ostream &, const segment_id_t &t); // Offset within a segment on disk, see SegmentManager @@ -103,6 +108,27 @@ struct paddr_t { return segment == BLOCK_REL_SEG_ID; } + /// Denotes special zero segment addr + bool is_zero() const { + return segment == ZERO_SEG_ID; + } + + /// Denotes special null segment addr + bool is_null() const { + return segment == NULL_SEG_ID; + } + + /** + * is_real + * + * indicates whether addr reflects a physical location, absolute + * or relative. FAKE segments also count as real so as to reflect + * the way in which unit tests use them. + */ + bool is_real() const { + return !is_zero() && !is_null(); + } + paddr_t add_offset(segment_off_t o) const { return paddr_t{segment, offset + o}; } @@ -175,6 +201,9 @@ constexpr paddr_t make_block_relative_paddr(segment_off_t off) { constexpr paddr_t make_fake_paddr(segment_off_t off) { return paddr_t{FAKE_SEG_ID, off}; } +constexpr paddr_t zero_paddr() { + return paddr_t{ZERO_SEG_ID, 0}; +} struct __attribute((packed)) paddr_le_t { ceph_le32 segment = ceph_le32(NULL_SEG_ID); diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index f9689254b916..3b7d74733a79 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -156,7 +156,7 @@ TransactionManager::ref_ret TransactionManager::dec_ref( { return lba_manager->decref_extent(t, offset ).safe_then([this, offset, &t](auto result) -> ref_ret { - if (result.refcount == 0) { + if (result.refcount == 0 && !result.addr.is_zero()) { logger().debug( "TransactionManager::dec_ref: offset {} refcount 0", offset); diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index d8c31a924d6e..1b260f4f021b 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -168,7 +168,7 @@ public: return get_pins( t, offset, length ).safe_then([this, &t, offset, length](auto pins) { - if (pins.size() != 1) { + if (pins.size() != 1 || !pins.front()->get_paddr().is_real()) { auto &logger = crimson::get_logger(ceph_subsys_filestore); logger.error( "TransactionManager::read_extent offset {} len {} got {} extents:", @@ -267,6 +267,19 @@ public: }); } + using reserve_extent_ertr = alloc_extent_ertr; + using reserve_extent_ret = reserve_extent_ertr::future; + reserve_extent_ret reserve_region( + Transaction &t, + laddr_t hint, + extent_len_t len) { + return lba_manager->alloc_extent( + t, + hint, + len, + zero_paddr()); + } + using find_hole_ertr = LBAManager::find_hole_ertr; using find_hole_ret = LBAManager::find_hole_ret; find_hole_ret find_hole(