]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cls_cas: renames, cleanups
authorSage Weil <sage@newdream.net>
Mon, 18 May 2020 15:21:12 +0000 (10:21 -0500)
committerSage Weil <sage@newdream.net>
Wed, 27 May 2020 15:44:31 +0000 (10:44 -0500)
- add write_or_get method
- fix PrimaryPG caller ot use write_or_get
- remove old method it previously called that did weird things
- cls_chunk_refcount_* -> cls_cas_chunk_*
- add _ref suffix for get and put to avoid confusion (get/put could mean
  read/write)
- some comments
- move (internal) refcount representation into separate header

Signed-off-by: Sage Weil <sage@newdream.net>
13 files changed:
qa/workunits/cls/test_cls_cas.sh [new file with mode: 0644]
src/cls/cas/cls_cas.cc
src/cls/cas/cls_cas_client.cc
src/cls/cas/cls_cas_client.h
src/cls/cas/cls_cas_internal.h [new file with mode: 0644]
src/cls/cas/cls_cas_ops.h
src/osd/PrimaryLogPG.cc
src/test/CMakeLists.txt
src/test/cls_cas/CMakeLists.txt [new file with mode: 0644]
src/test/cls_cas/test_cls_cas.cc [new file with mode: 0644]
src/test/librados/tier_cxx.cc
src/tools/ceph-dencoder/common_types.h
src/tools/ceph_dedup_tool.cc

diff --git a/qa/workunits/cls/test_cls_cas.sh b/qa/workunits/cls/test_cls_cas.sh
new file mode 100644 (file)
index 0000000..7659134
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh -e
+
+GTEST_FILTER=${CLS_CAS_GTEST_FILTER:-*}
+ceph_test_cls_cas --gtest_filter=${GTEST_FILTER}
+
+exit 0
index d5e5f0e28b856fccf520e2c36fd2abb753b21608..36bf7e8bafe58958133ad2f2a32f79ac9a5aa560 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "objclass/objclass.h"
 #include "cls_cas_ops.h"
+#include "cls_cas_internal.h"
 
 #include "include/compat.h"
 #include "osd/osd_types.h"
@@ -15,9 +16,14 @@ using ceph::decode;
 CLS_VER(1,0)
 CLS_NAME(cas)
 
-struct chunk_obj_refcount;
 
