});
}
+ObjectDataHandler::clone_ret
+ObjectDataHandler::copy_on_write(
+ context_t ctx)
+{
+ return with_object_data(
+ ctx,
+ [ctx, this](auto &object_data) -> clone_iertr::future<> {
+ auto mapping = co_await ctx.tm.get_pin(
+ ctx.t, object_data.get_reserved_data_base()
+ ).handle_error_interruptible(
+ clone_iertr::pass_further{},
+ crimson::ct_error::assert_all{"unexpected enoent"}
+ );
+ object_data_t d_object_data = get_null_object_data();
+ co_await do_clone(ctx, object_data, d_object_data, mapping, false);
+ auto old_base = object_data.get_reserved_data_base();
+ auto old_len = object_data.get_reserved_data_len();
+ object_data.update_reserved(
+ d_object_data.get_reserved_data_base(),
+ d_object_data.get_reserved_data_len());
+ ctx.onode.unset_need_cow(ctx.t);
+ co_await ctx.tm.remove_mappings_in_range(
+ ctx.t, old_base, old_len, std::move(mapping), {false, true}
+ ).handle_error_interruptible(
+ clone_iertr::pass_further{},
+ crimson::ct_error::assert_all{"unexpected enoent"}
+ ).discard_result();
+ });
+}
+
ObjectDataHandler::clone_ret
ObjectDataHandler::do_clone(
context_t ctx,
ObjectDataHandler(max_object_size),
[&onode, this, &ctx](auto &objhandler)
{
- return objhandler.clear(
- ObjectDataHandler::context_t{
- *transaction_manager,
- *ctx.transaction,
- *onode,
- });
+ auto fut = ObjectDataHandler::clone_iertr::now();
+ auto objctx = ObjectDataHandler::context_t{
+ *transaction_manager,
+ *ctx.transaction,
+ *onode,
+ };
+ if (onode->need_cow()) {
+ fut = objhandler.copy_on_write(objctx);
+ }
+ return fut.si_then([&objhandler, objctx] {
+ return objhandler.clear(objctx);
+ });
});
}).si_then([this, &ctx, &onode] {
return onode_manager->erase_onode(*ctx.transaction, onode);
std::move(_bl),
ObjectDataHandler(max_object_size),
[=, this, &ctx, &onode](auto &bl, auto &objhandler) {
- return objhandler.write(
- ObjectDataHandler::context_t{
- *transaction_manager,
- *ctx.transaction,
- onode,
- },
- offset,
- bl);
+ auto fut = ObjectDataHandler::clone_iertr::now();
+ auto objctx = ObjectDataHandler::context_t{
+ *transaction_manager,
+ *ctx.transaction,
+ onode,
+ };
+ if (onode.need_cow()) {
+ fut = objhandler.copy_on_write(objctx);
+ }
+ return fut.si_then([&objhandler, objctx, offset, &bl] {
+ return objhandler.write(objctx, offset, bl);
+ });
});
}
return seastar::do_with(
ObjectDataHandler(max_object_size),
[=, this, &ctx, &onode](auto &objhandler) {
- return objhandler.zero(
- ObjectDataHandler::context_t{
- *transaction_manager,
- *ctx.transaction,
- onode,
- },
- offset,
- len);
+ auto fut = ObjectDataHandler::clone_iertr::now();
+ auto objctx = ObjectDataHandler::context_t{
+ *transaction_manager,
+ *ctx.transaction,
+ onode,
+ };
+ if (onode.need_cow()) {
+ fut = objhandler.copy_on_write(objctx);
+ }
+ return fut.si_then([&objhandler, objctx, offset, len] {
+ return objhandler.zero(objctx, offset, len);
+ });
});
}
return seastar::do_with(
ObjectDataHandler(max_object_size),
[=, this, &ctx, &onode](auto &objhandler) {
- return objhandler.truncate(
- ObjectDataHandler::context_t{
- *transaction_manager,
- *ctx.transaction,
- onode
- },
- size);
+ auto fut = ObjectDataHandler::clone_iertr::now();
+ auto objctx = ObjectDataHandler::context_t{
+ *transaction_manager,
+ *ctx.transaction,
+ onode,
+ };
+ if (onode.need_cow()) {
+ fut = objhandler.copy_on_write(objctx);
+ }
+ return fut.si_then([&objhandler, objctx, size] {
+ return objhandler.truncate(objctx, size);
+ });
});
}