--- /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_MOSDPGBACKFILLREMOVE_H
+#define CEPH_MOSDPGBACKFILLREMOVE_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * instruct non-primary to remove some objects during backfill
+ */
+
+struct MOSDPGBackfillRemove : public MOSDFastDispatchOp {
+
+ static const int HEAD_VERSION = 1;
+ static const int COMPAT_VERSION = 1;
+
+ spg_t pgid; ///< target spg_t
+ epoch_t map_epoch = 0;
+ list<pair<hobject_t,eversion_t>> ls; ///< objects to remove
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGBackfillRemove()
+ : MOSDFastDispatchOp(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION) {}
+
+ MOSDPGBackfillRemove(spg_t pgid, epoch_t map_epoch)
+ : MOSDFastDispatchOp(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION),
+ pgid(pgid),
+ map_epoch(map_epoch) {}
+
+private:
+ ~MOSDPGBackfillRemove() {}
+
+public:
+ const char *get_type_name() const { return "backfill_remove"; }
+ void print(ostream& out) const {
+ out << "backfill_remove(" << pgid << " e" << map_epoch
+ << " " << ls << ")";
+ }
+
+ void encode_payload(uint64_t features) {
+ ::encode(pgid, payload);
+ ::encode(map_epoch, payload);
+ ::encode(ls, payload);
+ }
+ void decode_payload() {
+ bufferlist::iterator p = payload.begin();
+ ::decode(pgid, p);
+ ::decode(map_epoch, p);
+ ::decode(ls, p);
+ }
+};
+
+
+
+#endif
#include "messages/MOSDPGScan.h"
#include "messages/MOSDPGBackfill.h"
#include "messages/MOSDBackoff.h"
+#include "messages/MOSDPGBackfillRemove.h"
#include "messages/MRemoveSnaps.h"
case MSG_OSD_PG_BACKFILL:
m = new MOSDPGBackfill;
break;
+ case MSG_OSD_PG_BACKFILL_REMOVE:
+ m = new MOSDPGBackfillRemove;
+ break;
case MSG_OSD_PG_PUSH:
m = new MOSDPGPush;
break;
#define MSG_OSD_PG_SCAN 94
#define MSG_OSD_PG_BACKFILL 95
+#define MSG_OSD_PG_BACKFILL_REMOVE 96
#define MSG_COMMAND 97
#define MSG_COMMAND_REPLY 98
case MSG_OSD_PG_PUSH_REPLY:
case MSG_OSD_PG_SCAN:
case MSG_OSD_PG_BACKFILL:
+ case MSG_OSD_PG_BACKFILL_REMOVE:
case MSG_OSD_EC_WRITE:
case MSG_OSD_EC_WRITE_REPLY:
case MSG_OSD_EC_READ:
#include "messages/MOSDPGTrim.h"
#include "messages/MOSDPGScan.h"
#include "messages/MOSDPGBackfill.h"
+#include "messages/MOSDPGBackfillRemove.h"
#include "messages/MBackfillReserve.h"
#include "messages/MRecoveryReserve.h"
#include "messages/MOSDPGPush.h"
return can_discard_scan(op);
case MSG_OSD_PG_BACKFILL:
return can_discard_backfill(op);
+ case MSG_OSD_PG_BACKFILL_REMOVE:
+ return can_discard_replica_op<MOSDPGBackfillRemove,
+ MSG_OSD_PG_BACKFILL_REMOVE>(op);
}
return true;
}
cur_epoch,
static_cast<const MOSDPGBackfill*>(op->get_req())->map_epoch);
+ case MSG_OSD_PG_BACKFILL_REMOVE:
+ return !have_same_or_newer_map(
+ cur_epoch,
+ static_cast<const MOSDPGBackfillRemove*>(op->get_req())->map_epoch);
+
case MSG_OSD_PG_PUSH:
return !have_same_or_newer_map(
cur_epoch,
#include "messages/MOSDPGScan.h"
#include "messages/MOSDRepScrub.h"
#include "messages/MOSDPGBackfill.h"
+#include "messages/MOSDPGBackfillRemove.h"
#include "messages/MOSDPGUpdateLogMissing.h"
#include "messages/MOSDPGUpdateLogMissingReply.h"
#include "messages/MCommandReply.h"
do_backfill(op);
break;
+ case MSG_OSD_PG_BACKFILL_REMOVE:
+ do_backfill_remove(op);
+ break;
+
case MSG_OSD_REP_SCRUB:
replica_scrub(op, handle);
break;
}
}
+void PrimaryLogPG::do_backfill_remove(OpRequestRef op)
+{
+ const MOSDPGBackfillRemove *m = static_cast<const MOSDPGBackfillRemove*>(
+ op->get_req());
+ assert(m->get_type() == MSG_OSD_PG_BACKFILL_REMOVE);
+ dout(7) << __func__ << " " << m->ls << dendl;
+
+ op->mark_started();
+
+ ObjectStore::Transaction t;
+ for (auto& p : m->ls) {
+ remove_snap_mapped_object(t, p.first);
+ }
+ int r = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+ assert(r == 0);
+}
+
PrimaryLogPG::OpContextUPtr PrimaryLogPG::trim_object(bool first, const hobject_t &coid)
{
// load clone info
add_object_context_to_pg_stat(obc, &stat);
pending_backfill_updates[*i] = stat;
}
- for (unsigned i = 0; i < to_remove.size(); ++i) {
- handle.reset_tp_timeout();
+ if (HAVE_FEATURE(get_min_upacting_features(), SERVER_LUMINOUS)) {
+ map<pg_shard_t,MOSDPGBackfillRemove*> reqs;
+ for (unsigned i = 0; i < to_remove.size(); ++i) {
+ handle.reset_tp_timeout();
+ const hobject_t& oid = to_remove[i].get<0>();
+ eversion_t v = to_remove[i].get<1>();
+ pg_shard_t peer = to_remove[i].get<2>();
+ MOSDPGBackfillRemove *m;
+ auto it = reqs.find(peer);
+ if (it != reqs.end()) {
+ m = it->second;
+ } else {
+ m = reqs[peer] = new MOSDPGBackfillRemove(
+ spg_t(info.pgid.pgid, peer.shard),
+ get_osdmap()->get_epoch());
+ }
+ m->ls.push_back(make_pair(oid, v));
- // ordered before any subsequent updates
- send_remove_op(to_remove[i].get<0>(), to_remove[i].get<1>(), to_remove[i].get<2>());
+ if (oid <= last_backfill_started)
+ pending_backfill_updates[oid]; // add empty stat!
+ }
+ for (auto p : reqs) {
+ osd->send_message_osd_cluster(p.first.osd, p.second,
+ get_osdmap()->get_epoch());
+ }
+ } else {
+ // for jewel targets
+ for (unsigned i = 0; i < to_remove.size(); ++i) {
+ handle.reset_tp_timeout();
+
+ // ordered before any subsequent updates
+ send_remove_op(to_remove[i].get<0>(), to_remove[i].get<1>(),
+ to_remove[i].get<2>());
- if (to_remove[i].get<0>() <= last_backfill_started)
- pending_backfill_updates[to_remove[i].get<0>()]; // add empty stat!
+ if (to_remove[i].get<0>() <= last_backfill_started)
+ pending_backfill_updates[to_remove[i].get<0>()]; // add empty stat!
+ }
}
PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op();
OpRequestRef op,
ThreadPool::TPHandle &handle) override;
void do_backfill(OpRequestRef op) override;
+ void do_backfill_remove(OpRequestRef op);
void handle_backoff(OpRequestRef& op);