return std::invoke(f, object_data
).si_then([ctx, &object_data] {
if (object_data.must_update()) {
- ctx.onode.get_mutable_layout(ctx.t).object_data.update(object_data);
+ ctx.onode.update_object_data(ctx.t, object_data);
}
return seastar::now();
});
return std::invoke(f, object_data, d_object_data
).si_then([ctx, &object_data, &d_object_data] {
if (object_data.must_update()) {
- ctx.onode.get_mutable_layout(ctx.t).object_data.update(object_data);
+ ctx.onode.update_object_data(ctx.t, object_data);
}
if (d_object_data.must_update()) {
- ctx.d_onode->get_mutable_layout(
- ctx.t).object_data.update(d_object_data);
+ ctx.d_onode->update_object_data(ctx.t, d_object_data);
}
return seastar::now();
});
virtual bool is_alive() const = 0;
virtual const onode_layout_t &get_layout() const = 0;
- virtual onode_layout_t &get_mutable_layout(Transaction &t) = 0;
virtual ~Onode() = default;
+ virtual void update_onode_size(Transaction&, uint32_t) = 0;
+ virtual void update_omap_root(Transaction&, omap_root_t&) = 0;
+ virtual void update_xattr_root(Transaction&, omap_root_t&) = 0;
+ virtual void update_object_data(Transaction&, object_data_t&) = 0;
+ virtual void update_object_info(Transaction&, ceph::bufferlist&) = 0;
+ virtual void update_snapset(Transaction&, ceph::bufferlist&) = 0;
+ virtual void clear_object_info(Transaction&) = 0;
+ virtual void clear_snapset(Transaction&) = 0;
+
laddr_t get_metadata_hint(uint64_t block_size) const {
assert(default_metadata_offset);
assert(default_metadata_range);
).si_then([this, &trans, &hoid, FNAME](auto p)
-> get_or_create_onode_ret {
auto [cursor, created] = std::move(p);
- auto val = OnodeRef(new FLTreeOnode(
+ auto onode = new FLTreeOnode(
default_data_reservation,
default_metadata_range,
- cursor.value()));
+ cursor.value());
if (created) {
DEBUGT("created onode for entry for {}", trans, hoid);
- val->get_mutable_layout(trans) = onode_layout_t{};
+ onode->with_mutable_layout(trans, [](onode_layout_t &mlayout) {
+ mlayout = onode_layout_t{};
+ });
}
- return get_or_create_onode_iertr::make_ready_future<OnodeRef>(
- val
- );
+ return get_or_create_onode_iertr::make_ready_future<OnodeRef>(onode);
});
}
return *read_payload<onode_layout_t>();
}
- onode_layout_t &get_mutable_layout(Transaction &t) final {
+ template <typename Func>
+ void with_mutable_layout(Transaction &t, Func&& f) {
assert(status != status_t::DELETED);
auto p = prepare_mutate_payload<
onode_layout_t,
Recorder>(t);
status = status_t::MUTATED;
- return *reinterpret_cast<onode_layout_t*>(p.first.get_write());
- };
+ f(*reinterpret_cast<onode_layout_t*>(p.first.get_write()));
+ populate_recorder(t);
+ }
void populate_recorder(Transaction &t) {
assert(status == status_t::MUTATED);
status = status_t::STABLE;
}
+ void update_onode_size(Transaction &t, uint32_t size) final {
+ with_mutable_layout(t, [size](onode_layout_t &mlayout) {
+ mlayout.size = size;
+ });
+ }
+
+ void update_omap_root(Transaction &t, omap_root_t &oroot) final {
+ with_mutable_layout(t, [&oroot](onode_layout_t &mlayout) {
+ mlayout.omap_root.update(oroot);
+ });
+ }
+
+ void update_xattr_root(Transaction &t, omap_root_t &xroot) final {
+ with_mutable_layout(t, [&xroot](onode_layout_t &mlayout) {
+ mlayout.xattr_root.update(xroot);
+ });
+ }
+
+ void update_object_data(Transaction &t, object_data_t &odata) final {
+ with_mutable_layout(t, [&odata](onode_layout_t &mlayout) {
+ mlayout.object_data.update(odata);
+ });
+ }
+
+ void update_object_info(Transaction &t, ceph::bufferlist &oi_bl) final {
+ with_mutable_layout(t, [&oi_bl](onode_layout_t &mlayout) {
+ maybe_inline_memcpy(
+ &mlayout.oi[0],
+ oi_bl.c_str(),
+ oi_bl.length(),
+ onode_layout_t::MAX_OI_LENGTH);
+ mlayout.oi_size = oi_bl.length();
+ });
+ }
+
+ void clear_object_info(Transaction &t) final {
+ with_mutable_layout(t, [](onode_layout_t &mlayout) {
+ memset(&mlayout.oi[0], 0, mlayout.oi_size);
+ mlayout.oi_size = 0;
+ });
+ }
+
+ void update_snapset(Transaction &t, ceph::bufferlist &ss_bl) final {
+ with_mutable_layout(t, [&ss_bl](onode_layout_t &mlayout) {
+ maybe_inline_memcpy(
+ &mlayout.ss[0],
+ ss_bl.c_str(),
+ ss_bl.length(),
+ onode_layout_t::MAX_OI_LENGTH);
+ mlayout.ss_size = ss_bl.length();
+ });
+ }
+
+ void clear_snapset(Transaction &t) final {
+ with_mutable_layout(t, [](onode_layout_t &mlayout) {
+ memset(&mlayout.ss[0], 0, mlayout.ss_size);
+ mlayout.ss_size = 0;
+ });
+ }
+
void mark_delete() {
assert(status != status_t::DELETED);
status = status_t::DELETED;
LOG_PREFIX(SeaStore::_write);
DEBUGT("onode={} {}~{}", *ctx.transaction, *onode, offset, len);
{
- auto &object_size = onode->get_mutable_layout(*ctx.transaction).size;
- object_size = std::max<uint64_t>(
- offset + len,
- object_size);
+ const auto &object_size = onode->get_layout().size;
+ onode->update_onode_size(
+ *ctx.transaction,
+ std::max<uint64_t>(offset + len, object_size));
}
return seastar::do_with(
std::move(_bl),
//TODO: currently, we only care about object data, leaving cloning
// of xattr/omap for future work
auto &object_size = onode->get_layout().size;
- auto &d_object_size = d_onode->get_mutable_layout(*ctx.transaction).size;
- d_object_size = object_size;
+ d_onode->update_onode_size(*ctx.transaction, object_size);
return objHandler.clone(
ObjectDataHandler::context_t{
*transaction_manager,
if (offset + len >= max_object_size) {
return crimson::ct_error::input_output_error::make();
}
- auto &object_size = onode->get_mutable_layout(*ctx.transaction).size;
- object_size = std::max<uint64_t>(offset + len, object_size);
+ const auto &object_size = onode->get_layout().size;
+ onode->update_onode_size(
+ *ctx.transaction,
+ std::max<uint64_t>(offset + len, object_size));
return seastar::do_with(
ObjectDataHandler(max_object_size),
[=, this, &ctx, &onode](auto &objhandler) {
OnodeRef &onode,
const omap_root_le_t& omap_root,
Transaction& t,
- omap_root_le_t& mutable_omap_root,
std::map<std::string, ceph::bufferlist>&& kvs)
{
return seastar::do_with(
return omap_manager.omap_set_keys(root, t, std::move(keys));
}).si_then([&] {
return tm_iertr::make_ready_future<omap_root_t>(std::move(root));
- }).si_then([&mutable_omap_root](auto root) {
- if (root.must_update()) {
- mutable_omap_root.update(root);
- }
});
}
);
onode,
onode->get_layout().omap_root,
*ctx.transaction,
- onode->get_mutable_layout(*ctx.transaction).omap_root,
- std::move(aset));
+ std::move(aset)
+ ).si_then([onode, &ctx](auto root) {
+ if (root.must_update()) {
+ onode->update_omap_root(*ctx.transaction, root);
+ }
+ });
}
SeaStore::Shard::tm_ret
*ctx.transaction)
.si_then([&] {
if (omap_root.must_update()) {
- onode->get_mutable_layout(*ctx.transaction
- ).omap_root.update(omap_root);
+ onode->update_omap_root(*ctx.transaction, omap_root);
}
});
});
}
).si_then([&] {
if (omap_root.must_update()) {
- onode->get_mutable_layout(*ctx.transaction
- ).omap_root.update(omap_root);
+ onode->update_omap_root(*ctx.transaction, omap_root);
}
});
}
config
).si_then([&] {
if (omap_root.must_update()) {
- onode->get_mutable_layout(*ctx.transaction
- ).omap_root.update(omap_root);
+ onode->update_omap_root(*ctx.transaction, omap_root);
}
});
});
{
LOG_PREFIX(SeaStore::_truncate);
DEBUGT("onode={} size={}", *ctx.transaction, *onode, size);
- onode->get_mutable_layout(*ctx.transaction).size = size;
+ onode->update_onode_size(*ctx.transaction, size);
return seastar::do_with(
ObjectDataHandler(max_object_size),
[=, this, &ctx, &onode](auto &objhandler) {
DEBUGT("onode={}", *ctx.transaction, *onode);
auto fut = tm_iertr::now();
- auto& layout = onode->get_mutable_layout(*ctx.transaction);
+ auto& layout = onode->get_layout();
if (auto it = aset.find(OI_ATTR); it != aset.end()) {
auto& val = it->second;
if (likely(val.length() <= onode_layout_t::MAX_OI_LENGTH)) {
- maybe_inline_memcpy(
- &layout.oi[0],
- val.c_str(),
- val.length(),
- onode_layout_t::MAX_OI_LENGTH);
if (!layout.oi_size) {
// if oi was not in the layout, it probably exists in the omap,
// need to remove it first
fut = _xattr_rmattr(ctx, onode, OI_ATTR);
}
- layout.oi_size = val.length();
+ onode->update_object_info(*ctx.transaction, val);
aset.erase(it);
} else {
- layout.oi_size = 0;
+ onode->clear_object_info(*ctx.transaction);
}
}
if (auto it = aset.find(SS_ATTR); it != aset.end()) {
auto& val = it->second;
if (likely(val.length() <= onode_layout_t::MAX_SS_LENGTH)) {
- maybe_inline_memcpy(
- &layout.ss[0],
- val.c_str(),
- val.length(),
- onode_layout_t::MAX_SS_LENGTH);
if (!layout.ss_size) {
fut = _xattr_rmattr(ctx, onode, SS_ATTR);
}
- layout.ss_size = val.length();
-
+ onode->update_snapset(*ctx.transaction, val);
aset.erase(it);
} else {
- layout.ss_size = 0;
+ onode->clear_snapset(*ctx.transaction);
}
}
}
return fut.si_then(
- [this, onode, &ctx, &layout,
- aset=std::move(aset)]() mutable {
+ [this, onode, &ctx, aset=std::move(aset)]() mutable {
return _omap_set_kvs(
onode,
onode->get_layout().xattr_root,
*ctx.transaction,
- layout.xattr_root,
- std::move(aset));
+ std::move(aset)
+ ).si_then([onode, &ctx](auto root) {
+ if (root.must_update()) {
+ onode->update_xattr_root(*ctx.transaction, root);
+ }
+ });
});
}
{
LOG_PREFIX(SeaStore::_rmattr);
DEBUGT("onode={}", *ctx.transaction, *onode);
- auto& layout = onode->get_mutable_layout(*ctx.transaction);
+ auto& layout = onode->get_layout();
if ((name == OI_ATTR) && (layout.oi_size > 0)) {
- memset(&layout.oi[0], 0, layout.oi_size);
- layout.oi_size = 0;
+ onode->clear_object_info(*ctx.transaction);
return tm_iertr::now();
} else if ((name == SS_ATTR) && (layout.ss_size > 0)) {
- memset(&layout.ss[0], 0, layout.ss_size);
- layout.ss_size = 0;
+ onode->clear_snapset(*ctx.transaction);
return tm_iertr::now();
} else {
return _xattr_rmattr(
return omap_manager.omap_rm_key(xattr_root, *ctx.transaction, name)
.si_then([&] {
if (xattr_root.must_update()) {
- onode->get_mutable_layout(*ctx.transaction
- ).xattr_root.update(xattr_root);
+ onode->update_xattr_root(*ctx.transaction, xattr_root);
}
});
});
{
LOG_PREFIX(SeaStore::_rmattrs);
DEBUGT("onode={}", *ctx.transaction, *onode);
- auto& layout = onode->get_mutable_layout(*ctx.transaction);
- memset(&layout.oi[0], 0, layout.oi_size);
- layout.oi_size = 0;
- memset(&layout.ss[0], 0, layout.ss_size);
- layout.ss_size = 0;
+ onode->clear_object_info(*ctx.transaction);
+ onode->clear_snapset(*ctx.transaction);
return _xattr_clear(ctx, onode);
}
return omap_manager.omap_clear(xattr_root, *ctx.transaction)
.si_then([&] {
if (xattr_root.must_update()) {
- onode->get_mutable_layout(*ctx.transaction
- ).xattr_root.update(xattr_root);
+ onode->update_xattr_root(*ctx.transaction, xattr_root);
}
});
});
tm_ret _remove_collection(
internal_context_t &ctx,
const coll_t& cid);
- using omap_set_kvs_ret = tm_iertr::future<>;
+ using omap_set_kvs_ret = tm_iertr::future<omap_root_t>;
omap_set_kvs_ret _omap_set_kvs(
OnodeRef &onode,
const omap_root_le_t& omap_root,
Transaction& t,
- omap_root_le_t& mutable_omap_root,
std::map<std::string, ceph::bufferlist>&& kvs);
boost::intrusive_ptr<SeastoreCollection> _get_collection(const coll_t& cid);
uint32_t cnt_modify = 0;
void initialize(Transaction& t, Onode& value) const {
- auto& layout = value.get_mutable_layout(t);
- layout.size = size;
- layout.omap_root.update(omap_root_t(id, cnt_modify,
- value.get_metadata_hint(block_size)));
+ auto &ftvalue = static_cast<FLTreeOnode&>(value);
+ ftvalue.with_mutable_layout(t, [this, &value](auto &mlayout) {
+ mlayout.size = size;
+ mlayout.omap_root.update(omap_root_t(id, cnt_modify,
+ value.get_metadata_hint(block_size)));
+ });
validate(value);
}
const onode_layout_t &get_layout() const final {
return layout;
}
- onode_layout_t &get_mutable_layout(Transaction &t) final {
- dirty = true;
- return layout;
+ template <typename Func>
+ void with_mutable_layout(Transaction &t, Func&& f) {
+ f(layout);
}
bool is_alive() const {
return true;
bool is_dirty() const { return dirty; }
laddr_t get_hint() const final {return L_ADDR_MIN; }
~TestOnode() final = default;
+
+ void update_onode_size(Transaction &t, uint32_t size) final {
+ with_mutable_layout(t, [size](onode_layout_t &mlayout) {
+ mlayout.size = size;
+ });
+ }
+
+ void update_omap_root(Transaction &t, omap_root_t &oroot) final {
+ with_mutable_layout(t, [&oroot](onode_layout_t &mlayout) {
+ mlayout.omap_root.update(oroot);
+ });
+ }
+
+ void update_xattr_root(Transaction &t, omap_root_t &xroot) final {
+ with_mutable_layout(t, [&xroot](onode_layout_t &mlayout) {
+ mlayout.xattr_root.update(xroot);
+ });
+ }
+
+ void update_object_data(Transaction &t, object_data_t &odata) final {
+ with_mutable_layout(t, [&odata](onode_layout_t &mlayout) {
+ mlayout.object_data.update(odata);
+ });
+ }
+
+ void update_object_info(Transaction &t, ceph::bufferlist &oi_bl) final {
+ with_mutable_layout(t, [&oi_bl](onode_layout_t &mlayout) {
+ maybe_inline_memcpy(
+ &mlayout.oi[0],
+ oi_bl.c_str(),
+ oi_bl.length(),
+ onode_layout_t::MAX_OI_LENGTH);
+ mlayout.oi_size = oi_bl.length();
+ });
+ }
+
+ void clear_object_info(Transaction &t) final {
+ with_mutable_layout(t, [](onode_layout_t &mlayout) {
+ memset(&mlayout.oi[0], 0, mlayout.oi_size);
+ mlayout.oi_size = 0;
+ });
+ }
+
+ void update_snapset(Transaction &t, ceph::bufferlist &ss_bl) final {
+ with_mutable_layout(t, [&ss_bl](onode_layout_t &mlayout) {
+ maybe_inline_memcpy(
+ &mlayout.ss[0],
+ ss_bl.c_str(),
+ ss_bl.length(),
+ onode_layout_t::MAX_OI_LENGTH);
+ mlayout.ss_size = ss_bl.length();
+ });
+ }
+
+ void clear_snapset(Transaction &t) final {
+ with_mutable_layout(t, [](onode_layout_t &mlayout) {
+ memset(&mlayout.ss[0], 0, mlayout.ss_size);
+ mlayout.ss_size = 0;
+ });
+ }
+
};
struct object_data_handler_test_t: