#define CEPH_FEATURE_MON_STATEFUL_SUB (1ULL<<57) /* stateful mon subscription */
#define CEPH_FEATURE_MON_ROUTE_OSDMAP (1ULL<<57) /* peon sends osdmaps */
#define CEPH_FEATURE_CRUSH_TUNABLES5 (1ULL<<58) /* chooseleaf stable mode */
+// duplicated since it was introduced at the same time as CEPH_FEATURE_CRUSH_TUNABLES5
+#define CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING (1ULL<<58) /* New, v7 encoding */
#define CEPH_FEATURE_RESERVED2 (1ULL<<61) /* slow down, we are almost out... */
#define CEPH_FEATURE_RESERVED (1ULL<<62) /* DO NOT USE THIS ... last bit! */
CEPH_FEATURE_MDSENC | \
CEPH_FEATURE_OSDHASHPSPOOL | \
CEPH_FEATURE_NEW_OSDOP_ENCODING | \
+ CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \
CEPH_FEATURE_MON_SINGLE_PAXOS | \
CEPH_FEATURE_OSD_SNAPMAPPER | \
CEPH_FEATURE_MON_SCRUB | \
class MOSDOpReply : public Message {
- static const int HEAD_VERSION = 6;
+ static const int HEAD_VERSION = 7;
static const int COMPAT_VERSION = 2;
object_t oid;
version_t user_version;
epoch_t osdmap_epoch;
int32_t retry_attempt;
+ bool do_redirect;
request_redirect_t redirect;
public:
void set_redirect(const request_redirect_t& redir) { redirect = redir; }
const request_redirect_t& get_redirect() const { return redirect; }
- bool is_redirect_reply() const { return !redirect.empty(); }
+ bool is_redirect_reply() const { return do_redirect; }
void add_flags(int f) { flags |= f; }
public:
MOSDOpReply()
- : Message(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION) { }
+ : Message(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION) {
+ do_redirect = false;
+ }
MOSDOpReply(MOSDOp *req, int r, epoch_t e, int acktype, bool ignore_out_data)
: Message(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION),
oid(req->oid), pgid(req->pgid), ops(req->ops) {
osdmap_epoch = e;
user_version = 0;
retry_attempt = req->get_retry_attempt();
+ do_redirect = false;
// zero out ops payload_len and possibly out data
for (unsigned i = 0; i < ops.size(); i++) {
::encode(replay_version, payload);
::encode(user_version, payload);
- ::encode(redirect, payload);
+ if ((features & CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING) == 0) {
+ header.version = 6;
+ ::encode(redirect, payload);
+ } else {
+ do_redirect = !redirect.empty();
+ ::encode(do_redirect, payload);
+ if (do_redirect) {
+ ::encode(redirect, payload);
+ }
+ }
}
}
virtual void decode_payload() {
// Always keep here the newest version of decoding order/rule
if (header.version == HEAD_VERSION) {
- ::decode(oid, p);
- ::decode(pgid, p);
- ::decode(flags, p);
- ::decode(result, p);
- ::decode(bad_replay_version, p);
- ::decode(osdmap_epoch, p);
-
- __u32 num_ops = ops.size();
- ::decode(num_ops, p);
- ops.resize(num_ops);
- for (unsigned i = 0; i < num_ops; i++)
+ ::decode(oid, p);
+ ::decode(pgid, p);
+ ::decode(flags, p);
+ ::decode(result, p);
+ ::decode(bad_replay_version, p);
+ ::decode(osdmap_epoch, p);
+
+ __u32 num_ops = ops.size();
+ ::decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
::decode(ops[i].op, p);
- ::decode(retry_attempt, p);
+ ::decode(retry_attempt, p);
- for (unsigned i = 0; i < num_ops; ++i)
+ for (unsigned i = 0; i < num_ops; ++i)
::decode(ops[i].rval, p);
- OSDOp::split_osd_op_vector_out_data(ops, data);
+ OSDOp::split_osd_op_vector_out_data(ops, data);
- ::decode(replay_version, p);
- ::decode(user_version, p);
+ ::decode(replay_version, p);
+ ::decode(user_version, p);
+ ::decode(do_redirect, p);
+ if (do_redirect)
::decode(redirect, p);
} else if (header.version < 2) {
ceph_osd_reply_head head;
user_version = replay_version.version;
}
- if (header.version >= 6)
+ if (header.version == 6) {
::decode(redirect, p);
+ do_redirect = !redirect.empty();
+ }
+ if (header.version >= 7) {
+ ::decode(do_redirect, p);
+ if (do_redirect) {
+ ::decode(redirect, p);
+ }
+ }
}
}