instead of cmp_fail error code.
Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
using enametoolong = ct_error_code<static_cast<int>(std::errc::filename_too_long)>;
using eexist = ct_error_code<static_cast<int>(std::errc::file_exists)>;
using edquot = ct_error_code<int(122)>;
- using cmp_fail = ct_error_code<int(4095)>;
+ constexpr int cmp_fail_error_value = 4095;
+ using cmp_fail = ct_error_code<int(cmp_fail_error_value)>;
struct pass_further_all {
template <class ErrorT>
return do_execute_op(osd_op).handle_error_interruptible(
osd_op_errorator::all_same_way([&osd_op](auto e, auto&& e_raw)
-> OpsExecuter::osd_op_errorator::future<> {
- osd_op.rval = -e.value();
+ // All ops except for CMPEXT should have rval set to -e.value(),
+ // CMPEXT sets rval itself and shouldn't be overridden.
+ if (e.value() != ct_error::cmp_fail_error_value) {
+ osd_op.rval = -e.value();
+ }
if ((osd_op.op.flags & CEPH_OSD_OP_FLAG_FAILOK) &&
e.value() != EAGAIN && e.value() != EINPROGRESS) {
return osd_op_errorator::now();
m->ops.back().op.flags & CEPH_OSD_OP_FLAG_FAILOK) {
reply->set_result(0);
}
+ // For all ops except for CMPEXT, the correct error value is encoded
+ // in e.value(). For CMPEXT, osdop.rval has the actual error value.
+ if (e.value() == ct_error::cmp_fail_error_value) {
+ assert(!m->ops.empty());
+ for (auto &osdop : m->ops) {
+ if (osdop.rval < 0) {
+ reply->set_result(osdop.rval);
+ break;
+ }
+ }
+ }
reply->set_enoent_reply_versions(
peering_state.get_info().last_update,
peering_state.get_info().last_user_version);
char byte_from_disk = (index < read_bl.length() ? read_bl[index] : 0);
if (byte_in_op != byte_from_disk) {
logger().debug("cmp_ext: mismatch at {}", index);
+ // Unlike other ops, we set osd_op.rval here and return a different
+ // error code via ct_error::cmp_fail.
osd_op.rval = -MAX_ERRNO - index;
return crimson::ct_error::cmp_fail::make();
}