mirror of
https://github.com/ceph/ceph
synced 2025-04-20 22:36:04 +00:00
crimson/osd: erroratorize the do_op_call() path more.
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
This commit is contained in:
parent
7a1eb3d4c5
commit
d8d0ab1a69
@ -13,7 +13,9 @@ namespace _impl {
|
|||||||
invarg,
|
invarg,
|
||||||
enodata,
|
enodata,
|
||||||
input_output_error,
|
input_output_error,
|
||||||
object_corrupted
|
object_corrupted,
|
||||||
|
permission_denied,
|
||||||
|
operation_not_supported
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,6 +592,8 @@ namespace ct_error {
|
|||||||
using invarg = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::invarg>;
|
using invarg = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::invarg>;
|
||||||
using input_output_error = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::input_output_error>;
|
using input_output_error = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::input_output_error>;
|
||||||
using object_corrupted = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::object_corrupted>;
|
using object_corrupted = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::object_corrupted>;
|
||||||
|
using permission_denied = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::permission_denied>;
|
||||||
|
using operation_not_supported = unthrowable_wrapper<_impl::ct_error, _impl::ct_error::operation_not_supported>;
|
||||||
}
|
}
|
||||||
|
|
||||||
using stateful_errc = stateful_error_t<std::errc>;
|
using stateful_errc = stateful_error_t<std::errc>;
|
||||||
|
@ -37,7 +37,7 @@ OpsExecuter::call_errorator::future<> OpsExecuter::do_op_call(OSDOp& osd_op)
|
|||||||
bp.copy(osd_op.op.cls.indata_len, indata);
|
bp.copy(osd_op.op.cls.indata_len, indata);
|
||||||
} catch (buffer::error&) {
|
} catch (buffer::error&) {
|
||||||
logger().warn("call unable to decode class + method + indata");
|
logger().warn("call unable to decode class + method + indata");
|
||||||
throw crimson::osd::invalid_argument{};
|
return crimson::ct_error::invarg::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: opening a class can actually result in dlopen(), and thus
|
// NOTE: opening a class can actually result in dlopen(), and thus
|
||||||
@ -48,23 +48,23 @@ OpsExecuter::call_errorator::future<> OpsExecuter::do_op_call(OSDOp& osd_op)
|
|||||||
if (r) {
|
if (r) {
|
||||||
logger().warn("class {} open got {}", cname, cpp_strerror(r));
|
logger().warn("class {} open got {}", cname, cpp_strerror(r));
|
||||||
if (r == -ENOENT) {
|
if (r == -ENOENT) {
|
||||||
throw crimson::osd::operation_not_supported{};
|
return crimson::ct_error::operation_not_supported::make();
|
||||||
} else if (r == -EPERM) {
|
} else if (r == -EPERM) {
|
||||||
// propagate permission errors
|
// propagate permission errors
|
||||||
throw crimson::osd::permission_denied{};
|
return crimson::ct_error::permission_denied::make();
|
||||||
}
|
}
|
||||||
throw crimson::osd::input_output_error{};
|
return crimson::ct_error::input_output_error::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassHandler::ClassMethod* method = cls->get_method(mname);
|
ClassHandler::ClassMethod* method = cls->get_method(mname);
|
||||||
if (!method) {
|
if (!method) {
|
||||||
logger().warn("call method {}.{} does not exist", cname, mname);
|
logger().warn("call method {}.{} does not exist", cname, mname);
|
||||||
throw crimson::osd::operation_not_supported{};
|
return crimson::ct_error::operation_not_supported::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto flags = method->get_flags();
|
const auto flags = method->get_flags();
|
||||||
if (!os->exists && (flags & CLS_METHOD_WR) == 0) {
|
if (!os->exists && (flags & CLS_METHOD_WR) == 0) {
|
||||||
throw crimson::osd::object_not_found{};
|
return crimson::ct_error::enoent::make();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -74,19 +74,27 @@ OpsExecuter::call_errorator::future<> OpsExecuter::do_op_call(OSDOp& osd_op)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
logger().debug("calling method {}.{}", cname, mname);
|
logger().debug("calling method {}.{}", cname, mname);
|
||||||
return seastar::async([this, &osd_op, flags, method, indata=std::move(indata)]() mutable {
|
return seastar::async(
|
||||||
|
[this, method, indata=std::move(indata)]() mutable {
|
||||||
ceph::bufferlist outdata;
|
ceph::bufferlist outdata;
|
||||||
const auto prev_rd = num_read;
|
auto cls_context = reinterpret_cast<cls_method_context_t>(this);
|
||||||
const auto prev_wr = num_write;
|
const auto ret = method->exec(cls_context, indata, outdata);
|
||||||
const auto ret = method->exec(reinterpret_cast<cls_method_context_t>(this),
|
return std::make_pair(ret, std::move(outdata));
|
||||||
indata, outdata);
|
}
|
||||||
|
).then(
|
||||||
|
[prev_rd = num_read, prev_wr = num_write, this, &osd_op, flags]
|
||||||
|
(auto outcome) {
|
||||||
|
auto& [ret, outdata] = outcome;
|
||||||
|
|
||||||
if (num_read > prev_rd && !(flags & CLS_METHOD_RD)) {
|
if (num_read > prev_rd && !(flags & CLS_METHOD_RD)) {
|
||||||
logger().error("method tried to read object but is not marked RD");
|
logger().error("method tried to read object but is not marked RD");
|
||||||
throw crimson::osd::input_output_error{};
|
return call_errorator::make_plain_exception_future<>(
|
||||||
|
crimson::ct_error::input_output_error::make());
|
||||||
}
|
}
|
||||||
if (num_write > prev_wr && !(flags & CLS_METHOD_WR)) {
|
if (num_write > prev_wr && !(flags & CLS_METHOD_WR)) {
|
||||||
logger().error("method tried to update object but is not marked WR");
|
logger().error("method tried to update object but is not marked WR");
|
||||||
throw crimson::osd::input_output_error{};
|
return call_errorator::make_plain_exception_future<>(
|
||||||
|
crimson::ct_error::input_output_error::make());
|
||||||
}
|
}
|
||||||
|
|
||||||
// for write calls we never return data expect errors. For details refer
|
// for write calls we never return data expect errors. For details refer
|
||||||
@ -96,14 +104,13 @@ OpsExecuter::call_errorator::future<> OpsExecuter::do_op_call(OSDOp& osd_op)
|
|||||||
osd_op.op.extent.length = outdata.length();
|
osd_op.op.extent.length = outdata.length();
|
||||||
osd_op.outdata.claim_append(outdata);
|
osd_op.outdata.claim_append(outdata);
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}).then([] (const int ret) {
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return call_errorator::make_plain_exception_future<>(
|
return call_errorator::make_plain_exception_future<>(
|
||||||
ceph::stateful_errint{ ret });
|
crimson::stateful_errint{ ret });
|
||||||
}
|
}
|
||||||
return seastar::now();
|
return seastar::now();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::unique_ptr<const PGLSFilter> get_pgls_filter(
|
static inline std::unique_ptr<const PGLSFilter> get_pgls_filter(
|
||||||
@ -416,7 +423,15 @@ OpsExecuter::execute_osd_op(OSDOp& osd_op)
|
|||||||
return seastar::now();
|
return seastar::now();
|
||||||
}, ceph::stateful_errint::handle([] (int err) {
|
}, ceph::stateful_errint::handle([] (int err) {
|
||||||
// TODO: implement the handler. NOP for now.
|
// TODO: implement the handler. NOP for now.
|
||||||
}));
|
}), crimson::ct_error::input_output_error::handle([] {
|
||||||
|
// TODO: implement the handler. NOP for now.
|
||||||
|
}),
|
||||||
|
crimson::errorator<crimson::ct_error::enoent,
|
||||||
|
crimson::ct_error::input_output_error,
|
||||||
|
crimson::ct_error::operation_not_supported,
|
||||||
|
crimson::ct_error::permission_denied,
|
||||||
|
crimson::ct_error::invarg>::discard_all{}
|
||||||
|
);
|
||||||
case CEPH_OSD_OP_STAT:
|
case CEPH_OSD_OP_STAT:
|
||||||
// note: stat does not require RD
|
// note: stat does not require RD
|
||||||
return do_const_op([&osd_op] (/* const */auto& backend, const auto& os) {
|
return do_const_op([&osd_op] (/* const */auto& backend, const auto& os) {
|
||||||
|
@ -65,7 +65,13 @@ class OpsExecuter {
|
|||||||
template <class Context, class MainFunc, class EffectFunc>
|
template <class Context, class MainFunc, class EffectFunc>
|
||||||
auto with_effect(Context&& ctx, MainFunc&& main_func, EffectFunc&& effect_func);
|
auto with_effect(Context&& ctx, MainFunc&& main_func, EffectFunc&& effect_func);
|
||||||
|
|
||||||
using call_errorator = ceph::errorator<ceph::stateful_errint>;
|
using call_errorator = crimson::errorator<
|
||||||
|
crimson::stateful_errint,
|
||||||
|
crimson::ct_error::enoent,
|
||||||
|
crimson::ct_error::invarg,
|
||||||
|
crimson::ct_error::permission_denied,
|
||||||
|
crimson::ct_error::operation_not_supported,
|
||||||
|
crimson::ct_error::input_output_error>;
|
||||||
call_errorator::future<> do_op_call(class OSDOp& osd_op);
|
call_errorator::future<> do_op_call(class OSDOp& osd_op);
|
||||||
|
|
||||||
template <class Func>
|
template <class Func>
|
||||||
|
Loading…
Reference in New Issue
Block a user