]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: using fingerprint OID if fingerprint is set
authormyoungwon oh <omwmw@sk.com>
Sun, 22 Jul 2018 16:35:58 +0000 (01:35 +0900)
committermyoungwon oh <omwmw@sk.com>
Fri, 7 Sep 2018 12:11:16 +0000 (21:11 +0900)
cas class is introduced(cas class includes a write_or_get op)
This operation increase the reference count
if the chunk is already stored.

Signed-off-by: Myoungwon Oh <omwmw@sk.com>
14 files changed:
src/cls/CMakeLists.txt
src/cls/cas/cls_cas.cc [new file with mode: 0644]
src/cls/cas/cls_cas_client.cc [new file with mode: 0644]
src/cls/cas/cls_cas_client.h [new file with mode: 0644]
src/cls/cas/cls_cas_ops.h [new file with mode: 0644]
src/cls/refcount/cls_refcount.cc
src/cls/refcount/cls_refcount_client.cc
src/cls/refcount/cls_refcount_ops.h
src/common/options.cc
src/objclass/class_api.cc
src/objclass/objclass.h
src/osd/PrimaryLogPG.cc
src/osd/PrimaryLogPG.h
src/test/librados/tier.cc

index 2369f3c179669607f9351921542a942667143ced..fa0c05d9acfb337c8d1097a6f515d0cfc8f5aaa6 100644 (file)
@@ -262,3 +262,17 @@ set(cls_lua_client_srcs
     lua/cls_lua_client.cc)
 add_library(cls_lua_client STATIC ${cls_lua_client_srcs})
 
