]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: add CEPH_OSD_OP_SCRUBLS pg op
authorKefu Chai <kchai@redhat.com>
Sat, 30 Jan 2016 06:51:17 +0000 (14:51 +0800)
committerKefu Chai <kchai@redhat.com>
Thu, 25 Feb 2016 04:41:55 +0000 (12:41 +0800)
it is a new pg op which returns the encoded objects stored when
scrubbing.

Fixes: #13505
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/common/scrub_types.cc
src/common/scrub_types.h
src/include/rados.h
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h
src/osd/osd_types.cc

index 91ac141b847a36d01d1968bfab14645f18f435fa..3342a49d2ed741c0fd36d58bbd6d76cc0899dbfc 100644 (file)
@@ -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);
+}
index df219e523ce3e88100b346889e831ff49939aeec..c9f4fda90c268a974086a96b823742944c5e45e0 100644 (file)
@@ -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<bufferlist> vals;
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+};
+
+WRITE_CLASS_ENCODER(scrub_ls_result_t);
+
 #endif
index dde4d9e81814af0fe1a4a55cf7b1c3b9e36b0645..ef068d6518b66a4699a6787f2d6a3e58153009a1 100644 (file)
@@ -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),
index 3ef2cde4ad3e870abcf2b5e17e032f7cbf524d8d..6f5a91dac124e69033bb362b1b9b575ef950a079 100644 (file)
@@ -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;
index bf95df0c46bec766baeea986f76ef99bea25ed4b..f0211168f12c33d8bbf7b3a5e2540057a39bc823 100644 (file)
@@ -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;
 
index 2d874e5fd8261e36193dd63bcbfbb9afdc821c75..6f26284b69c5f2b89ea1ff5e753ec984450ef24f 100644 (file)
@@ -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) {