-static int chunk_read_refcount(cls_method_context_t hctx, chunk_obj_refcount *objr)
+//
+// helpers
+//
+
+static int chunk_read_refcount(
+  cls_method_context_t hctx,
+  chunk_obj_refcount *objr)
 {
   bufferlist bl;
   objr->refs.clear();
@@ -39,7 +45,9 @@ static int chunk_read_refcount(cls_method_context_t hctx, chunk_obj_refcount *ob
   return 0;
 }
 
-static int chunk_set_refcount(cls_method_context_t hctx, const struct chunk_obj_refcount& objr)
+static int chunk_set_refcount(
+  cls_method_context_t hctx,
+  const struct chunk_obj_refcount& objr)
 {
   bufferlist bl;
 
@@ -52,43 +60,111 @@ static int chunk_set_refcount(cls_method_context_t hctx, const struct chunk_obj_
   return 0;
 }
 
-static int cls_rc_chunk_refcount_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+
+//
+// methods
+//
+
+static int chunk_create_or_get_ref(cls_method_context_t hctx,
+                                  bufferlist *in, bufferlist *out)
 {
   auto in_iter = in->cbegin();
 
-  cls_chunk_refcount_get_op op;
+  cls_cas_chunk_create_or_get_ref_op op;
   try {
     decode(op, in_iter);
   } catch (ceph::buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_rc_refcount_get(): failed to decode entry\n");
+    CLS_LOG(1, "ERROR: failed to decode entry\n");
     return -EINVAL;
   }
 
   chunk_obj_refcount objr;
   int ret = chunk_read_refcount(hctx, &objr);
-  if (ret < 0)
+  if (ret == -ENOENT) {
+    // new chunk; init refs
+    CLS_LOG(10, "create oid=%s\n",
+           op.source.oid.name.c_str());
+    ret = cls_cxx_write_full(hctx, &op.data);
+    if (ret < 0) {
+      return ret;
+    }
+    objr.refs.insert(op.source);
+    ret = chunk_set_refcount(hctx, objr);
+    if (ret < 0) {
+      return ret;
+    }
+  } else if (ret < 0) {
     return ret;
+  } else {
+    // existing chunk; inc ref
+    if (op.flags & cls_cas_chunk_create_or_get_ref_op::FLAG_VERIFY) {
+      bufferlist old;
+      cls_cxx_read(hctx, 0, 0, &old);
+      if (!old.contents_equal(op.data)) {
+       return -ENOMSG;
+      }
+    }
+    CLS_LOG(10, "inc ref oid=%s\n",
+           op.source.oid.name.c_str());
 
-  CLS_LOG(10, "cls_rc_chunk_refcount_get() oid=%s\n", op.source.oid.name.c_str());
+    if (objr.refs.count(op.source)) {
+      return -EEXIST;
+    }
+    objr.refs.insert(op.source);
 
+    ret = chunk_set_refcount(hctx, objr);
+    if (ret < 0) {
+      return ret;
+    }
+  }
+  return 0;
+}
+
+static int chunk_get_ref(cls_method_context_t hctx,
+                        bufferlist *in, bufferlist *out)
+{
+  auto in_iter = in->cbegin();
+
+  cls_cas_chunk_get_ref_op op;
+  try {
+    decode(op, in_iter);
+  } catch (ceph::buffer::error& err) {
+    CLS_LOG(1, "ERROR: failed to decode entry\n");
+    return -EINVAL;
+  }
+
+  chunk_obj_refcount objr;
+  int ret = chunk_read_refcount(hctx, &objr);
+  if (ret < 0) {
+    CLS_LOG(1, "ERROR: failed to read attr\n");
+    return ret;
+  }
+
+  // existing chunk; inc ref
+  CLS_LOG(10, "oid=%s\n", op.source.oid.name.c_str());
+  
+  if (objr.refs.count(op.source)) {
+    return -EEXIST;
+  }
   objr.refs.insert(op.source);
 
   ret = chunk_set_refcount(hctx, objr);
-  if (ret < 0)
+  if (ret < 0) {
     return ret;
-
+  }
   return 0;
 }
 
-static int cls_rc_chunk_refcount_put(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+static int chunk_put_ref(cls_method_context_t hctx,
+                        bufferlist *in, bufferlist *out)
 {
   auto in_iter = in->cbegin();
 
-  cls_chunk_refcount_put_op op;
+  cls_cas_chunk_put_ref_op op;
   try {
     decode(op, in_iter);
   } catch (ceph::buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_rc_chunk_refcount_put(): failed to decode entry\n");
+    CLS_LOG(1, "ERROR: failed to decode entry\n");
     return -EINVAL;
   }
 
@@ -98,31 +174,23 @@ static int cls_rc_chunk_refcount_put(cls_method_context_t hctx, bufferlist *in,
     return ret;
 
   if (objr.refs.empty()) {// shouldn't happen!
-    CLS_LOG(0, "ERROR: cls_rc_chunk_refcount_put() was called without any references!\n");
-    return -EINVAL;
-  }
-
-  CLS_LOG(10, "cls_rc_chunk_refcount_put() oid=%s\n", op.source.oid.name.c_str());
-
-  bool found = false;
-  for (auto &p : objr.refs) {
-    if (p == op.source) {
-      found = true;
-      break;
-    }
-  }
-
-  if (!found) {
-    return 0;
+    CLS_LOG(0, "ERROR was called without any references!\n");
+    return -ENOLINK;
   }
 
   auto p = objr.refs.find(op.source);
+  if (p == objr.refs.end()) {
+    CLS_LOG(10, "oid=%s (no ref)\n", op.source.oid.name.c_str());
+    return -ENOLINK;
+  }
   objr.refs.erase(p);
 
   if (objr.refs.empty()) {
+    CLS_LOG(10, "oid=%s (last ref)\n", op.source.oid.name.c_str());
     return cls_cxx_remove(hctx);
   }
 
+  CLS_LOG(10, "oid=%s (dec)\n", op.source.oid.name.c_str());
   ret = chunk_set_refcount(hctx, objr);
   if (ret < 0)
     return ret;
@@ -130,15 +198,16 @@ static int cls_rc_chunk_refcount_put(cls_method_context_t hctx, bufferlist *in,
   return 0;
 }
 
-static int cls_rc_chunk_refcount_set(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+static int chunk_set_refs(cls_method_context_t hctx,
+                         bufferlist *in, bufferlist *out)
 {
   auto in_iter = in->cbegin();
 
-  cls_chunk_refcount_set_op op;
+  cls_cas_chunk_set_refs_op op;
   try {
     decode(op, in_iter);
   } catch (ceph::buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_chunk_refcount_set(): failed to decode entry\n");
+    CLS_LOG(1, "ERROR: cls_cas_chunk_set(): failed to decode entry\n");
     return -EINVAL;
   }
 
@@ -156,11 +225,12 @@ static int cls_rc_chunk_refcount_set(cls_method_context_t hctx, bufferlist *in,
   return 0;
 }
 
-static int cls_rc_chunk_refcount_read(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+static int chunk_read_refs(cls_method_context_t hctx,
+                          bufferlist *in, bufferlist *out)
 {
   chunk_obj_refcount objr;
 
-  cls_chunk_refcount_read_ret read_ret;
+  cls_cas_chunk_read_refs_ret read_ret;
   int ret = chunk_read_refcount(hctx, &objr);
   if (ret < 0)
     return ret;
@@ -174,48 +244,8 @@ static int cls_rc_chunk_refcount_read(cls_method_context_t hctx, bufferlist *in,
   return 0;
 }
 
-static int cls_rc_write_or_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
-{
-  auto in_iter = in->cbegin();
-  hobject_t src_obj; 
-  bufferlist indata, outdata;
-  ceph_osd_op op;
-  try {
-    decode (op, in_iter);
-    decode(src_obj, in_iter);
-    in_iter.copy(op.extent.length, indata);
-  }
-  catch (ceph::buffer::error& e) {
-    return -EINVAL;
-  }
-
-  CLS_LOG(10, " offset: %llu length: %llu \n",
-         static_cast<long long unsigned>(op.extent.offset),
-         static_cast<long long unsigned>(op.extent.length));
-  chunk_obj_refcount objr;
-  int ret = chunk_read_refcount(hctx, &objr);
-  if (ret == -ENOENT) {
-    objr.refs.insert(src_obj);
-    bufferlist set_bl;
-    encode(objr, set_bl);
-    ret = cls_cxx_chunk_write_and_set(hctx, op.extent.offset, op.extent.length, &indata, op.flags,
-                                     &set_bl, set_bl.length());
-    if (ret < 0)
-      return ret;
-
-    return 0;
-  }
-
-  objr.refs.insert(src_obj);
-  ret = chunk_set_refcount(hctx, objr);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-
-static int cls_rc_has_chunk(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+static int references_chunk(cls_method_context_t hctx,
+                           bufferlist *in, bufferlist *out)
 {
   auto in_iter = in->cbegin();
   std::string fp_oid;
@@ -226,7 +256,7 @@ static int cls_rc_has_chunk(cls_method_context_t hctx, bufferlist *in, bufferlis
   catch (ceph::buffer::error& e) {
     return -EINVAL;
   }
-  CLS_LOG(10, " fp_oid: %s \n", fp_oid.c_str());
+  CLS_LOG(10, "fp_oid: %s \n", fp_oid.c_str());
 
   bool ret = cls_has_chunk(hctx, fp_oid);
   if (ret) {
@@ -240,28 +270,37 @@ CLS_INIT(cas)
   CLS_LOG(1, "Loaded cas class!");
 
   cls_handle_t h_class;
-  cls_method_handle_t h_cas_write_or_get;
-  cls_method_handle_t h_chunk_refcount_get;
-  cls_method_handle_t h_chunk_refcount_put;
-  cls_method_handle_t h_chunk_refcount_set;
-  cls_method_handle_t h_chunk_refcount_read;
-  cls_method_handle_t h_chunk_has_chunk;
+  cls_method_handle_t h_chunk_create_or_get_ref;
+  cls_method_handle_t h_chunk_get_ref;
+  cls_method_handle_t h_chunk_put_ref;
+  cls_method_handle_t h_chunk_set_refs;
+  cls_method_handle_t h_chunk_read_refs;
+  cls_method_handle_t h_references_chunk;
 
   cls_register("cas", &h_class);
 
-  /* chunk refcount */
-  cls_register_cxx_method(h_class, "chunk_get", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_chunk_refcount_get, 
-                         &h_chunk_refcount_get);
-  cls_register_cxx_method(h_class, "chunk_put", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_chunk_refcount_put, 
-                         &h_chunk_refcount_put);
-  cls_register_cxx_method(h_class, "chunk_set", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_chunk_refcount_set, 
-                         &h_chunk_refcount_set);
-  cls_register_cxx_method(h_class, "chunk_read", CLS_METHOD_RD, cls_rc_chunk_refcount_read, 
-                         &h_chunk_refcount_read);
-  cls_register_cxx_method(h_class, "cas_write_or_get", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_write_or_get, 
-                         &h_cas_write_or_get);
-  cls_register_cxx_method(h_class, "has_chunk", CLS_METHOD_RD, cls_rc_has_chunk, 
-             &h_chunk_has_chunk);
+  cls_register_cxx_method(h_class, "chunk_create_or_get_ref",
+                         CLS_METHOD_RD | CLS_METHOD_WR,
+                         chunk_create_or_get_ref,
+                         &h_chunk_create_or_get_ref);
+  cls_register_cxx_method(h_class, "chunk_get_ref",
+                         CLS_METHOD_RD | CLS_METHOD_WR,
+                         chunk_get_ref,
+                         &h_chunk_get_ref);
+  cls_register_cxx_method(h_class, "chunk_put_ref",
+                         CLS_METHOD_RD | CLS_METHOD_WR,
+                         chunk_put_ref,
+                         &h_chunk_put_ref);
+  cls_register_cxx_method(h_class, "chunk_set_refs",
+                         CLS_METHOD_RD | CLS_METHOD_WR,
+                         chunk_set_refs,
+                         &h_chunk_set_refs);
+  cls_register_cxx_method(h_class, "chunk_read_refs", CLS_METHOD_RD,
+                         chunk_read_refs,
+                         &h_chunk_read_refs);
+  cls_register_cxx_method(h_class, "references_chunk", CLS_METHOD_RD,
+                         references_chunk,
+                         &h_references_chunk);
 
   return;
 }
index 8ccc445aff68b67f8300a8a10d65ca61e5f70522..7492f62a39a8f89691025c8bfd54db6c0de5ee05 100644 (file)
@@ -14,41 +14,67 @@ using ceph::bufferlist;
 using ceph::decode;
 using ceph::encode;
 
-void cls_chunk_refcount_get(librados::ObjectWriteOperation& op, const hobject_t& soid)
+void cls_cas_chunk_create_or_get_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid,
+  const bufferlist& data,
+  bool verify)
 {
   bufferlist in;
-  cls_chunk_refcount_get_op call;
+  cls_cas_chunk_create_or_get_ref_op call;
+  call.source = soid;
+  if (verify) {
+    call.flags |= cls_cas_chunk_create_or_get_ref_op::FLAG_VERIFY;
+  }
+  call.data = data;
+  encode(call, in);
+  op.exec("cas", "chunk_create_or_get_ref", in);
+}
+
+void cls_cas_chunk_get_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid)
+{
+  bufferlist in;
+  cls_cas_chunk_get_ref_op call;
   call.source = soid;
   encode(call, in);
-  op.exec("cas", "chunk_get", in);
+  op.exec("cas", "chunk_get_ref", in);
 }
 
-void cls_chunk_refcount_put(librados::ObjectWriteOperation& op, const hobject_t& soid)
+void cls_cas_chunk_put_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid)
 {
   bufferlist in;
-  cls_chunk_refcount_put_op call;
+  cls_cas_chunk_put_ref_op call;
   call.source = soid;
   encode(call, in);
-  op.exec("cas", "chunk_put", in);
+  op.exec("cas", "chunk_put_ref", in);
 }
 
-void cls_chunk_refcount_set(librados::ObjectWriteOperation& op, set<hobject_t>& refs)
+void cls_cas_chunk_set_refs(
+  librados::ObjectWriteOperation& op,
+  set<hobject_t>& refs)
 {
   bufferlist in;
-  cls_chunk_refcount_set_op call;
+  cls_cas_chunk_set_refs_op call;
   call.refs = refs;
   encode(call, in);
-  op.exec("cas", "chunk_set", in);
+  op.exec("cas", "chunk_set_refs", in);
 }
 
-int cls_chunk_refcount_read(librados::IoCtx& io_ctx, string& oid, set<hobject_t> *refs)
+int cls_cas_chunk_read_refs(
+  librados::IoCtx& io_ctx,
+  string& oid,
+  set<hobject_t> *refs)
 {
   bufferlist in, out;
-  int r = io_ctx.exec(oid, "cas", "chunk_read", in, out);
+  int r = io_ctx.exec(oid, "cas", "chunk_read_refs", in, out);
   if (r < 0)
     return r;
 
-  cls_chunk_refcount_read_ret ret;
+  cls_cas_chunk_read_refs_ret ret;
   try {
     auto iter = out.cbegin();
     decode(ret, iter);
@@ -61,10 +87,13 @@ int cls_chunk_refcount_read(librados::IoCtx& io_ctx, string& oid, set<hobject_t>
   return r;
 }
 
-int cls_chunk_has_chunk(librados::IoCtx& io_ctx, string& oid, string& fp_oid)
+int cls_cas_references_chunk(
+  librados::IoCtx& io_ctx,
+  const string& oid,
+  const string& chunk_oid)
 {
   bufferlist in, out;
-  encode(fp_oid, in);
-  int r = io_ctx.exec(oid, "cas", "has_chunk", in, out);
+  encode(chunk_oid, in);
+  int r = io_ctx.exec(oid, "cas", "references_chunk", in, out);
   return r;
 }
index af64f342c015dfdf7eecd509f5f52aa696ebbd6f..1017edfb0d2abac60727cf840f01db1bfd94bb26 100644 (file)
@@ -8,9 +8,47 @@
 #include "include/rados/librados_fwd.hpp"
 #include "common/hobject.h"
 
-void cls_chunk_refcount_get(librados::ObjectWriteOperation& op,const hobject_t& soid);
-void cls_chunk_refcount_put(librados::ObjectWriteOperation& op, const hobject_t& soid);
-void cls_chunk_refcount_set(librados::ObjectWriteOperation& op, std::set<hobject_t>& refs);
-int cls_chunk_refcount_read(librados::IoCtx& io_ctx, std::string& oid, std::set<hobject_t> *refs);
-int cls_chunk_has_chunk(librados::IoCtx& io_ctx, std::string& oid, std::string& fp_oid);
+//
+// basic methods
+//
+
+/// create a chunk, or get additional reference if it already exists
+void cls_cas_chunk_create_or_get_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid,
+  const bufferlist& data,
+  bool verify=false);
+
+/// get ref on existing chunk
+void cls_cas_chunk_get_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid);
+
+/// drop reference on existing chunk
+void cls_cas_chunk_put_ref(
+  librados::ObjectWriteOperation& op,
+  const hobject_t& soid);
+
+
+//
+// advanced (used for scrub, repair, etc.)
+//
+
+/// read list of all chunk references
+int cls_cas_chunk_read_refs(
+  librados::IoCtx& io_ctx,
+  std::string& oid,
+  std::set<hobject_t> *refs);
+
+/// force update on chunk references
+void cls_cas_chunk_set_refs(
+  librados::ObjectWriteOperation& op,
+  std::set<hobject_t>& refs);
+
+/// check if a tiered rados object links to a chunk
+int cls_cas_references_chunk(
+  librados::IoCtx& io_ctx,
+  const std::string& oid,
+  const std::string& chunk_oid);
+
 #endif
diff --git a/src/cls/cas/cls_cas_internal.h b/src/cls/cas/cls_cas_internal.h
new file mode 100644 (file)
index 0000000..3bcb856
--- /dev/null
@@ -0,0 +1,38 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "common/Formatter.h"
+
+#define CHUNK_REFCOUNT_ATTR "chunk_refcount"
+
+struct chunk_obj_refcount {
+  std::set<hobject_t> refs;
+
+  chunk_obj_refcount() {}
+
+  void encode(ceph::buffer::list& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(refs, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(ceph::buffer::list::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(refs, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    f->open_array_section("refs");
+    for (auto& i : refs) {
+      f->dump_object("ref", i);
+    }
+    f->close_section();
+  }
+  static void generate_test_instances(std::list<chunk_obj_refcount*>& ls) {
+    ls.push_back(new chunk_obj_refcount());
+  }
+};
+WRITE_CLASS_ENCODER(chunk_obj_refcount)
index cfd9a77301af32b980978acb0a187b4ec5253a45..4d3ec147c744c0d21ff408a40cb0b08a7990489d 100644 (file)
@@ -6,34 +6,50 @@
 
 #include "include/types.h"
 #include "common/hobject.h"
+#include "common/Formatter.h"
 
-#define CHUNK_REFCOUNT_ATTR "chunk_refcount"
+struct cls_cas_chunk_create_or_get_ref_op {
+  enum {
+    FLAG_VERIFY = 1,  // verify content bit-for-bit if chunk already exists
+  };
 
-struct cls_chunk_refcount_get_op {
   hobject_t source;
+  uint64_t flags = 0;
+  bufferlist data;
 
-  cls_chunk_refcount_get_op() {}
+  cls_cas_chunk_create_or_get_ref_op() {}
 
   void encode(ceph::buffer::list& bl) const {
     ENCODE_START(1, 1, bl);
     encode(source, bl);
+    encode(flags, bl);
+    encode(data, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(ceph::buffer::list::const_iterator& bl) {
     DECODE_START(1, bl);
     decode(source, bl);
+    decode(flags, bl);
+    decode(data, bl);
     DECODE_FINISH(bl);
   }
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(std::list<cls_chunk_refcount_get_op*>& ls);
+  void dump(ceph::Formatter *f) const {
+    f->dump_object("source", source);
+    f->dump_unsigned("flags", flags);
+    f->dump_unsigned("data_len", data.length());
+  }
+  static void generate_test_instances(std::list<cls_cas_chunk_create_or_get_ref_op*>& ls) {
+    ls.push_back(new cls_cas_chunk_create_or_get_ref_op());
+  }
 };
-WRITE_CLASS_ENCODER(cls_chunk_refcount_get_op)
+WRITE_CLASS_ENCODER(cls_cas_chunk_create_or_get_ref_op)
+
 
-struct cls_chunk_refcount_put_op {
+struct cls_cas_chunk_get_ref_op {
   hobject_t source;
 
-  cls_chunk_refcount_put_op() {}
+  cls_cas_chunk_get_ref_op() {}
 
   void encode(ceph::buffer::list& bl) const {
     ENCODE_START(1, 1, bl);
@@ -46,38 +62,47 @@ struct cls_chunk_refcount_put_op {
     decode(source, bl);
     DECODE_FINISH(bl);
   }
-
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(std::list<cls_chunk_refcount_put_op*>& ls);
+  void dump(ceph::Formatter *f) const {
+    f->dump_object("source", source);
+  }
+  static void generate_test_instances(std::list<cls_cas_chunk_get_ref_op*>& ls) {
+    ls.push_back(new cls_cas_chunk_get_ref_op());
+  }
 };
-WRITE_CLASS_ENCODER(cls_chunk_refcount_put_op)
+WRITE_CLASS_ENCODER(cls_cas_chunk_get_ref_op)
 
-struct cls_chunk_refcount_set_op {
-  std::set<hobject_t> refs;
 
-  cls_chunk_refcount_set_op() {}
+struct cls_cas_chunk_put_ref_op {
+  hobject_t source;
+
+  cls_cas_chunk_put_ref_op() {}
 
   void encode(ceph::buffer::list& bl) const {
     ENCODE_START(1, 1, bl);
-    encode(refs, bl);
+    encode(source, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(ceph::buffer::list::const_iterator& bl) {
     DECODE_START(1, bl);
-    decode(refs, bl);
+    decode(source, bl);
     DECODE_FINISH(bl);
   }
 
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(std::list<cls_chunk_refcount_set_op*>& ls);
+  void dump(ceph::Formatter *f) const {
+    f->dump_object("source", source);
+  }
+  static void generate_test_instances(std::list<cls_cas_chunk_put_ref_op*>& ls) {
+    ls.push_back(new cls_cas_chunk_put_ref_op());
+  }
 };
-WRITE_CLASS_ENCODER(cls_chunk_refcount_set_op)
+WRITE_CLASS_ENCODER(cls_cas_chunk_put_ref_op)
+
 
-struct cls_chunk_refcount_read_ret {
+struct cls_cas_chunk_set_refs_op {
   std::set<hobject_t> refs;
 
-  cls_chunk_refcount_read_ret() {}
+  cls_cas_chunk_set_refs_op() {}
 
   void encode(ceph::buffer::list& bl) const {
     ENCODE_START(1, 1, bl);
@@ -91,15 +116,24 @@ struct cls_chunk_refcount_read_ret {
     DECODE_FINISH(bl);
   }
 
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(std::list<cls_chunk_refcount_read_ret*>& ls);
+  void dump(ceph::Formatter *f) const {
+    f->open_array_section("refs");
+    for (auto& i : refs) {
+      f->dump_object("ref", i);
+    }
+    f->close_section();
+  }
+  static void generate_test_instances(std::list<cls_cas_chunk_set_refs_op*>& ls) {
+    ls.push_back(new cls_cas_chunk_set_refs_op());
+  }
 };
-WRITE_CLASS_ENCODER(cls_chunk_refcount_read_ret)
+WRITE_CLASS_ENCODER(cls_cas_chunk_set_refs_op)
+
 
-struct chunk_obj_refcount {
+struct cls_cas_chunk_read_refs_ret {
   std::set<hobject_t> refs;
 
-  chunk_obj_refcount() {}
+  cls_cas_chunk_read_refs_ret() {}
 
   void encode(ceph::buffer::list& bl) const {
     ENCODE_START(1, 1, bl);
@@ -112,7 +146,18 @@ struct chunk_obj_refcount {
     decode(refs, bl);
     DECODE_FINISH(bl);
   }
+
+  void dump(ceph::Formatter *f) const {
+    f->open_array_section("refs");
+    for (auto& i : refs) {
+      f->dump_object("ref", i);
+    }
+    f->close_section();
+  }
+  static void generate_test_instances(std::list<cls_cas_chunk_read_refs_ret*>& ls) {
+    ls.push_back(new cls_cas_chunk_read_refs_ret());
+  }
 };
-WRITE_CLASS_ENCODER(chunk_obj_refcount)
+WRITE_CLASS_ENCODER(cls_cas_chunk_read_refs_ret)
 
 #endif
index 23197dd8eed88a20b7439c371304bc8d4f187a4a..70c97c4be561b2eb78d8ce1eb7ffa4e39d9b3876 100644 (file)
@@ -25,6 +25,7 @@
 #include "Session.h"
 #include "objclass/objclass.h"
 
+#include "cls/cas/cls_cas_ops.h"
 #include "common/ceph_crypto.h"
 #include "common/errno.h"
 #include "common/scrub_types.h"
@@ -2589,10 +2590,10 @@ int PrimaryLogPG::do_manifest_flush(OpRequestRef op, ObjectContextRef obc, Flush
       if (fp_oid != tgt_soid.oid) {
        // decrement old chunk's reference count
        ObjectOperation dec_op;
-       cls_chunk_refcount_put_op put_call;
+       cls_cas_chunk_put_ref_op put_call;
        put_call.source = soid;
        ::encode(put_call, in);
-       dec_op.call("cas", "chunk_put", in);
+       dec_op.call("cas", "chunk_put_ref", in);
        // we don't care dec_op's completion. scrub for dedup will fix this.
        tid = osd->objecter->mutate(
          tgt_soid.oid, oloc, dec_op, snapc,
@@ -2602,14 +2603,14 @@ int PrimaryLogPG::do_manifest_flush(OpRequestRef op, ObjectContextRef obc, Flush
       }
       tgt_soid.oid = fp_oid;
       iter->second.oid = tgt_soid;
-      // add data op
-      ceph_osd_op osd_op;
-      osd_op.extent.offset = 0;
-      osd_op.extent.length = chunk_data.length();
-      encode(osd_op, in);
-      encode(soid, in);
-      in.append(chunk_data);
-      obj_op.call("cas", "cas_write_or_get", in);
+      {
+       bufferlist t;
+       cls_cas_chunk_create_or_get_ref_op get_call;
+       get_call.source = soid;
+       get_call.data = chunk_data;
+       ::encode(get_call, t);
+       obj_op.call("cas", "chunk_create_or_get_ref", t);
+      }
     } else {
       obj_op.add_data(CEPH_OSD_OP_WRITE, tgt_offset, tgt_length, chunk_data);
     }
@@ -3467,15 +3468,15 @@ void PrimaryLogPG::refcount_manifest(ObjectContextRef obc, object_locator_t oloc
   ObjectOperation obj_op;
   bufferlist in;
   if (get) {             
-    cls_chunk_refcount_get_op call;
+    cls_cas_chunk_get_ref_op call;
     call.source = obc->obs.oi.soid;
     ::encode(call, in);                             
-    obj_op.call("cas", "chunk_get", in);         
+    obj_op.call("cas", "chunk_get_ref", in);
   } else {                    
-    cls_chunk_refcount_put_op call;                
+    cls_cas_chunk_put_ref_op call;
     call.source = obc->obs.oi.soid;
     ::encode(call, in);          
-    obj_op.call("cas", "chunk_put", in);         
+    obj_op.call("cas", "chunk_put_ref", in);
   }                                                     
   
   Context *c = nullptr;
index 25a2f2436c41da670422f1cab61615a19b83d61b..3bef8548b4f90bda5f4603e06b7325fd5d3c81c6 100644 (file)
@@ -9,6 +9,7 @@ target_include_directories(unit-main PRIVATE
 
 add_subdirectory(cls_hello)
 add_subdirectory(cls_lock)
+add_subdirectory(cls_cas)
 add_subdirectory(cls_log)
 add_subdirectory(cls_numops)
 add_subdirectory(cls_sdk)
diff --git a/src/test/cls_cas/CMakeLists.txt b/src/test/cls_cas/CMakeLists.txt
new file mode 100644 (file)
index 0000000..83426bc
--- /dev/null
@@ -0,0 +1,16 @@
+add_executable(ceph_test_cls_cas
+  test_cls_cas.cc)
+target_link_libraries(ceph_test_cls_cas
+  librados
+  cls_cas_client
+  global
+  radostest-cxx
+  ${UNITTEST_LIBS}
+  ${BLKID_LIBRARIES}
+  ${CMAKE_DL_LIBS}
+  ${CRYPTO_LIBS}
+  ${EXTRALIBS}
+  )
+install(TARGETS
+  ceph_test_cls_cas
+  DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/src/test/cls_cas/test_cls_cas.cc b/src/test/cls_cas/test_cls_cas.cc
new file mode 100644 (file)
index 0000000..90aa207
--- /dev/null
@@ -0,0 +1,285 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "include/types.h"
+#include "cls/cas/cls_cas_client.h"
+#include "cls/cas/cls_cas_internal.h"
+
+#include "include/utime.h"
+#include "common/Clock.h"
+#include "global/global_context.h"
+
+#include "gtest/gtest.h"
+#include "test/librados/test_cxx.h"
+
+#include <errno.h>
+#include <string>
+#include <vector>
+
+
+/// creates a temporary pool and initializes an IoCtx for each test
+class cls_cas : public ::testing::Test {
+  librados::Rados rados;
+  std::string pool_name;
+ protected:
+  librados::IoCtx ioctx;
+
+  void SetUp() {
+    pool_name = get_temp_pool_name();
+    /* create pool */
+    ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
+    ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+  }
+  void TearDown() {
+    /* remove pool */
+    ioctx.close();
+    ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
+  }
+};
+
+static librados::ObjectWriteOperation *new_op() {
+  return new librados::ObjectWriteOperation();
+}
+
+static librados::ObjectReadOperation *new_rop() {
+  return new librados::ObjectReadOperation();
+}
+
+TEST_F(cls_cas, get_put)
+{
+  bufferlist bl;
+  bl.append("my data");
+  string oid = "mychunk";
+  hobject_t ref1, ref2, ref3;
+  ref1.oid.name = "foo1";
+  ref2.oid.name = "foo2";
+  ref3.oid.name = "foo3";
+
+  // initially the object does not exist
+  bufferlist t;
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  // write
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+  
+  // get x3
+  {
+    auto op = new_op();
+    cls_cas_chunk_get_ref(*op, ref2);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // get again
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref3, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // 3x puts to remove
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref3);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref2);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  
+  // get
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // put
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+}
+
+TEST_F(cls_cas, wrong_put)
+{
+  bufferlist bl;
+  bl.append("my data");
+  string oid = "mychunk";
+  hobject_t ref1, ref2;
+  ref1.oid.name = "foo1";
+  ref2.oid.name = "foo2";
+
+  // initially the object does not exist
+  bufferlist t;
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  // write
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // put wrong thing
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref2);
+    ASSERT_EQ(-ENOLINK, ioctx.operate(oid, op));
+  }
+
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+}
+
+TEST_F(cls_cas, dup_get)
+{
+  bufferlist bl;
+  bl.append("my data");
+  string oid = "mychunk";
+  hobject_t ref1;
+  ref1.oid.name = "foo1";
+
+  // initially the object does not exist
+  bufferlist t;
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  // write
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // dup create_or_get_ref, get_ref
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(-EEXIST, ioctx.operate(oid, op));
+  }
+  {
+    auto op = new_op();
+    cls_cas_chunk_get_ref(*op, ref1);
+    ASSERT_EQ(-EEXIST, ioctx.operate(oid, op));
+  }
+
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+}
+
+TEST_F(cls_cas, dup_put)
+{
+  bufferlist bl;
+  bl.append("my data");
+  string oid = "mychunk";
+  hobject_t ref1;
+  ref1.oid.name = "foo1";
+
+  // initially the object does not exist
+  bufferlist t;
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  // write
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
+  }
+}
+
+
+TEST_F(cls_cas, get_wrong_data)
+{
+  bufferlist bl, bl2;
+  bl.append("my data");
+  bl2.append("my different data");
+  string oid = "mychunk";
+  hobject_t ref1, ref2;
+  ref1.oid.name = "foo1";
+  ref2.oid.name = "foo2";
+
+  // initially the object does not exist
+  bufferlist t;
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+
+  // get
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref1, bl);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // get w/ different data
+  // with verify
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref2, bl2, true);
+    ASSERT_EQ(-ENOMSG, ioctx.operate(oid, op));
+  }
+  // without verify
+  {
+    auto op = new_op();
+    cls_cas_chunk_create_or_get_ref(*op, ref2, bl2, false);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+
+  // put
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref1);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(bl.length(), ioctx.read(oid, t, 0, 0));
+  {
+    auto op = new_op();
+    cls_cas_chunk_put_ref(*op, ref2);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+  }
+  ASSERT_EQ(-ENOENT, ioctx.read(oid, t, 0, 0));
+}
index 42c03c278e92ea875285c5059e56da66dcaa888f..e5df5b70d77ceb893b28d0037a2f3b3399731797 100644 (file)
@@ -3214,8 +3214,8 @@ TEST_F(LibRadosTwoPoolsPP, ManifestRefRead) {
   // redirect's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar", "cas", "chunk_read", in, out);
-    cls_chunk_refcount_read_ret read_ret;
+    cache_ioctx.exec("bar", "cas", "chunk_read_refs", in, out);
+    cls_cas_chunk_read_refs_ret read_ret;
     try {
       auto iter = out.cbegin();
       decode(read_ret, iter);
@@ -3227,8 +3227,8 @@ TEST_F(LibRadosTwoPoolsPP, ManifestRefRead) {
   // chunk's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar-chunk", "cas", "chunk_read", in, out);
-    cls_chunk_refcount_read_ret read_ret;
+    cache_ioctx.exec("bar-chunk", "cas", "chunk_read_refs", in, out);
+    cls_cas_chunk_read_refs_ret read_ret;
     try {
       auto iter = out.cbegin();
       decode(read_ret, iter);
@@ -3304,8 +3304,8 @@ TEST_F(LibRadosTwoPoolsPP, ManifestUnset) {
   // redirect's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar", "cas", "chunk_read", in, out);
-    cls_chunk_refcount_read_ret read_ret;
+    cache_ioctx.exec("bar", "cas", "chunk_read_refs", in, out);
+    cls_cas_chunk_read_refs_ret read_ret;
     try {
       auto iter = out.cbegin();
       decode(read_ret, iter);
@@ -3317,8 +3317,8 @@ TEST_F(LibRadosTwoPoolsPP, ManifestUnset) {
   // chunk's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar-chunk", "cas", "chunk_read", in, out);
-    cls_chunk_refcount_read_ret read_ret;
+    cache_ioctx.exec("bar-chunk", "cas", "chunk_read_refs", in, out);
+    cls_cas_chunk_read_refs_ret read_ret;
     try {
       auto iter = out.cbegin();
       decode(read_ret, iter);
@@ -3352,7 +3352,7 @@ TEST_F(LibRadosTwoPoolsPP, ManifestUnset) {
   // redirect's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar", "cas", "chunk_read", in, out);
+    cache_ioctx.exec("bar", "cas", "chunk_read_refs", in, out);
     if (out.length() != 0U) {
       ObjectWriteOperation op;
       op.unset_manifest();
@@ -3366,7 +3366,7 @@ TEST_F(LibRadosTwoPoolsPP, ManifestUnset) {
   // chunk's refcount 
   {
     bufferlist in, out;
-    cache_ioctx.exec("bar-chunk", "cas", "chunk_read", in, out);
+    cache_ioctx.exec("bar-chunk", "cas", "chunk_read_refs", in, out);
     if (out.length() != 0U) {
       ObjectWriteOperation op;
       op.unset_manifest();
@@ -3497,8 +3497,8 @@ TEST_F(LibRadosTwoPoolsPP, ManifestDedupRefRead) {
     sha1_gen.Update((const unsigned char *)"There hi", size);
     sha1_gen.Final(fingerprint);
     buf_to_hex(fingerprint, CEPH_CRYPTO_SHA1_DIGESTSIZE, p_str);
-    cache_ioctx.exec(p_str, "cas", "chunk_read", in, out);
-    cls_chunk_refcount_read_ret read_ret;
+    cache_ioctx.exec(p_str, "cas", "chunk_read_refs", in, out);
+    cls_cas_chunk_read_refs_ret read_ret;
     try {
       auto iter = out.cbegin();
       decode(read_ret, iter);
index 3cf9e2d18bb3e4a049fcec2f297fe050abf2b2f6..ed6ffc6209f221e4259d30c407206ad8904e904d 100644 (file)
@@ -61,6 +61,16 @@ TYPE_FEATUREFUL(entity_inst_t)
 #include "crush/CrushWrapper.h"
 TYPE_FEATUREFUL_NOCOPY(CrushWrapper)
 
+#include "cls/cas/cls_cas_ops.h"
+TYPE(cls_cas_chunk_create_or_get_ref_op)
+TYPE(cls_cas_chunk_get_ref_op)
+TYPE(cls_cas_chunk_put_ref_op)
+TYPE(cls_cas_chunk_set_refs_op)
+TYPE(cls_cas_chunk_read_refs_ret)
+
+#include "cls/cas/cls_cas_internal.h"
+TYPE(chunk_obj_refcount)
+
 #include "cls/lock/cls_lock_types.h"
 TYPE(rados::cls::lock::locker_id_t)
 TYPE_FEATUREFUL(rados::cls::lock::locker_info_t)
index 48d468b157ed60c05bb8045defbfe34ab78b2a7a..bef1a5eb1bc7e26d491a5a098163d1efca570d2c 100644 (file)
@@ -430,7 +430,7 @@ void ChunkScrub::chunk_scrub_common()
       auto oid = i.oid;
       set<hobject_t> refs;
       set<hobject_t> real_refs;
-      ret = cls_chunk_refcount_read(chunk_io_ctx, oid, &refs);
+      ret = cls_cas_chunk_read_refs(chunk_io_ctx, oid, &refs);
       if (ret < 0) {
        continue;
       }
@@ -445,7 +445,7 @@ void ChunkScrub::chunk_scrub_common()
          continue;
        }
 
-       ret = cls_chunk_has_chunk(target_io_ctx, pp.oid.name, oid);
+       ret = cls_cas_references_chunk(target_io_ctx, pp.oid.name, oid);
        if (ret != -ENOENT) {
          real_refs.insert(pp);
        } 
@@ -453,7 +453,7 @@ void ChunkScrub::chunk_scrub_common()
 
       if (refs.size() != real_refs.size()) {
        ObjectWriteOperation op;
-       cls_chunk_refcount_set(op, real_refs);
+       cls_cas_chunk_set_refs(op, real_refs);
        ret = chunk_io_ctx.operate(oid, &op);
        if (ret < 0) {
          continue;
@@ -778,9 +778,9 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts,
     }
 
     set<hobject_t> refs;
-    ret = cls_chunk_refcount_read(chunk_io_ctx, object_name, &refs);
+    ret = cls_cas_chunk_read_refs(chunk_io_ctx, object_name, &refs);
     if (ret < 0) {
-      cerr << " cls_chunk_refcount_read fail : " << cpp_strerror(ret) << std::endl;
+      cerr << " cls_cas_chunk_read fail : " << cpp_strerror(ret) << std::endl;
       return ret;
     }
     for (auto p : refs) {
@@ -796,7 +796,7 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts,
     refs.insert(oid);
 
     ObjectWriteOperation op;
-    cls_chunk_refcount_set(op, refs);
+    cls_cas_chunk_set_refs(op, refs);
     ret = chunk_io_ctx.operate(object_name, &op);
     if (ret < 0) {
       cerr << " operate fail : " << cpp_strerror(ret) << std::endl;
@@ -814,7 +814,7 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts,
     }
     set<hobject_t> refs;
     cout << " refs: " << std::endl;
-    ret = cls_chunk_refcount_read(chunk_io_ctx, object_name, &refs);
+    ret = cls_cas_chunk_read_refs(chunk_io_ctx, object_name, &refs);
     for (auto p : refs) {
       cout << " " << p.oid.name << " ";
     }