From 3dea4f1f5c432a12da844edfbf17111fcbaa1b08 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sat, 30 Jan 2016 14:51:17 +0800 Subject: [PATCH] osd: add CEPH_OSD_OP_SCRUBLS pg op it is a new pg op which returns the encoded objects stored when scrubbing. Fixes: #13505 Signed-off-by: Kefu Chai --- src/common/scrub_types.cc | 39 +++++++++++++++++++++++++++++++++++++++ src/common/scrub_types.h | 20 ++++++++++++++++++++ src/include/rados.h | 3 ++- src/osd/ReplicatedPG.cc | 38 ++++++++++++++++++++++++++++++++++++++ src/osd/ReplicatedPG.h | 1 + src/osd/osd_types.cc | 2 ++ 6 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/common/scrub_types.cc b/src/common/scrub_types.cc index 91ac141b847a3..3342a49d2ed74 100644 --- a/src/common/scrub_types.cc +++ b/src/common/scrub_types.cc @@ -207,3 +207,42 @@ void inconsistent_snapset_wrapper::decode(bufferlist::iterator& bp) DECODE_FINISH(bp); } +void scrub_ls_arg_t::encode(bufferlist& bl) const +{ + ENCODE_START(1, 1, bl); + ::encode(interval, bl); + ::encode(get_snapsets, bl); + ::encode(start_after.name, bl); + ::encode(start_after.nspace, bl); + ::encode(start_after.snap, bl); + ::encode(max_return, bl); + ENCODE_FINISH(bl); +} + +void scrub_ls_arg_t::decode(bufferlist::iterator& bp) +{ + DECODE_START(1, bp); + ::decode(interval, bp); + ::decode(get_snapsets, bp); + ::decode(start_after.name, bp); + ::decode(start_after.nspace, bp); + ::decode(start_after.snap, bp); + ::decode(max_return, bp); + DECODE_FINISH(bp); +} + +void scrub_ls_result_t::encode(bufferlist& bl) const +{ + ENCODE_START(1, 1, bl); + ::encode(interval, bl); + ::encode(vals, bl); + ENCODE_FINISH(bl); +} + +void scrub_ls_result_t::decode(bufferlist::iterator& bp) +{ + DECODE_START(1, bp); + ::decode(interval, bp); + ::decode(vals, bp); + DECODE_FINISH(bp); +} diff --git a/src/common/scrub_types.h b/src/common/scrub_types.h index df219e523ce3e..c9f4fda90c268 100644 --- a/src/common/scrub_types.h +++ b/src/common/scrub_types.h @@ -118,4 +118,24 @@ namespace librados { } } +struct scrub_ls_arg_t { + uint32_t interval; + uint32_t get_snapsets; + librados::object_id_t start_after; + uint64_t max_return; + void encode(bufferlist& bl) const; + void decode(bufferlist::iterator& bl); +}; + +WRITE_CLASS_ENCODER(scrub_ls_arg_t); + +struct scrub_ls_result_t { + epoch_t interval; + std::vector vals; + void encode(bufferlist& bl) const; + void decode(bufferlist::iterator& bl); +}; + +WRITE_CLASS_ENCODER(scrub_ls_result_t); + #endif diff --git a/src/include/rados.h b/src/include/rados.h index dde4d9e81814a..ef068d6518b66 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -293,7 +293,8 @@ extern const char *ceph_osd_state_name(int s); f(PG_HITSET_LS, __CEPH_OSD_OP(RD, PG, 3), "pg-hitset-ls") \ f(PG_HITSET_GET, __CEPH_OSD_OP(RD, PG, 4), "pg-hitset-get") \ f(PGNLS, __CEPH_OSD_OP(RD, PG, 5), "pgnls") \ - f(PGNLS_FILTER, __CEPH_OSD_OP(RD, PG, 6), "pgnls-filter") + f(PGNLS_FILTER, __CEPH_OSD_OP(RD, PG, 6), "pgnls-filter") \ + f(SCRUBLS, __CEPH_OSD_OP(RD, PG, 7), "scrubls") enum { #define GENERATE_ENUM_ENTRY(op, opcode, str) CEPH_OSD_OP_##op = (opcode), diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 3ef2cde4ad3e8..6f5a91dac124e 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -1293,6 +1293,9 @@ void ReplicatedPG::do_pg_op(OpRequestRef op) } break; + case CEPH_OSD_OP_SCRUBLS: + result = do_scrub_ls(m, &osd_op); + break; default: result = -EINVAL; @@ -1311,6 +1314,41 @@ void ReplicatedPG::do_pg_op(OpRequestRef op) delete filter; } +int ReplicatedPG::do_scrub_ls(MOSDOp *m, OSDOp *osd_op) +{ + if (m->get_pg() != info.pgid.pgid) { + dout(10) << " scrubls pg=" << m->get_pg() << " != " << info.pgid << dendl; + return -EINVAL; // hmm? + } + auto bp = osd_op->indata.begin(); + scrub_ls_arg_t arg; + try { + arg.decode(bp); + } catch (buffer::error&) { + dout(10) << " corrupted scrub_ls_arg_t" << dendl; + return -EINVAL; + } + int r = 0; + scrub_ls_result_t result = {.interval = info.history.same_interval_since}; + if (arg.interval != 0 && arg.interval != info.history.same_interval_since) { + r = -EAGAIN; + } else if (!scrubber.store) { + r = -ENOENT; + } else if (arg.get_snapsets) { + result.vals = scrubber.store->get_snap_errors(osd->store, + get_pgid().pool(), + arg.start_after, + arg.max_return); + } else { + result.vals = scrubber.store->get_object_errors(osd->store, + get_pgid().pool(), + arg.start_after, + arg.max_return); + } + ::encode(result, osd_op->outdata); + return r; +} + void ReplicatedPG::calc_trim_to() { size_t target = cct->_conf->osd_min_pg_log_entries; diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index bf95df0c46bec..f0211168f12c3 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -1485,6 +1485,7 @@ public: void do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn); private: + int do_scrub_ls(MOSDOp *op, OSDOp *osd_op); hobject_t earliest_backfill() const; bool check_src_targ(const hobject_t& soid, const hobject_t& toid) const; diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 2d874e5fd8261..6f26284b69c5f 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -5498,6 +5498,8 @@ ostream& operator<<(ostream& out, const OSDOp& op) case CEPH_OSD_OP_PG_HITSET_GET: out << " " << utime_t(op.op.hit_set_get.stamp); break; + case CEPH_OSD_OP_SCRUBLS: + break; } } else if (ceph_osd_op_type_multi(op.op.op)) { switch (op.op.op) { -- 2.39.5