--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 Sage Weil <sage@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDREPSCRUBMAP_H
+#define CEPH_MOSDREPSCRUBMAP_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * pass a ScrubMap from a shard back to the primary
+ */
+
+struct MOSDRepScrubMap : public MOSDFastDispatchOp {
+
+ static const int HEAD_VERSION = 1;
+ static const int COMPAT_VERSION = 1;
+
+ spg_t pgid; // primary spg_t
+ epoch_t map_epoch = 0;
+ pg_shard_t from; // whose scrubmap this is
+ bufferlist scrub_map_bl;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDRepScrubMap()
+ : MOSDFastDispatchOp(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION) {}
+
+ MOSDRepScrubMap(spg_t pgid, epoch_t map_epoch, pg_shard_t from)
+ : MOSDFastDispatchOp(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid),
+ map_epoch(map_epoch),
+ from(from) {}
+
+private:
+ ~MOSDRepScrubMap() {}
+
+public:
+ const char *get_type_name() const { return "rep_scrubmap"; }
+ void print(ostream& out) const {
+ out << "rep_scrubmap(" << pgid << " e" << map_epoch
+ << " from shard " << from << ")";
+ }
+
+ void encode_payload(uint64_t features) {
+ ::encode(pgid, payload);
+ ::encode(map_epoch, payload);
+ ::encode(from, payload);
+ }
+ void decode_payload() {
+ bufferlist::iterator p = payload.begin();
+ ::decode(pgid, p);
+ ::decode(map_epoch, p);
+ ::decode(from, p);
+ }
+};
+
+
+#endif
#include "messages/MOSDRepOp.h"
#include "messages/MOSDSubOpReply.h"
#include "messages/MOSDRepOpReply.h"
+#include "messages/MOSDRepScrubMap.h"
+
#include "common/BackTrace.h"
#include "common/EventTrace.h"
}
}
+void PG::do_replica_scrub_map(OpRequestRef op)
+{
+ const MOSDRepScrubMap *m = static_cast<const MOSDRepScrubMap*>(op->get_req());
+ dout(7) << __func__ << " " << *m << dendl;
+ if (m->map_epoch < info.history.same_interval_since) {
+ dout(10) << __func__ << " discarding old from "
+ << m->map_epoch << " < " << info.history.same_interval_since
+ << dendl;
+ return;
+ }
+ if (!scrubber.is_chunky_scrub_active()) {
+ dout(10) << __func__ << " scrub isn't active" << dendl;
+ return;
+ }
+
+ op->mark_started();
+
+ bufferlist::iterator p = const_cast<bufferlist&>(m->get_data()).begin();
+ scrubber.received_maps[m->from].decode(p, info.pgid.pool());
+ dout(10) << "map version is "
+ << scrubber.received_maps[m->from].valid_through
+ << dendl;
+
+ --scrubber.waiting_on;
+ scrubber.waiting_on_whom.erase(m->from);
+ if (scrubber.waiting_on == 0) {
+ requeue_scrub();
+ }
+}
+
void PG::sub_op_scrub_map(OpRequestRef op)
{
+ // for legacy jewel compatibility only
const MOSDSubOp *m = static_cast<const MOSDSubOp *>(op->get_req());
assert(m->get_type() == MSG_OSD_SUBOP);
dout(7) << "sub_op_scrub_map" << dendl;
map, start, end, msg->deep, msg->seed,
handle);
- vector<OSDOp> scrub(1);
- scrub[0].op.op = CEPH_OSD_OP_SCRUB_MAP;
- hobject_t poid;
- eversion_t v;
- osd_reqid_t reqid;
- MOSDSubOp *subop = new MOSDSubOp(
- reqid,
- pg_whoami,
- spg_t(info.pgid.pgid, get_primary().shard),
- poid,
- 0,
- msg->map_epoch,
- osd->get_tid(),
- v);
- ::encode(map, subop->get_data());
- subop->ops = scrub;
-
- osd->send_message_osd_cluster(subop, msg->get_connection());
+ if (HAVE_FEATURE(acting_features, SERVER_LUMINOUS)) {
+ MOSDRepScrubMap *reply = new MOSDRepScrubMap(
+ spg_t(info.pgid.pgid, get_primary().shard),
+ msg->map_epoch,
+ pg_whoami);
+ ::encode(map, reply->get_data());
+ osd->send_message_osd_cluster(reply, msg->get_connection());
+ } else {
+ // for jewel compatibility
+ vector<OSDOp> scrub(1);
+ scrub[0].op.op = CEPH_OSD_OP_SCRUB_MAP;
+ hobject_t poid;
+ eversion_t v;
+ osd_reqid_t reqid;
+ MOSDSubOp *subop = new MOSDSubOp(
+ reqid,
+ pg_whoami,
+ spg_t(info.pgid.pgid, get_primary().shard),
+ poid,
+ 0,
+ msg->map_epoch,
+ osd->get_tid(),
+ v);
+ ::encode(map, subop->get_data());
+ subop->ops = scrub;
+ osd->send_message_osd_cluster(subop, msg->get_connection());
+ }
}
/* Scrub:
return can_discard_replica_op<MOSDECSubOpReadReply, MSG_OSD_EC_READ_REPLY>(op);
case MSG_OSD_REP_SCRUB:
return can_discard_replica_op<MOSDRepScrub, MSG_OSD_REP_SCRUB>(op);
+ case MSG_OSD_REP_SCRUBMAP:
+ return can_discard_replica_op<MOSDRepScrubMap, MSG_OSD_REP_SCRUBMAP>(op);
case MSG_OSD_PG_UPDATE_LOG_MISSING:
return can_discard_replica_op<
MOSDPGUpdateLogMissing, MSG_OSD_PG_UPDATE_LOG_MISSING>(op);
cur_epoch,
static_cast<const MOSDRepScrub*>(op->get_req())->map_epoch);
+ case MSG_OSD_REP_SCRUBMAP:
+ return !have_same_or_newer_map(
+ cur_epoch,
+ static_cast<const MOSDRepScrubMap*>(op->get_req())->map_epoch);
+
case MSG_OSD_PG_UPDATE_LOG_MISSING:
return !have_same_or_newer_map(
cur_epoch,