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})
--- /dev/null
+// -*- 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;
+}
+
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+// -*- 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
#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;
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!");
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 */
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;
}
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;
-}
};
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
.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)
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);
+}
#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
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;
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);
#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;
#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"