+# cls_cas
+set(cls_cas_srcs 
+  cas/cls_cas.cc)
+add_library(cls_cas SHARED ${cls_cas_srcs})
+set_target_properties(cls_cas PROPERTIES
+  VERSION "1.0.0"
+  SOVERSION "1"
+  INSTALL_RPATH ""
+  CXX_VISIBILITY_PRESET hidden)
+install(TARGETS cls_cas DESTINATION ${cls_dir})
+
+set(cls_cas_client_srcs
+  cas/cls_cas_client.cc)
+add_library(cls_cas_client STATIC ${cls_cas_client_srcs})
diff --git a/src/cls/cas/cls_cas.cc b/src/cls/cas/cls_cas.cc
new file mode 100644 (file)
index 0000000..cfa808e
--- /dev/null
@@ -0,0 +1,239 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <errno.h>
+
+#include "objclass/objclass.h"
+#include "cls_cas_ops.h"
+
+#include "include/compat.h"
+#include "osd/osd_types.h"
+
+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)
+{
+  bufferlist bl;
+  objr->refs.clear();
+  int ret = cls_cxx_getxattr(hctx, CHUNK_REFCOUNT_ATTR, &bl);
+  if (ret == -ENODATA) {
+    return 0;
+  }
+  if (ret < 0)
+    return ret;
+
+  try {
+    auto iter = bl.cbegin();
+    decode(*objr, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(0, "ERROR: chunk_read_refcount(): failed to decode refcount entry\n");
+    return -EIO;
+  }
+
+  return 0;
+}
+
+static int chunk_set_refcount(cls_method_context_t hctx, const struct chunk_obj_refcount& objr)
+{
+  bufferlist bl;
+
+  encode(objr, bl);
+
+  int ret = cls_cxx_setxattr(hctx, CHUNK_REFCOUNT_ATTR, &bl);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+static int cls_rc_chunk_refcount_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  auto in_iter = in->cbegin();
+
+  cls_chunk_refcount_get_op op;
+  try {
+    decode(op, in_iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(1, "ERROR: cls_rc_refcount_get(): failed to decode entry\n");
+    return -EINVAL;
+  }
+
+  chunk_obj_refcount objr;
+  int ret = chunk_read_refcount(hctx, &objr);
+  if (ret < 0)
+    return ret;
+
+  CLS_LOG(10, "cls_rc_chunk_refcount_get() oid=%s\n", op.source.oid.name.c_str());
+
+  objr.refs.insert(op.source);
+
+  ret = chunk_set_refcount(hctx, objr);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+static int cls_rc_chunk_refcount_put(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  auto in_iter = in->cbegin();
+
+  cls_chunk_refcount_put_op op;
+  try {
+    decode(op, in_iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(1, "ERROR: cls_rc_chunk_refcount_put(): failed to decode entry\n");
+    return -EINVAL;
+  }
+
+  chunk_obj_refcount objr;
+  int ret = chunk_read_refcount(hctx, &objr);
+  if (ret < 0)
+    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;
+  }
+
+  auto p = objr.refs.find(op.source);
+  objr.refs.erase(p);
+
+  if (objr.refs.empty()) {
+    return cls_cxx_remove(hctx);
+  }
+
+  ret = chunk_set_refcount(hctx, objr);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+static int cls_rc_chunk_refcount_set(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  auto in_iter = in->cbegin();
+
+  cls_chunk_refcount_set_op op;
+  try {
+    decode(op, in_iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(1, "ERROR: cls_chunk_refcount_set(): failed to decode entry\n");
+    return -EINVAL;
+  }
+
+  if (!op.refs.size()) {
+    return cls_cxx_remove(hctx);
+  }
+
+  chunk_obj_refcount objr;
+  objr.refs = op.refs;
+
+  int ret = chunk_set_refcount(hctx, objr);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+static int cls_rc_chunk_refcount_read(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  chunk_obj_refcount objr;
+
+  cls_chunk_refcount_read_ret read_ret;
+  int ret = chunk_read_refcount(hctx, &objr);
+  if (ret < 0)
+    return ret;
+
+  for (auto &p : objr.refs) {
+    read_ret.refs.insert(p);
+  }
+
+  encode(read_ret, *out);
+
+  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 (buffer::error& e) {
+    return -EINVAL;
+  }
+
+  CLS_LOG(10, " offset: %llu length: %llu \n", op.extent.offset, 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;
+}
+
+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_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);
+
+  return;
+}
+
diff --git a/src/cls/cas/cls_cas_client.cc b/src/cls/cas/cls_cas_client.cc
new file mode 100644 (file)
index 0000000..bcea9d0
--- /dev/null
@@ -0,0 +1,54 @@
+#include <errno.h>
+
+#include "cls/cas/cls_cas_client.h"
+#include "cls/cas/cls_cas_ops.h"
+#include "include/rados/librados.hpp"
+
+using namespace librados;
+
+void cls_chunk_refcount_get(librados::ObjectWriteOperation& op, const hobject_t& soid)
+{
+  bufferlist in;
+  cls_chunk_refcount_get_op call;
+  call.source = soid;
+  encode(call, in);
+  op.exec("refcount", "chunk_get", in);
+}
+
+void cls_chunk_refcount_put(librados::ObjectWriteOperation& op, const hobject_t& soid)
+{
+  bufferlist in;
+  cls_chunk_refcount_put_op call;
+  call.source = soid;
+  encode(call, in);
+  op.exec("refcount", "chunk_put", in);
+}
+
+void cls_chunk_refcount_set(librados::ObjectWriteOperation& op, set<hobject_t>& refs)
+{
+  bufferlist in;
+  cls_chunk_refcount_set_op call;
+  call.refs = refs;
+  encode(call, in);
+  op.exec("refcount", "chunk_set", in);
+}
+
+int cls_chunk_refcount_read(librados::IoCtx& io_ctx, string& oid, set<hobject_t> *refs)
+{
+  bufferlist in, out;
+  int r = io_ctx.exec(oid, "refcount", "chunk_read", in, out);
+  if (r < 0)
+    return r;
+
+  cls_chunk_refcount_read_ret ret;
+  try {
+    auto iter = out.cbegin();
+    decode(ret, iter);
+  } catch (buffer::error& err) {
+    return -EIO;
+  }
+
+  *refs = ret.refs;
+
+  return r;
+}
diff --git a/src/cls/cas/cls_cas_client.h b/src/cls/cas/cls_cas_client.h
new file mode 100644 (file)
index 0000000..4fad0f6
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef CEPH_CLS_CAS_CLIENT_H
+#define CEPH_CLS_CAS_CLIENT_H
+
+#include "include/types.h"
+#include "common/hobject.h"
+
+namespace librados {
+  class ObjectWriteOperation;
+  class IoCtx;
+}
+
+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, set<hobject_t>& refs);
+int cls_chunk_refcount_read(librados::IoCtx& io_ctx, string& oid, set<hobject_t> *refs);
+#endif
diff --git a/src/cls/cas/cls_cas_ops.h b/src/cls/cas/cls_cas_ops.h
new file mode 100644 (file)
index 0000000..35bc90d
--- /dev/null
@@ -0,0 +1,142 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_CLS_CAS_OPS_H
+#define CEPH_CLS_CAS_OPS_H
+
+#include "include/types.h"
+#include "common/hobject.h"
+
+#define CHUNK_REFCOUNT_ATTR "chunk_refcount"
+
+struct cls_chunk_refcount_get_op {
+  hobject_t source;
+
+  cls_chunk_refcount_get_op() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(source, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(source, bl);
+    DECODE_FINISH(bl);
+  }
+  void dump(ceph::Formatter *f) const;
+  static void generate_test_instances(list<cls_chunk_refcount_get_op*>& ls);
+};
+WRITE_CLASS_ENCODER(cls_chunk_refcount_get_op)
+
+struct cls_chunk_refcount_put_op {
+  hobject_t source;
+
+  cls_chunk_refcount_put_op() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(source, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(source, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(ceph::Formatter *f) const;
+  static void generate_test_instances(list<cls_chunk_refcount_put_op*>& ls);
+};
+WRITE_CLASS_ENCODER(cls_chunk_refcount_put_op)
+
+struct cls_chunk_refcount_set_op {
+  set<hobject_t> refs;
+
+  cls_chunk_refcount_set_op() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(refs, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(refs, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(ceph::Formatter *f) const;
+  static void generate_test_instances(list<cls_chunk_refcount_set_op*>& ls);
+};
+WRITE_CLASS_ENCODER(cls_chunk_refcount_set_op)
+
+struct cls_chunk_refcount_read_ret {
+  set<hobject_t> refs;
+
+  cls_chunk_refcount_read_ret() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(refs, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(refs, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(ceph::Formatter *f) const;
+  static void generate_test_instances(list<cls_chunk_refcount_read_ret*>& ls);
+};
+WRITE_CLASS_ENCODER(cls_chunk_refcount_read_ret)
+
+struct chunk_obj_refcount {
+  set<hobject_t> refs;
+
+  chunk_obj_refcount() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(refs, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(1, bl);
+    decode(refs, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(chunk_obj_refcount)
+
+struct obj_refcount {
+  map<string, bool> refs;
+  set<string> retired_refs;
+
+  obj_refcount() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(2, 1, bl);
+    encode(refs, bl);
+    encode(retired_refs, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator& bl) {
+    DECODE_START(2, bl);
+    decode(refs, bl);
+    if (struct_v >= 2) {
+      decode(retired_refs, bl);
+    }
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(obj_refcount)
+
+#endif
index 24798342eea14d849de6bed8083bd3330b6633b8..73cc3b852fddc994d59c288e036f6659b3e6d530 100644 (file)
@@ -13,50 +13,6 @@ CLS_NAME(refcount)
 
 
 #define REFCOUNT_ATTR "refcount"
-#define CHUNK_REFCOUNT_ATTR "chunk_refcount"
-
-struct chunk_obj_refcount {
-  set<hobject_t> refs;
-
-  chunk_obj_refcount() {}
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    encode(refs, bl);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(1, bl);
-    decode(refs, bl);
-    DECODE_FINISH(bl);
-  }
-};
-WRITE_CLASS_ENCODER(chunk_obj_refcount)
-
-struct obj_refcount {
-  map<string, bool> refs;
-  set<string> retired_refs;
-
-  obj_refcount() {}
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(2, 1, bl);
-    encode(refs, bl);
-    encode(retired_refs, bl);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(2, bl);
-    decode(refs, bl);
-    if (struct_v >= 2) {
-      decode(retired_refs, bl);
-    }
-    DECODE_FINISH(bl);
-  }
-};
-WRITE_CLASS_ENCODER(obj_refcount)
 
 static string wildcard_tag;
 
@@ -237,163 +193,6 @@ static int cls_rc_refcount_read(cls_method_context_t hctx, bufferlist *in, buffe
   return 0;
 }
 
-static int chunk_read_refcount(cls_method_context_t hctx, chunk_obj_refcount *objr)
-{
-  bufferlist bl;
-  objr->refs.clear();
-  int ret = cls_cxx_getxattr(hctx, CHUNK_REFCOUNT_ATTR, &bl);
-  if (ret == -ENODATA) {
-    return 0;
-  }
-  if (ret < 0)
-    return ret;
-
-  try {
-    auto iter = bl.cbegin();
-    decode(*objr, iter);
-  } catch (buffer::error& err) {
-    CLS_LOG(0, "ERROR: chunk_read_refcount(): failed to decode refcount entry\n");
-    return -EIO;
-  }
-
-  return 0;
-}
-
-static int chunk_set_refcount(cls_method_context_t hctx, const struct chunk_obj_refcount& objr)
-{
-  bufferlist bl;
-
-  encode(objr, bl);
-
-  int ret = cls_cxx_setxattr(hctx, CHUNK_REFCOUNT_ATTR, &bl);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-static int cls_rc_chunk_refcount_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
-{
-  auto in_iter = in->cbegin();
-
-  cls_chunk_refcount_get_op op;
-  try {
-    decode(op, in_iter);
-  } catch (buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_rc_refcount_get(): failed to decode entry\n");
-    return -EINVAL;
-  }
-
-  chunk_obj_refcount objr;
-  int ret = chunk_read_refcount(hctx, &objr);
-  if (ret < 0)
-    return ret;
-
-  CLS_LOG(10, "cls_rc_chunk_refcount_get() oid=%s\n", op.source.oid.name.c_str());
-
-  objr.refs.insert(op.source);
-
-  ret = chunk_set_refcount(hctx, objr);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-static int cls_rc_chunk_refcount_put(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
-{
-  auto in_iter = in->cbegin();
-
-  cls_chunk_refcount_put_op op;
-  try {
-    decode(op, in_iter);
-  } catch (buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_rc_chunk_refcount_put(): failed to decode entry\n");
-    return -EINVAL;
-  }
-
-  chunk_obj_refcount objr;
-  int ret = chunk_read_refcount(hctx, &objr);
-  if (ret < 0)
-    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;
-  }
-
-  auto p = objr.refs.find(op.source);
-  objr.refs.erase(p);
-
-  if (objr.refs.empty()) {
-    return cls_cxx_remove(hctx);
-  }
-
-  ret = chunk_set_refcount(hctx, objr);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-static int cls_rc_chunk_refcount_set(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
-{
-  auto in_iter = in->cbegin();
-
-  cls_chunk_refcount_set_op op;
-  try {
-    decode(op, in_iter);
-  } catch (buffer::error& err) {
-    CLS_LOG(1, "ERROR: cls_chunk_refcount_set(): failed to decode entry\n");
-    return -EINVAL;
-  }
-
-  if (!op.refs.size()) {
-    return cls_cxx_remove(hctx);
-  }
-
-  chunk_obj_refcount objr;
-  objr.refs = op.refs;
-
-  int ret = chunk_set_refcount(hctx, objr);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-static int cls_rc_chunk_refcount_read(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
-{
-  chunk_obj_refcount objr;
-
-  cls_chunk_refcount_read_ret read_ret;
-  int ret = chunk_read_refcount(hctx, &objr);
-  if (ret < 0)
-    return ret;
-
-  for (auto &p : objr.refs) {
-    read_ret.refs.insert(p);
-  }
-
-  encode(read_ret, *out);
-
-  return 0;
-}
-
 CLS_INIT(refcount)
 {
   CLS_LOG(1, "Loaded refcount class!");
@@ -404,11 +203,6 @@ CLS_INIT(refcount)
   cls_method_handle_t h_refcount_set;
   cls_method_handle_t h_refcount_read;
 
-  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_register("refcount", &h_class);
 
   /* refcount */
@@ -416,15 +210,6 @@ CLS_INIT(refcount)
   cls_register_cxx_method(h_class, "put", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_refcount_put, &h_refcount_put);
   cls_register_cxx_method(h_class, "set", CLS_METHOD_RD | CLS_METHOD_WR, cls_rc_refcount_set, &h_refcount_set);
   cls_register_cxx_method(h_class, "read", CLS_METHOD_RD, cls_rc_refcount_read, &h_refcount_read);
-  /* 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);
 
   return;
 }
index ae2853f73e0ba605bdc8a2cebed720861148bad5..9d5210c8abc85dac6e18c1ceedfc2f20c4d46397 100644 (file)
@@ -59,49 +59,3 @@ int cls_refcount_read(librados::IoCtx& io_ctx, string& oid, list<string> *refs,
   return r;
 }
 
-void cls_chunk_refcount_get(librados::ObjectWriteOperation& op, const hobject_t& soid)
-{
-  bufferlist in;
-  cls_chunk_refcount_get_op call;
-  call.source = soid;
-  encode(call, in);
-  op.exec("refcount", "chunk_get", in);
-}
-
-void cls_chunk_refcount_put(librados::ObjectWriteOperation& op, const hobject_t& soid)
-{
-  bufferlist in;
-  cls_chunk_refcount_put_op call;
-  call.source = soid;
-  encode(call, in);
-  op.exec("refcount", "chunk_put", in);
-}
-
-void cls_chunk_refcount_set(librados::ObjectWriteOperation& op, set<hobject_t>& refs)
-{
-  bufferlist in;
-  cls_chunk_refcount_set_op call;
-  call.refs = refs;
-  encode(call, in);
-  op.exec("refcount", "chunk_set", in);
-}
-
-int cls_chunk_refcount_read(librados::IoCtx& io_ctx, string& oid, set<hobject_t> *refs)
-{
-  bufferlist in, out;
-  int r = io_ctx.exec(oid, "refcount", "chunk_read", in, out);
-  if (r < 0)
-    return r;
-
-  cls_chunk_refcount_read_ret ret;
-  try {
-    auto iter = out.cbegin();
-    decode(ret, iter);
-  } catch (buffer::error& err) {
-    return -EIO;
-  }
-
-  *refs = ret.refs;
-
-  return r;
-}
index 6775d82cdaeede0145da532205f8edcca9ba28a8..3feaedc92d462570e2ecee3f327c6428a3aa3868 100644 (file)
@@ -124,90 +124,28 @@ struct cls_refcount_read_ret {
 };
 WRITE_CLASS_ENCODER(cls_refcount_read_ret)
 
-struct cls_chunk_refcount_get_op {
-  hobject_t source;
+struct obj_refcount {
+  map<string, bool> refs;
+  set<string> retired_refs;
 
-  cls_chunk_refcount_get_op() {}
+  obj_refcount() {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    encode(source, bl);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(1, bl);
-    decode(source, bl);
-    DECODE_FINISH(bl);
-  }
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(list<cls_chunk_refcount_get_op*>& ls);
-};
-WRITE_CLASS_ENCODER(cls_chunk_refcount_get_op)
-
-struct cls_chunk_refcount_put_op {
-  hobject_t source;
-
-  cls_chunk_refcount_put_op() {}
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    encode(source, bl);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(1, bl);
-    decode(source, bl);
-    DECODE_FINISH(bl);
-  }
-
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(list<cls_chunk_refcount_put_op*>& ls);
-};
-WRITE_CLASS_ENCODER(cls_chunk_refcount_put_op)
-
-struct cls_chunk_refcount_set_op {
-  set<hobject_t> refs;
-
-  cls_chunk_refcount_set_op() {}
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(2, 1, bl);
     encode(refs, bl);
+    encode(retired_refs, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(1, bl);
+    DECODE_START(2, bl);
     decode(refs, bl);
+    if (struct_v >= 2) {
+      decode(retired_refs, bl);
+    }
     DECODE_FINISH(bl);
   }
-
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(list<cls_chunk_refcount_set_op*>& ls);
 };
-WRITE_CLASS_ENCODER(cls_chunk_refcount_set_op)
-
-struct cls_chunk_refcount_read_ret {
-  set<hobject_t> refs;
-
-  cls_chunk_refcount_read_ret() {}
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    encode(refs, bl);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(1, bl);
-    decode(refs, bl);
-    DECODE_FINISH(bl);
-  }
+WRITE_CLASS_ENCODER(obj_refcount)
 
-  void dump(ceph::Formatter *f) const;
-  static void generate_test_instances(list<cls_chunk_refcount_read_ret*>& ls);
-};
-WRITE_CLASS_ENCODER(cls_chunk_refcount_read_ret)
 #endif
index 68f036ce6bccf137fdb4a59dfe6531dbc7f16794..0c1081fd848d5eb3aed5b049a290649113f856c5 100644 (file)
@@ -3157,11 +3157,11 @@ std::vector<Option> get_global_options() {
     .set_description(""),
 
     Option("osd_class_load_list", Option::TYPE_STR, Option::LEVEL_ADVANCED)
-    .set_default("cephfs hello journal lock log numops " "otp rbd refcount rgw statelog timeindex user version")
+    .set_default("cephfs hello journal lock log numops " "otp rbd refcount rgw statelog timeindex user version cas")
     .set_description(""),
 
     Option("osd_class_default_list", Option::TYPE_STR, Option::LEVEL_ADVANCED)
-    .set_default("cephfs hello journal lock log numops " "otp rbd refcount rgw statelog timeindex user version")
+    .set_default("cephfs hello journal lock log numops " "otp rbd refcount rgw statelog timeindex user version cas")
     .set_description(""),
 
     Option("osd_check_for_log_corruption", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
index 3edfbf6244c513e9e8c8dfe350ff2624667b3488..8d0776c389eac3b04f0c73d1af4545d0c13d0188 100644 (file)
@@ -731,3 +731,29 @@ int cls_log(int level, const char *format, ...)
      size *= 2;
    }
 }
+
+int cls_cxx_chunk_write_and_set(cls_method_context_t hctx, int ofs, int len,
+                   bufferlist *write_inbl, uint32_t op_flags, bufferlist *set_inbl,
+                  int set_len)
+{
+  PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
+  char cname[] = "refcount";
+  char method[] = "chunk_set";
+
+  vector<OSDOp> ops(2);
+  ops[0].op.op = CEPH_OSD_OP_WRITE;
+  ops[0].op.extent.offset = ofs;
+  ops[0].op.extent.length = len;
+  ops[0].op.flags = op_flags;
+  ops[0].indata = *write_inbl;
+
+  ops[1].op.op = CEPH_OSD_OP_CALL;
+  ops[1].op.cls.class_len = strlen(cname);
+  ops[1].op.cls.method_len = strlen(method);
+  ops[1].op.cls.indata_len = set_len;
+  ops[1].indata.append(cname, ops[1].op.cls.class_len);
+  ops[1].indata.append(method, ops[1].op.cls.method_len);
+  ops[1].indata.append(*set_inbl);
+
+  return (*pctx)->pg->do_osd_ops(*pctx, ops);
+}
index df2017d9f5d2224f6aac2308827ccc3be61bbd4e..f1d08f8c20cc3101e7884cc854e1bc8ed35a388c 100644 (file)
@@ -168,6 +168,9 @@ extern int cls_get_snapset_seq(cls_method_context_t hctx, uint64_t *snap_seq);
 #define CEPH_OSD_TMAP_CREATE 'c'
 #define CEPH_OSD_TMAP_RM 'r'
 
+int cls_cxx_chunk_write_and_set(cls_method_context_t hctx, int ofs, int len,
+                   bufferlist *write_inbl, uint32_t op_flags, bufferlist *set_inbl,
+                  int set_len);
 
 #endif
 
index 94f51a258166074f39b233e0858ecbde6df0cc0c..23240db8f726507b1f98a8744a4c5c115cf51790 100644 (file)
@@ -2609,11 +2609,42 @@ int PrimaryLogPG::do_manifest_flush(OpRequestRef op, ObjectContextRef obc, Flush
     if (!chunk_data.length()) {
       return -ENODATA;
     }
-    tgt_length = chunk_data.length();
-    obj_op.add_data(CEPH_OSD_OP_WRITE, tgt_offset, tgt_length, chunk_data);
 
+    tgt_length = chunk_data.length();
+    pg_pool_t::fingerprint_t fp_t = pool.info.get_fingerprint_type();
+    if (iter->second.has_reference() &&
+       fp_t != pg_pool_t::TYPE_FINGERPRINT_NONE) {
+      switch (fp_t) {
+       case pg_pool_t::TYPE_FINGERPRINT_SHA1:
+         {
+           boost::optional<sha1_digest_info_t> fp_t = chunk_data.sha1();
+           object_t fp_oid;
+           bufferlist in;
+           if (fp_t != boost::none) {
+             fp_oid = fp_t.get().to_str();
+           }
+           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);
+           break;
+         }
+       default:
+         assert(0 == "unrecognized fingerprint type");
+         break;
+      }
+    } else {
+      obj_op.add_data(CEPH_OSD_OP_WRITE, tgt_offset, tgt_length, chunk_data);
+    }
     unsigned flags = CEPH_OSD_FLAG_IGNORE_CACHE | CEPH_OSD_FLAG_IGNORE_OVERLAY |
                     CEPH_OSD_FLAG_RWORDERED ;
+
     C_ManifestFlush *fin = new C_ManifestFlush(this, soid, get_last_peering_reset());
     fin->offset = iter->first;
     fin->last_offset = last_offset;
@@ -3450,12 +3481,12 @@ void PrimaryLogPG::refcount_manifest(ObjectContextRef obc, object_locator_t oloc
     cls_chunk_refcount_get_op call;
     call.source = obc->obs.oi.soid;
     ::encode(call, in);                             
-    obj_op.call("refcount", "chunk_get", in);         
+    obj_op.call("cas", "chunk_get", in);         
   } else {                    
     cls_chunk_refcount_put_op call;                
     call.source = obc->obs.oi.soid;
     ::encode(call, in);          
-    obj_op.call("refcount", "chunk_put", in);         
+    obj_op.call("cas", "chunk_put", in);         
   }                                                     
   
   unsigned n = info.pgid.hash_to_shard(osd->m_objecter_finishers);
index 0afdbaf2d8c2379a9c388f24059b93ad82cc7626..65299344f939c879d0d14e0ae8e917e651ae18eb 100644 (file)
@@ -29,7 +29,7 @@
 #include "common/shared_cache.hpp"
 #include "ReplicatedBackend.h"
 #include "PGTransaction.h"
-#include "cls/refcount/cls_refcount_ops.h"
+#include "cls/cas/cls_cas_ops.h"
 
 class CopyFromCallback;
 class PromoteCallback;
index 26d2c0e69eab762a2134c4047a405de11203d1ed..08dc40807fd544fae6f32e8ca6f33ae748f644f7 100644 (file)
@@ -14,7 +14,7 @@
 #include "test/librados/test.h"
 #include "test/librados/TestCase.h"
 #include "json_spirit/json_spirit.h"
-#include "cls/refcount/cls_refcount_ops.h"
+#include "cls/cas/cls_cas_ops.h"
 
 #include "osd/HitSet.h"