From 330f6f3ae986aaf3ef4c4a5f2d2099da2a2f5d02 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 23 Sep 2019 17:22:03 -0500 Subject: [PATCH] librados: add a RETURNVEC flag This signals that the client is soliciting and expecting return codes that are >0 and/or return buffers on update ops. This should be used with caution, since it means that compound requests that include read and write requests will *also* persist the read ops in order to be idempotent, which means that those ops' results may get truncated. Signed-off-by: Sage Weil --- src/include/rados.h | 1 + src/include/rados/librados.h | 2 ++ src/include/rados/librados.hpp | 4 +++- src/librados/librados_util.cc | 2 ++ src/osd/OSD.cc | 3 +++ src/osd/OpRequest.cc | 4 ++++ src/osd/OpRequest.h | 2 ++ src/osd/osd_types.cc | 1 + src/osd/osd_types.h | 1 + 9 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/include/rados.h b/src/include/rados.h index 8e35994daed..95ef95c1dbf 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -469,6 +469,7 @@ enum { CEPH_OSD_FLAG_FULL_TRY = 0x800000, /* try op despite full flag */ CEPH_OSD_FLAG_FULL_FORCE = 0x1000000, /* force op despite full flag */ CEPH_OSD_FLAG_IGNORE_REDIRECT = 0x2000000, /* ignore redirection */ + CEPH_OSD_FLAG_RETURNVEC = 0x4000000, /* allow overall result >= 0, and return >= 0 and buffer for each op in opvec */ }; enum { diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 5b1e6c7dccc..11d5d991d10 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -130,6 +130,8 @@ enum { LIBRADOS_OPERATION_FULL_FORCE = 128, LIBRADOS_OPERATION_IGNORE_REDIRECT = 256, LIBRADOS_OPERATION_ORDERSNAP = 512, + /* enable/allow >0 return values and payloads on write/update */ + LIBRADOS_OPERATION_RETURNVEC = 1024, }; /** @} */ diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 00c18063382..aa72e3804d4 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -270,10 +270,12 @@ inline namespace v14_2_0 { // marked full; ops will either succeed (e.g., delete) or return // EDQUOT or ENOSPC OPERATION_FULL_TRY = LIBRADOS_OPERATION_FULL_TRY, - //mainly for delete + // mainly for delete OPERATION_FULL_FORCE = LIBRADOS_OPERATION_FULL_FORCE, OPERATION_IGNORE_REDIRECT = LIBRADOS_OPERATION_IGNORE_REDIRECT, OPERATION_ORDERSNAP = LIBRADOS_OPERATION_ORDERSNAP, + // enable/allow return value and per-op return code/buffers + OPERATION_RETURNVEC = LIBRADOS_OPERATION_RETURNVEC, }; /* diff --git a/src/librados/librados_util.cc b/src/librados/librados_util.cc index 109bf9ab680..72cd96947f4 100644 --- a/src/librados/librados_util.cc +++ b/src/librados/librados_util.cc @@ -56,6 +56,8 @@ int translate_flags(int flags) op_flags |= CEPH_OSD_FLAG_IGNORE_REDIRECT; if (flags & librados::OPERATION_ORDERSNAP) op_flags |= CEPH_OSD_FLAG_ORDERSNAP; + if (flags & librados::OPERATION_RETURNVEC) + op_flags |= CEPH_OSD_FLAG_RETURNVEC; return op_flags; } diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 96aed0b706e..fcdf69f225f 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -10087,6 +10087,9 @@ int OSD::init_op_flags(OpRequestRef& op) if (m->has_flag(CEPH_OSD_FLAG_RWORDERED)) { op->set_force_rwordered(); } + if (m->has_flag(CEPH_OSD_FLAG_RETURNVEC)) { + op->set_returnvec(); + } // set bits based on op codes, called methods. for (iter = m->ops.begin(); iter != m->ops.end(); ++iter) { diff --git a/src/osd/OpRequest.cc b/src/osd/OpRequest.cc index 661cbf6d82a..f37e1d7839c 100644 --- a/src/osd/OpRequest.cc +++ b/src/osd/OpRequest.cc @@ -135,6 +135,9 @@ bool OpRequest::need_skip_handle_cache() { bool OpRequest::need_skip_promote() { return check_rmw(CEPH_OSD_RMW_FLAG_SKIP_PROMOTE); } +bool OpRequest::allows_returnvec() const { + return check_rmw(CEPH_OSD_RMW_FLAG_RETURNVEC); +} void OpRequest::set_rmw_flags(int flags) { #ifdef WITH_LTTNG @@ -156,6 +159,7 @@ void OpRequest::set_promote() { set_rmw_flags(CEPH_OSD_RMW_FLAG_FORCE_PROMOTE); void OpRequest::set_skip_handle_cache() { set_rmw_flags(CEPH_OSD_RMW_FLAG_SKIP_HANDLE_CACHE); } void OpRequest::set_skip_promote() { set_rmw_flags(CEPH_OSD_RMW_FLAG_SKIP_PROMOTE); } void OpRequest::set_force_rwordered() { set_rmw_flags(CEPH_OSD_RMW_FLAG_RWORDERED); } +void OpRequest::set_returnvec() { set_rmw_flags(CEPH_OSD_RMW_FLAG_RETURNVEC); } void OpRequest::mark_flag_point(uint8_t flag, const char *s) { #ifdef WITH_LTTNG diff --git a/src/osd/OpRequest.h b/src/osd/OpRequest.h index 4f1fa541128..565ecb8969b 100644 --- a/src/osd/OpRequest.h +++ b/src/osd/OpRequest.h @@ -39,6 +39,7 @@ struct OpRequest : public TrackedOp { bool need_promote(); bool need_skip_handle_cache(); bool need_skip_promote(); + bool allows_returnvec() const; void set_read(); void set_write(); void set_cache(); @@ -49,6 +50,7 @@ struct OpRequest : public TrackedOp { void set_skip_handle_cache(); void set_skip_promote(); void set_force_rwordered(); + void set_returnvec(); struct ClassInfo { ClassInfo(std::string&& class_name, std::string&& method_name, diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index d83991fc20a..86c98fc53b7 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -88,6 +88,7 @@ const char *ceph_osd_flag_name(unsigned flag) case CEPH_OSD_FLAG_FULL_TRY: return "full_try"; case CEPH_OSD_FLAG_FULL_FORCE: return "full_force"; case CEPH_OSD_FLAG_IGNORE_REDIRECT: return "ignore_redirect"; + case CEPH_OSD_FLAG_RETURNVEC: return "returnvec"; default: return "???"; } } diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index cc4546f441b..3e3a7cdfd31 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -365,6 +365,7 @@ enum { CEPH_OSD_RMW_FLAG_SKIP_HANDLE_CACHE = (1 << 8), CEPH_OSD_RMW_FLAG_SKIP_PROMOTE = (1 << 9), CEPH_OSD_RMW_FLAG_RWORDERED = (1 << 10), + CEPH_OSD_RMW_FLAG_RETURNVEC = (1 << 11), }; -- 2.39.5