bpiter.copy(tmp.length(), get_bptr().c_str());
}
-CachedExtent::complete_load_ertr::future<> RootBlock::complete_load()
+RootBlock::complete_load_ertr::future<> RootBlock::complete_load()
{
auto biter = get_bptr().cbegin();
root.decode(biter);
+ if (root.lba_root.lba_root_addr.is_relative()) {
+ root.lba_root.lba_root_addr = get_paddr().add_block_relative(
+ root.lba_root.lba_root_addr);
+ }
return complete_load_ertr::now();
}
-void RootBlock::set_lba_root(btree_lba_root_t lba_root)
+void RootBlock::on_delta_write(paddr_t record_block_offset)
{
- root.lba_root = lba_root;
+ if (root.lba_root.lba_root_addr.is_relative()) {
+ root.lba_root.lba_root_addr = record_block_offset.add_record_relative(
+ root.lba_root.lba_root_addr);
+ }
+}
+
+void RootBlock::on_initial_write()
+{
+ if (root.lba_root.lba_root_addr.is_relative()) {
+ root.lba_root.lba_root_addr = get_paddr().add_block_relative(
+ root.lba_root.lba_root_addr);
+ }
+}
+
+btree_lba_root_t &RootBlock::get_lba_root()
+{
+ return root.lba_root;
}
}
* permit more than one lba_manager implementation
*/
struct btree_lba_root_t {
- depth_t lba_depth;
- depth_t segment_depth;
+ depth_t lba_depth = 0;
+ depth_t segment_depth = 0;
paddr_t lba_root_addr;
paddr_t segment_root;
}
};
+/**
+ * RootBlock
+ *
+ * Holds the physical addresses of all metadata roots.
+ * In-memory values may be
+ * - absolute: reference to block which predates the current transaction
+ * - record_relative: reference to block updated in this transaction
+ * if !is_initial_pending()
+ * - block_relative: reference to block updated in this transaction
+ * if is_initial_pending()
+ *
+ * Upon initial commit, on_initial_write checks physical references and updates
+ * based on newly discovered address (relative ones must be block_relative).
+ *
+ * complete_load also updates addresses in memory post load based on block addr.
+ *
+ * Upon delta commit, on_delta_write uses record addr to update in-memory values.
+ * apply_delta will do the same once implemented (TODO).
+ */
struct RootBlock : CachedExtent {
constexpr static segment_off_t SIZE = 4<<10;
using Ref = TCachedExtentRef<RootBlock>;
return CachedExtentRef(new RootBlock(*this));
};
+ /**
+ * prepare_write
+ *
+ * For RootBlock, serializes RootBlock::root into the bptr.
+ */
void prepare_write() final;
static constexpr extent_types_t TYPE = extent_types_t::ROOT;
}
ceph::bufferlist get_delta() final {
- ceph_assert(0 == "TODO");
return ceph::bufferlist();
}
ceph_assert(0 == "TODO");
}
+ /// Patches relative addrs in memory based on actual address
complete_load_ertr::future<> complete_load() final;
- void set_lba_root(btree_lba_root_t lba_root);
- btree_lba_root_t &get_lba_root() {
- return root.lba_root;
- }
+ /// Patches relative addrs in memory based on record commit addr
+ void on_delta_write(paddr_t record_block_offset) final;
+
+ /// Patches relative addrs in memory based on record addr
+ void on_initial_write() final;
+
+ btree_lba_root_t &get_lba_root();
};
using RootBlockRef = RootBlock::Ref;