std::numeric_limits<segment_id_t>::max() - 2;
constexpr segment_id_t BLOCK_REL_SEG_ID =
std::numeric_limits<segment_id_t>::max() - 3;
-
// for tests which generate fake paddrs
constexpr segment_id_t FAKE_SEG_ID =
std::numeric_limits<segment_id_t>::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<segment_id_t>::max() - 5;
+
std::ostream &segment_to_stream(std::ostream &, const segment_id_t &t);
// Offset within a segment on disk, see SegmentManager
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};
}
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);
{
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);
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:",
});
}
+ using reserve_extent_ertr = alloc_extent_ertr;
+ using reserve_extent_ret = reserve_extent_ertr::future<LBAPinRef>;
+ 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(