summaryrefslogtreecommitdiffstats
path: root/src/librados/librados_cxx.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/librados/librados_cxx.cc
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/librados/librados_cxx.cc3177
1 files changed, 3177 insertions, 0 deletions
diff --git a/src/librados/librados_cxx.cc b/src/librados/librados_cxx.cc
new file mode 100644
index 000000000..8c9ac3c91
--- /dev/null
+++ b/src/librados/librados_cxx.cc
@@ -0,0 +1,3177 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2012 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <limits.h>
+
+#include "common/config.h"
+#include "common/errno.h"
+#include "common/ceph_argparse.h"
+#include "common/ceph_json.h"
+#include "common/common_init.h"
+#include "common/TracepointProvider.h"
+#include "common/hobject.h"
+#include "common/async/waiter.h"
+#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
+#include "include/types.h"
+#include <include/stringify.h>
+
+#include "librados/AioCompletionImpl.h"
+#include "librados/IoCtxImpl.h"
+#include "librados/PoolAsyncCompletionImpl.h"
+#include "librados/RadosClient.h"
+#include "librados/RadosXattrIter.h"
+#include "librados/ListObjectImpl.h"
+#include "librados/librados_util.h"
+#include "cls/lock/cls_lock_client.h"
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+#include <list>
+#include <stdexcept>
+#include <system_error>
+
+#ifdef WITH_LTTNG
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
+#include "tracing/librados.h"
+#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
+#undef TRACEPOINT_DEFINE
+#else
+#define tracepoint(...)
+#endif
+
+using std::string;
+using std::map;
+using std::set;
+using std::vector;
+using std::list;
+
+#define dout_subsys ceph_subsys_rados
+#undef dout_prefix
+#define dout_prefix *_dout << "librados: "
+
+static TracepointProvider::Traits tracepoint_traits("librados_tp.so", "rados_tracing");
+
+/*
+ * Structure of this file
+ *
+ * RadosClient and the related classes are the internal implementation of librados.
+ * Above that layer sits the C API, found in include/rados/librados.h, and
+ * the C++ API, found in include/rados/librados.hpp
+ *
+ * The C++ API sometimes implements things in terms of the C API.
+ * Both the C++ and C API rely on RadosClient.
+ *
+ * Visually:
+ * +--------------------------------------+
+ * | C++ API |
+ * +--------------------+ |
+ * | C API | |
+ * +--------------------+-----------------+
+ * | RadosClient |
+ * +--------------------------------------+
+ */
+
+namespace librados {
+
+struct ObjectOperationImpl {
+ ::ObjectOperation o;
+ real_time rt;
+ real_time *prt;
+
+ ObjectOperationImpl() : prt(NULL) {}
+};
+
+}
+
+size_t librados::ObjectOperation::size()
+{
+ ::ObjectOperation *o = &impl->o;
+ if (o)
+ return o->size();
+ else
+ return 0;
+}
+
+//deprcated
+void librados::ObjectOperation::set_op_flags(ObjectOperationFlags flags)
+{
+ set_op_flags2((int)flags);
+}
+
+void librados::ObjectOperation::set_op_flags2(int flags)
+{
+ ceph_assert(impl);
+ impl->o.set_last_op_flags(get_op_flags(flags));
+}
+
+void librados::ObjectOperation::cmpext(uint64_t off,
+ const bufferlist &cmp_bl,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = cmp_bl;
+ o->cmpext(off, c, prval);
+}
+
+void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, const bufferlist& v)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_STRING, v);
+}
+
+void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, uint64_t v)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist bl;
+ encode(v, bl);
+ o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_U64, bl);
+}
+
+void librados::ObjectOperation::assert_version(uint64_t ver)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->assert_version(ver);
+}
+
+void librados::ObjectOperation::assert_exists()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->stat(nullptr, nullptr, nullptr);
+}
+
+void librados::ObjectOperation::exec(const char *cls, const char *method,
+ bufferlist& inbl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->call(cls, method, inbl);
+}
+
+void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, bufferlist *outbl, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->call(cls, method, inbl, outbl, NULL, prval);
+}
+
+class ObjectOpCompletionCtx : public Context {
+ librados::ObjectOperationCompletion *completion;
+ bufferlist bl;
+public:
+ explicit ObjectOpCompletionCtx(librados::ObjectOperationCompletion *c) : completion(c) {}
+ void finish(int r) override {
+ completion->handle_completion(r, bl);
+ delete completion;
+ }
+
+ bufferlist *outbl() {
+ return &bl;
+ }
+};
+
+void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, librados::ObjectOperationCompletion *completion)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+
+ ObjectOpCompletionCtx *ctx = new ObjectOpCompletionCtx(completion);
+
+ o->call(cls, method, inbl, ctx->outbl(), ctx, NULL);
+}
+
+void librados::ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->stat(psize, pmtime, prval);
+}
+
+void librados::ObjectReadOperation::stat2(uint64_t *psize, struct timespec *pts, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->stat(psize, pts, prval);
+}
+
+void librados::ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->read(off, len, pbl, prval, NULL);
+}
+
+void librados::ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
+ std::map<uint64_t,uint64_t> *m,
+ bufferlist *data_bl, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->sparse_read(off, len, m, data_bl, prval);
+}
+
+void librados::ObjectReadOperation::checksum(rados_checksum_type_t type,
+ const bufferlist &init_value_bl,
+ uint64_t off, size_t len,
+ size_t chunk_size, bufferlist *pbl,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->checksum(get_checksum_op_type(type), init_value_bl, off, len, chunk_size,
+ pbl, prval, nullptr);
+}
+
+void librados::ObjectReadOperation::getxattr(const char *name, bufferlist *pbl, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->getxattr(name, pbl, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_vals(
+ const std::string &start_after,
+ const std::string &filter_prefix,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, nullptr,
+ prval);
+}
+
+void librados::ObjectReadOperation::omap_get_vals2(
+ const std::string &start_after,
+ const std::string &filter_prefix,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ bool *pmore,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, pmore,
+ prval);
+}
+
+void librados::ObjectReadOperation::omap_get_vals(
+ const std::string &start_after,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_vals(start_after, "", max_return, out_vals, nullptr, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_vals2(
+ const std::string &start_after,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ bool *pmore,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_vals(start_after, "", max_return, out_vals, pmore, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_keys(
+ const std::string &start_after,
+ uint64_t max_return,
+ std::set<std::string> *out_keys,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_keys(start_after, max_return, out_keys, nullptr, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_keys2(
+ const std::string &start_after,
+ uint64_t max_return,
+ std::set<std::string> *out_keys,
+ bool *pmore,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_keys(start_after, max_return, out_keys, pmore, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_header(bufferlist *bl, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_header(bl, prval);
+}
+
+void librados::ObjectReadOperation::omap_get_vals_by_keys(
+ const std::set<std::string> &keys,
+ std::map<std::string, bufferlist> *map,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_get_vals_by_keys(keys, map, prval);
+}
+
+void librados::ObjectOperation::omap_cmp(
+ const std::map<std::string, pair<bufferlist, int> > &assertions,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_cmp(assertions, prval);
+}
+
+void librados::ObjectReadOperation::list_watchers(
+ list<obj_watch_t> *out_watchers,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->list_watchers(out_watchers, prval);
+}
+
+void librados::ObjectReadOperation::list_snaps(
+ snap_set_t *out_snaps,
+ int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->list_snaps(out_snaps, prval);
+}
+
+void librados::ObjectReadOperation::is_dirty(bool *is_dirty, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->is_dirty(is_dirty, prval);
+}
+
+int librados::IoCtx::omap_get_vals(const std::string& oid,
+ const std::string& orig_start_after,
+ const std::string& filter_prefix,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals)
+{
+ bool first = true;
+ string start_after = orig_start_after;
+ bool more = true;
+ while (max_return > 0 && more) {
+ std::map<std::string,bufferlist> out;
+ ObjectReadOperation op;
+ op.omap_get_vals2(start_after, filter_prefix, max_return, &out, &more,
+ nullptr);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0) {
+ return ret;
+ }
+ if (more) {
+ if (out.empty()) {
+ return -EINVAL; // wth
+ }
+ start_after = out.rbegin()->first;
+ }
+ if (out.size() <= max_return) {
+ max_return -= out.size();
+ } else {
+ max_return = 0;
+ }
+ if (first) {
+ out_vals->swap(out);
+ first = false;
+ } else {
+ out_vals->insert(out.begin(), out.end());
+ out.clear();
+ }
+ }
+ return 0;
+}
+
+int librados::IoCtx::omap_get_vals2(
+ const std::string& oid,
+ const std::string& start_after,
+ const std::string& filter_prefix,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ bool *pmore)
+{
+ ObjectReadOperation op;
+ int r;
+ op.omap_get_vals2(start_after, filter_prefix, max_return, out_vals, pmore, &r);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+ return r;
+}
+
+void librados::ObjectReadOperation::getxattrs(map<string, bufferlist> *pattrs, int *prval)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->getxattrs(pattrs, prval);
+}
+
+void librados::ObjectWriteOperation::mtime(time_t *pt)
+{
+ ceph_assert(impl);
+ if (pt) {
+ impl->rt = ceph::real_clock::from_time_t(*pt);
+ impl->prt = &impl->rt;
+ }
+}
+
+void librados::ObjectWriteOperation::mtime2(struct timespec *pts)
+{
+ ceph_assert(impl);
+ if (pts) {
+ impl->rt = ceph::real_clock::from_timespec(*pts);
+ impl->prt = &impl->rt;
+ }
+}
+
+void librados::ObjectWriteOperation::create(bool exclusive)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->create(exclusive);
+}
+
+void librados::ObjectWriteOperation::create(bool exclusive,
+ const std::string& category) // unused
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->create(exclusive);
+}
+
+void librados::ObjectWriteOperation::write(uint64_t off, const bufferlist& bl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = bl;
+ o->write(off, c);
+}
+
+void librados::ObjectWriteOperation::write_full(const bufferlist& bl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = bl;
+ o->write_full(c);
+}
+
+void librados::ObjectWriteOperation::writesame(uint64_t off, uint64_t write_len,
+ const bufferlist& bl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = bl;
+ o->writesame(off, write_len, c);
+}
+
+void librados::ObjectWriteOperation::append(const bufferlist& bl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = bl;
+ o->append(c);
+}
+
+void librados::ObjectWriteOperation::remove()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->remove();
+}
+
+void librados::ObjectWriteOperation::truncate(uint64_t off)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->truncate(off);
+}
+
+void librados::ObjectWriteOperation::zero(uint64_t off, uint64_t len)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->zero(off, len);
+}
+
+void librados::ObjectWriteOperation::rmxattr(const char *name)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->rmxattr(name);
+}
+
+void librados::ObjectWriteOperation::setxattr(const char *name, const bufferlist& v)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->setxattr(name, v);
+}
+
+void librados::ObjectWriteOperation::setxattr(const char *name,
+ const buffer::list&& v)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->setxattr(name, std::move(v));
+}
+
+void librados::ObjectWriteOperation::omap_set(
+ const map<string, bufferlist> &map)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_set(map);
+}
+
+void librados::ObjectWriteOperation::omap_set_header(const bufferlist &bl)
+{
+ ceph_assert(impl);
+ bufferlist c = bl;
+ ::ObjectOperation *o = &impl->o;
+ o->omap_set_header(c);
+}
+
+void librados::ObjectWriteOperation::omap_clear()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_clear();
+}
+
+void librados::ObjectWriteOperation::omap_rm_keys(
+ const std::set<std::string> &to_rm)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->omap_rm_keys(to_rm);
+}
+
+void librados::ObjectWriteOperation::copy_from(const std::string& src,
+ const IoCtx& src_ioctx,
+ uint64_t src_version,
+ uint32_t src_fadvise_flags)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->copy_from(object_t(src), src_ioctx.io_ctx_impl->snap_seq,
+ src_ioctx.io_ctx_impl->oloc, src_version, 0, src_fadvise_flags);
+}
+
+void librados::ObjectWriteOperation::copy_from2(const std::string& src,
+ const IoCtx& src_ioctx,
+ uint64_t src_version,
+ uint32_t truncate_seq,
+ uint64_t truncate_size,
+ uint32_t src_fadvise_flags)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->copy_from2(object_t(src), src_ioctx.io_ctx_impl->snap_seq,
+ src_ioctx.io_ctx_impl->oloc, src_version, 0,
+ truncate_seq, truncate_size, src_fadvise_flags);
+}
+
+void librados::ObjectWriteOperation::undirty()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->undirty();
+}
+
+void librados::ObjectReadOperation::cache_flush()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cache_flush();
+}
+
+void librados::ObjectReadOperation::cache_try_flush()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cache_try_flush();
+}
+
+void librados::ObjectReadOperation::cache_evict()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cache_evict();
+}
+
+void librados::ObjectReadOperation::tier_flush()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->tier_flush();
+}
+
+void librados::ObjectReadOperation::tier_evict()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->tier_evict();
+}
+
+void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj,
+ const IoCtx& tgt_ioctx,
+ uint64_t tgt_version,
+ int flag)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->set_redirect(object_t(tgt_obj), tgt_ioctx.io_ctx_impl->snap_seq,
+ tgt_ioctx.io_ctx_impl->oloc, tgt_version, flag);
+}
+
+void librados::ObjectReadOperation::set_chunk(uint64_t src_offset,
+ uint64_t src_length,
+ const IoCtx& tgt_ioctx,
+ string tgt_oid,
+ uint64_t tgt_offset,
+ int flag)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->set_chunk(src_offset, src_length,
+ tgt_ioctx.io_ctx_impl->oloc, object_t(tgt_oid), tgt_offset, flag);
+}
+
+void librados::ObjectWriteOperation::tier_promote()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->tier_promote();
+}
+
+void librados::ObjectWriteOperation::unset_manifest()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->unset_manifest();
+}
+
+void librados::ObjectWriteOperation::tmap_update(const bufferlist& cmdbl)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ bufferlist c = cmdbl;
+ o->tmap_update(c);
+}
+
+void librados::ObjectWriteOperation::selfmanaged_snap_rollback(snap_t snapid)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->rollback(snapid);
+}
+
+// You must specify the snapid not the name normally used with pool snapshots
+void librados::ObjectWriteOperation::snap_rollback(snap_t snapid)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->rollback(snapid);
+}
+
+void librados::ObjectWriteOperation::set_alloc_hint(
+ uint64_t expected_object_size,
+ uint64_t expected_write_size)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->set_alloc_hint(expected_object_size, expected_write_size, 0);
+}
+void librados::ObjectWriteOperation::set_alloc_hint2(
+ uint64_t expected_object_size,
+ uint64_t expected_write_size,
+ uint32_t flags)
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->set_alloc_hint(expected_object_size, expected_write_size, flags);
+}
+
+void librados::ObjectWriteOperation::cache_pin()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cache_pin();
+}
+
+void librados::ObjectWriteOperation::cache_unpin()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->cache_unpin();
+}
+
+librados::WatchCtx::
+~WatchCtx()
+{
+}
+
+librados::WatchCtx2::
+~WatchCtx2()
+{
+}
+
+///////////////////////////// NObjectIteratorImpl /////////////////////////////
+librados::NObjectIteratorImpl::NObjectIteratorImpl(ObjListCtx *ctx_)
+ : ctx(ctx_)
+{
+}
+
+librados::NObjectIteratorImpl::~NObjectIteratorImpl()
+{
+ ctx.reset();
+}
+
+librados::NObjectIteratorImpl::NObjectIteratorImpl(const NObjectIteratorImpl &rhs)
+{
+ *this = rhs;
+}
+
+librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator=(const librados::NObjectIteratorImpl &rhs)
+{
+ if (&rhs == this)
+ return *this;
+ if (rhs.ctx.get() == NULL) {
+ ctx.reset();
+ return *this;
+ }
+ Objecter::NListContext *list_ctx = new Objecter::NListContext(*rhs.ctx->nlc);
+ ctx.reset(new ObjListCtx(rhs.ctx->ctx, list_ctx));
+ cur_obj = rhs.cur_obj;
+ return *this;
+}
+
+bool librados::NObjectIteratorImpl::operator==(const librados::NObjectIteratorImpl& rhs) const {
+
+ if (ctx.get() == NULL) {
+ if (rhs.ctx.get() == NULL)
+ return true;
+ return rhs.ctx->nlc->at_end();
+ }
+ if (rhs.ctx.get() == NULL) {
+ // Redundant but same as ObjectIterator version
+ if (ctx.get() == NULL)
+ return true;
+ return ctx->nlc->at_end();
+ }
+ return ctx.get() == rhs.ctx.get();
+}
+
+bool librados::NObjectIteratorImpl::operator!=(const librados::NObjectIteratorImpl& rhs) const {
+ return !(*this == rhs);
+}
+
+const librados::ListObject& librados::NObjectIteratorImpl::operator*() const {
+ return cur_obj;
+}
+
+const librados::ListObject* librados::NObjectIteratorImpl::operator->() const {
+ return &cur_obj;
+}
+
+librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator++()
+{
+ get_next();
+ return *this;
+}
+
+librados::NObjectIteratorImpl librados::NObjectIteratorImpl::operator++(int)
+{
+ librados::NObjectIteratorImpl ret(*this);
+ get_next();
+ return ret;
+}
+
+uint32_t librados::NObjectIteratorImpl::seek(uint32_t pos)
+{
+ uint32_t r = rados_nobjects_list_seek(ctx.get(), pos);
+ get_next();
+ return r;
+}
+
+uint32_t librados::NObjectIteratorImpl::seek(const ObjectCursor& cursor)
+{
+ uint32_t r = rados_nobjects_list_seek_cursor(ctx.get(), (rados_object_list_cursor)cursor.c_cursor);
+ get_next();
+ return r;
+}
+
+librados::ObjectCursor librados::NObjectIteratorImpl::get_cursor()
+{
+ librados::ObjListCtx *lh = (librados::ObjListCtx *)ctx.get();
+ librados::ObjectCursor oc;
+ oc.set(lh->ctx->nlist_get_cursor(lh->nlc));
+ return oc;
+}
+
+void librados::NObjectIteratorImpl::set_filter(const bufferlist &bl)
+{
+ ceph_assert(ctx);
+ ctx->nlc->filter = bl;
+}
+
+void librados::NObjectIteratorImpl::get_next()
+{
+ const char *entry, *key, *nspace;
+ size_t entry_size, key_size, nspace_size;
+ if (ctx->nlc->at_end())
+ return;
+ int ret = rados_nobjects_list_next2(ctx.get(), &entry, &key, &nspace,
+ &entry_size, &key_size, &nspace_size);
+ if (ret == -ENOENT) {
+ return;
+ }
+ else if (ret) {
+ throw std::system_error(-ret, std::system_category(),
+ "rados_nobjects_list_next2");
+ }
+
+ if (cur_obj.impl == NULL)
+ cur_obj.impl = new ListObjectImpl();
+ cur_obj.impl->nspace = string{nspace, nspace_size};
+ cur_obj.impl->oid = string{entry, entry_size};
+ cur_obj.impl->locator = key ? string(key, key_size) : string();
+}
+
+uint32_t librados::NObjectIteratorImpl::get_pg_hash_position() const
+{
+ return ctx->nlc->get_pg_hash_position();
+}
+
+///////////////////////////// NObjectIterator /////////////////////////////
+librados::NObjectIterator::NObjectIterator(ObjListCtx *ctx_)
+{
+ impl = new NObjectIteratorImpl(ctx_);
+}
+
+librados::NObjectIterator::~NObjectIterator()
+{
+ delete impl;
+}
+
+librados::NObjectIterator::NObjectIterator(const NObjectIterator &rhs)
+{
+ if (rhs.impl == NULL) {
+ impl = NULL;
+ return;
+ }
+ impl = new NObjectIteratorImpl();
+ *impl = *(rhs.impl);
+}
+
+librados::NObjectIterator& librados::NObjectIterator::operator=(const librados::NObjectIterator &rhs)
+{
+ if (rhs.impl == NULL) {
+ delete impl;
+ impl = NULL;
+ return *this;
+ }
+ if (impl == NULL)
+ impl = new NObjectIteratorImpl();
+ *impl = *(rhs.impl);
+ return *this;
+}
+
+bool librados::NObjectIterator::operator==(const librados::NObjectIterator& rhs) const
+{
+ if (impl && rhs.impl) {
+ return *impl == *(rhs.impl);
+ } else {
+ return impl == rhs.impl;
+ }
+}
+
+bool librados::NObjectIterator::operator!=(const librados::NObjectIterator& rhs) const
+{
+ return !(*this == rhs);
+}
+
+const librados::ListObject& librados::NObjectIterator::operator*() const {
+ ceph_assert(impl);
+ return *(impl->get_listobjectp());
+}
+
+const librados::ListObject* librados::NObjectIterator::operator->() const {
+ ceph_assert(impl);
+ return impl->get_listobjectp();
+}
+
+librados::NObjectIterator& librados::NObjectIterator::operator++()
+{
+ ceph_assert(impl);
+ impl->get_next();
+ return *this;
+}
+
+librados::NObjectIterator librados::NObjectIterator::operator++(int)
+{
+ librados::NObjectIterator ret(*this);
+ impl->get_next();
+ return ret;
+}
+
+uint32_t librados::NObjectIterator::seek(uint32_t pos)
+{
+ ceph_assert(impl);
+ return impl->seek(pos);
+}
+
+uint32_t librados::NObjectIterator::seek(const ObjectCursor& cursor)
+{
+ ceph_assert(impl);
+ return impl->seek(cursor);
+}
+
+librados::ObjectCursor librados::NObjectIterator::get_cursor()
+{
+ ceph_assert(impl);
+ return impl->get_cursor();
+}
+
+void librados::NObjectIterator::set_filter(const bufferlist &bl)
+{
+ impl->set_filter(bl);
+}
+
+void librados::NObjectIterator::get_next()
+{
+ ceph_assert(impl);
+ impl->get_next();
+}
+
+uint32_t librados::NObjectIterator::get_pg_hash_position() const
+{
+ ceph_assert(impl);
+ return impl->get_pg_hash_position();
+}
+
+const librados::NObjectIterator librados::NObjectIterator::__EndObjectIterator(NULL);
+
+///////////////////////////// PoolAsyncCompletion //////////////////////////////
+librados::PoolAsyncCompletion::PoolAsyncCompletion::~PoolAsyncCompletion()
+{
+ auto c = reinterpret_cast<PoolAsyncCompletionImpl *>(pc);
+ c->release();
+}
+
+int librados::PoolAsyncCompletion::PoolAsyncCompletion::set_callback(void *cb_arg,
+ rados_callback_t cb)
+{
+ PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
+ return c->set_callback(cb_arg, cb);
+}
+
+int librados::PoolAsyncCompletion::PoolAsyncCompletion::wait()
+{
+ PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
+ return c->wait();
+}
+
+bool librados::PoolAsyncCompletion::PoolAsyncCompletion::is_complete()
+{
+ PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
+ return c->is_complete();
+}
+
+int librados::PoolAsyncCompletion::PoolAsyncCompletion::get_return_value()
+{
+ PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
+ return c->get_return_value();
+}
+
+void librados::PoolAsyncCompletion::PoolAsyncCompletion::release()
+{
+ delete this;
+}
+
+///////////////////////////// AioCompletion //////////////////////////////
+librados::AioCompletion::AioCompletion::~AioCompletion()
+{
+ auto c = reinterpret_cast<AioCompletionImpl *>(pc);
+ c->release();
+}
+
+int librados::AioCompletion::AioCompletion::set_complete_callback(void *cb_arg, rados_callback_t cb)
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->set_complete_callback(cb_arg, cb);
+}
+
+int librados::AioCompletion::AioCompletion::set_safe_callback(void *cb_arg, rados_callback_t cb)
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->set_safe_callback(cb_arg, cb);
+}
+
+int librados::AioCompletion::AioCompletion::wait_for_complete()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->wait_for_complete();
+}
+
+int librados::AioCompletion::AioCompletion::wait_for_safe()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->wait_for_complete();
+}
+
+bool librados::AioCompletion::AioCompletion::is_complete()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->is_complete();
+}
+
+bool librados::AioCompletion::AioCompletion::is_safe()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->is_safe();
+}
+
+int librados::AioCompletion::AioCompletion::wait_for_complete_and_cb()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->wait_for_complete_and_cb();
+}
+
+int librados::AioCompletion::AioCompletion::wait_for_safe_and_cb()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->wait_for_safe_and_cb();
+}
+
+bool librados::AioCompletion::AioCompletion::is_complete_and_cb()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->is_complete_and_cb();
+}
+
+bool librados::AioCompletion::AioCompletion::is_safe_and_cb()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->is_safe_and_cb();
+}
+
+int librados::AioCompletion::AioCompletion::get_return_value()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->get_return_value();
+}
+
+int librados::AioCompletion::AioCompletion::get_version()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->get_version();
+}
+
+uint64_t librados::AioCompletion::AioCompletion::get_version64()
+{
+ AioCompletionImpl *c = (AioCompletionImpl *)pc;
+ return c->get_version();
+}
+
+void librados::AioCompletion::AioCompletion::release()
+{
+ delete this;
+}
+
+///////////////////////////// IoCtx //////////////////////////////
+librados::IoCtx::IoCtx() : io_ctx_impl(NULL)
+{
+}
+
+void librados::IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io)
+{
+ IoCtxImpl *io_ctx_impl = (IoCtxImpl*)p;
+
+ io.io_ctx_impl = io_ctx_impl;
+ if (io_ctx_impl) {
+ io_ctx_impl->get();
+ }
+}
+
+librados::IoCtx::IoCtx(const IoCtx& rhs)
+{
+ io_ctx_impl = rhs.io_ctx_impl;
+ if (io_ctx_impl) {
+ io_ctx_impl->get();
+ }
+}
+
+librados::IoCtx& librados::IoCtx::operator=(const IoCtx& rhs)
+{
+ if (io_ctx_impl)
+ io_ctx_impl->put();
+ io_ctx_impl = rhs.io_ctx_impl;
+ io_ctx_impl->get();
+ return *this;
+}
+
+librados::IoCtx::IoCtx(IoCtx&& rhs) noexcept
+ : io_ctx_impl(std::exchange(rhs.io_ctx_impl, nullptr))
+{
+}
+
+librados::IoCtx& librados::IoCtx::operator=(IoCtx&& rhs) noexcept
+{
+ if (io_ctx_impl)
+ io_ctx_impl->put();
+ io_ctx_impl = std::exchange(rhs.io_ctx_impl, nullptr);
+ return *this;
+}
+
+librados::IoCtx::~IoCtx()
+{
+ close();
+}
+
+bool librados::IoCtx::is_valid() const {
+ return io_ctx_impl != nullptr;
+}
+
+void librados::IoCtx::close()
+{
+ if (io_ctx_impl)
+ io_ctx_impl->put();
+ io_ctx_impl = 0;
+}
+
+void librados::IoCtx::dup(const IoCtx& rhs)
+{
+ if (io_ctx_impl)
+ io_ctx_impl->put();
+ io_ctx_impl = new IoCtxImpl();
+ io_ctx_impl->get();
+ io_ctx_impl->dup(*rhs.io_ctx_impl);
+}
+
+int librados::IoCtx::set_auid(uint64_t auid_)
+{
+ return -EOPNOTSUPP;
+}
+
+int librados::IoCtx::set_auid_async(uint64_t auid_, PoolAsyncCompletion *c)
+{
+ return -EOPNOTSUPP;
+}
+
+int librados::IoCtx::get_auid(uint64_t *auid_)
+{
+ return -EOPNOTSUPP;
+}
+
+bool librados::IoCtx::pool_requires_alignment()
+{
+ return io_ctx_impl->client->pool_requires_alignment(get_id());
+}
+
+int librados::IoCtx::pool_requires_alignment2(bool *requires)
+{
+ return io_ctx_impl->client->pool_requires_alignment2(get_id(), requires);
+}
+
+uint64_t librados::IoCtx::pool_required_alignment()
+{
+ return io_ctx_impl->client->pool_required_alignment(get_id());
+}
+
+int librados::IoCtx::pool_required_alignment2(uint64_t *alignment)
+{
+ return io_ctx_impl->client->pool_required_alignment2(get_id(), alignment);
+}
+
+std::string librados::IoCtx::get_pool_name()
+{
+ std::string s;
+ io_ctx_impl->client->pool_get_name(get_id(), &s);
+ return s;
+}
+
+std::string librados::IoCtx::get_pool_name() const
+{
+ return io_ctx_impl->get_cached_pool_name();
+}
+
+uint64_t librados::IoCtx::get_instance_id() const
+{
+ return io_ctx_impl->client->get_instance_id();
+}
+
+int librados::IoCtx::create(const std::string& oid, bool exclusive)
+{
+ object_t obj(oid);
+ return io_ctx_impl->create(obj, exclusive);
+}
+
+int librados::IoCtx::create(const std::string& oid, bool exclusive,
+ const std::string& category) // unused
+{
+ object_t obj(oid);
+ return io_ctx_impl->create(obj, exclusive);
+}
+
+int librados::IoCtx::write(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
+{
+ object_t obj(oid);
+ return io_ctx_impl->write(obj, bl, len, off);
+}
+
+int librados::IoCtx::append(const std::string& oid, bufferlist& bl, size_t len)
+{
+ object_t obj(oid);
+ return io_ctx_impl->append(obj, bl, len);
+}
+
+int librados::IoCtx::write_full(const std::string& oid, bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->write_full(obj, bl);
+}
+
+int librados::IoCtx::writesame(const std::string& oid, bufferlist& bl,
+ size_t write_len, uint64_t off)
+{
+ object_t obj(oid);
+ return io_ctx_impl->writesame(obj, bl, write_len, off);
+}
+
+
+int librados::IoCtx::read(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
+{
+ object_t obj(oid);
+ return io_ctx_impl->read(obj, bl, len, off);
+}
+
+int librados::IoCtx::checksum(const std::string& oid,
+ rados_checksum_type_t type,
+ const bufferlist &init_value_bl, size_t len,
+ uint64_t off, size_t chunk_size, bufferlist *pbl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->checksum(obj, get_checksum_op_type(type), init_value_bl,
+ len, off, chunk_size, pbl);
+}
+
+int librados::IoCtx::remove(const std::string& oid)
+{
+ object_t obj(oid);
+ return io_ctx_impl->remove(obj);
+}
+
+int librados::IoCtx::remove(const std::string& oid, int flags)
+{
+ object_t obj(oid);
+ return io_ctx_impl->remove(obj, flags);
+}
+
+int librados::IoCtx::trunc(const std::string& oid, uint64_t size)
+{
+ object_t obj(oid);
+ return io_ctx_impl->trunc(obj, size);
+}
+
+int librados::IoCtx::mapext(const std::string& oid, uint64_t off, size_t len,
+ std::map<uint64_t,uint64_t>& m)
+{
+ object_t obj(oid);
+ return io_ctx_impl->mapext(obj, off, len, m);
+}
+
+int librados::IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->cmpext(obj, off, cmp_bl);
+}
+
+int librados::IoCtx::sparse_read(const std::string& oid, std::map<uint64_t,uint64_t>& m,
+ bufferlist& bl, size_t len, uint64_t off)
+{
+ object_t obj(oid);
+ return io_ctx_impl->sparse_read(obj, m, bl, len, off);
+}
+
+int librados::IoCtx::getxattr(const std::string& oid, const char *name, bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->getxattr(obj, name, bl);
+}
+
+int librados::IoCtx::getxattrs(const std::string& oid, map<std::string, bufferlist>& attrset)
+{
+ object_t obj(oid);
+ return io_ctx_impl->getxattrs(obj, attrset);
+}
+
+int librados::IoCtx::setxattr(const std::string& oid, const char *name, bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->setxattr(obj, name, bl);
+}
+
+int librados::IoCtx::rmxattr(const std::string& oid, const char *name)
+{
+ object_t obj(oid);
+ return io_ctx_impl->rmxattr(obj, name);
+}
+
+int librados::IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtime)
+{
+ object_t obj(oid);
+ return io_ctx_impl->stat(obj, psize, pmtime);
+}
+
+int librados::IoCtx::stat2(const std::string& oid, uint64_t *psize, struct timespec *pts)
+{
+ object_t obj(oid);
+ return io_ctx_impl->stat2(obj, psize, pts);
+}
+
+int librados::IoCtx::exec(const std::string& oid, const char *cls, const char *method,
+ bufferlist& inbl, bufferlist& outbl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->exec(obj, cls, method, inbl, outbl);
+}
+
+int librados::IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->tmap_update(obj, cmdbl);
+}
+
+int librados::IoCtx::omap_get_vals(const std::string& oid,
+ const std::string& start_after,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals)
+{
+ return omap_get_vals(oid, start_after, string(), max_return, out_vals);
+}
+
+int librados::IoCtx::omap_get_vals2(
+ const std::string& oid,
+ const std::string& start_after,
+ uint64_t max_return,
+ std::map<std::string, bufferlist> *out_vals,
+ bool *pmore)
+{
+ ObjectReadOperation op;
+ int r;
+ op.omap_get_vals2(start_after, max_return, out_vals, pmore, &r);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+ return r;
+}
+
+int librados::IoCtx::omap_get_keys(const std::string& oid,
+ const std::string& orig_start_after,
+ uint64_t max_return,
+ std::set<std::string> *out_keys)
+{
+ bool first = true;
+ string start_after = orig_start_after;
+ bool more = true;
+ while (max_return > 0 && more) {
+ std::set<std::string> out;
+ ObjectReadOperation op;
+ op.omap_get_keys2(start_after, max_return, &out, &more, nullptr);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0) {
+ return ret;
+ }
+ if (more) {
+ if (out.empty()) {
+ return -EINVAL; // wth
+ }
+ start_after = *out.rbegin();
+ }
+ if (out.size() <= max_return) {
+ max_return -= out.size();
+ } else {
+ max_return = 0;
+ }
+ if (first) {
+ out_keys->swap(out);
+ first = false;
+ } else {
+ out_keys->insert(out.begin(), out.end());
+ out.clear();
+ }
+ }
+ return 0;
+}
+
+int librados::IoCtx::omap_get_keys2(
+ const std::string& oid,
+ const std::string& start_after,
+ uint64_t max_return,
+ std::set<std::string> *out_keys,
+ bool *pmore)
+{
+ ObjectReadOperation op;
+ int r;
+ op.omap_get_keys2(start_after, max_return, out_keys, pmore, &r);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+ return r;
+}
+
+int librados::IoCtx::omap_get_header(const std::string& oid,
+ bufferlist *bl)
+{
+ ObjectReadOperation op;
+ int r;
+ op.omap_get_header(bl, &r);
+ bufferlist b;
+ int ret = operate(oid, &op, &b);
+ if (ret < 0)
+ return ret;
+
+ return r;
+}
+
+int librados::IoCtx::omap_get_vals_by_keys(const std::string& oid,
+ const std::set<std::string>& keys,
+ std::map<std::string, bufferlist> *vals)
+{
+ ObjectReadOperation op;
+ int r;
+ bufferlist bl;
+ op.omap_get_vals_by_keys(keys, vals, &r);
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+
+ return r;
+}
+
+int librados::IoCtx::omap_set(const std::string& oid,
+ const map<string, bufferlist>& m)
+{
+ ObjectWriteOperation op;
+ op.omap_set(m);
+ return operate(oid, &op);
+}
+
+int librados::IoCtx::omap_set_header(const std::string& oid,
+ const bufferlist& bl)
+{
+ ObjectWriteOperation op;
+ op.omap_set_header(bl);
+ return operate(oid, &op);
+}
+
+int librados::IoCtx::omap_clear(const std::string& oid)
+{
+ ObjectWriteOperation op;
+ op.omap_clear();
+ return operate(oid, &op);
+}
+
+int librados::IoCtx::omap_rm_keys(const std::string& oid,
+ const std::set<std::string>& keys)
+{
+ ObjectWriteOperation op;
+ op.omap_rm_keys(keys);
+ return operate(oid, &op);
+}
+
+int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->operate(obj, &o->impl->o, (ceph::real_time *)o->impl->prt);
+}
+
+int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o, int flags)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->operate(obj, &o->impl->o, (ceph::real_time *)o->impl->prt, translate_flags(flags));
+}
+
+int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->operate_read(obj, &o->impl->o, pbl);
+}
+
+int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl, int flags)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->operate_read(obj, &o->impl->o, pbl, translate_flags(flags));
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectWriteOperation *o)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
+ io_ctx_impl->snapc, 0);
+}
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ ObjectWriteOperation *o, int flags)
+{
+ object_t obj(oid);
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
+ io_ctx_impl->snapc,
+ translate_flags(flags));
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectWriteOperation *o,
+ snap_t snap_seq, std::vector<snap_t>& snaps)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ vector<snapid_t> snv;
+ snv.resize(snaps.size());
+ for (size_t i = 0; i < snaps.size(); ++i)
+ snv[i] = snaps[i];
+ SnapContext snapc(snap_seq, snv);
+ return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
+ snapc, 0);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectWriteOperation *o,
+ snap_t snap_seq, std::vector<snap_t>& snaps,
+ const blkin_trace_info *trace_info)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ vector<snapid_t> snv;
+ snv.resize(snaps.size());
+ for (size_t i = 0; i < snaps.size(); ++i)
+ snv[i] = snaps[i];
+ SnapContext snapc(snap_seq, snv);
+ return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
+ snapc, 0, trace_info);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectWriteOperation *o,
+ snap_t snap_seq, std::vector<snap_t>& snaps, int flags,
+ const blkin_trace_info *trace_info)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ vector<snapid_t> snv;
+ snv.resize(snaps.size());
+ for (size_t i = 0; i < snaps.size(); ++i)
+ snv[i] = snaps[i];
+ SnapContext snapc(snap_seq, snv);
+ return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc, snapc,
+ translate_flags(flags), trace_info);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectReadOperation *o,
+ bufferlist *pbl)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
+ 0, pbl);
+}
+
+// deprecated
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectReadOperation *o,
+ snap_t snapid_unused_deprecated,
+ int flags, bufferlist *pbl)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ int op_flags = 0;
+ if (flags & OPERATION_BALANCE_READS)
+ op_flags |= CEPH_OSD_FLAG_BALANCE_READS;
+ if (flags & OPERATION_LOCALIZE_READS)
+ op_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
+ if (flags & OPERATION_ORDER_READS_WRITES)
+ op_flags |= CEPH_OSD_FLAG_RWORDERED;
+
+ return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
+ op_flags, pbl);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectReadOperation *o,
+ int flags, bufferlist *pbl)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
+ translate_flags(flags), pbl);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+ librados::ObjectReadOperation *o,
+ int flags, bufferlist *pbl, const blkin_trace_info *trace_info)
+{
+ if (unlikely(!o->impl))
+ return -EINVAL;
+ object_t obj(oid);
+ return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
+ translate_flags(flags), pbl, trace_info);
+}
+
+void librados::IoCtx::snap_set_read(snap_t seq)
+{
+ io_ctx_impl->set_snap_read(seq);
+}
+
+int librados::IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq, vector<snap_t>& snaps)
+{
+ vector<snapid_t> snv;
+ snv.resize(snaps.size());
+ for (unsigned i=0; i<snaps.size(); i++)
+ snv[i] = snaps[i];
+ return io_ctx_impl->set_snap_write_context(seq, snv);
+}
+
+int librados::IoCtx::snap_create(const char *snapname)
+{
+ return io_ctx_impl->snap_create(snapname);
+}
+
+int librados::IoCtx::snap_lookup(const char *name, snap_t *snapid)
+{
+ return io_ctx_impl->snap_lookup(name, snapid);
+}
+
+int librados::IoCtx::snap_get_stamp(snap_t snapid, time_t *t)
+{
+ return io_ctx_impl->snap_get_stamp(snapid, t);
+}
+
+int librados::IoCtx::snap_get_name(snap_t snapid, std::string *s)
+{
+ return io_ctx_impl->snap_get_name(snapid, s);
+}
+
+int librados::IoCtx::snap_remove(const char *snapname)
+{
+ return io_ctx_impl->snap_remove(snapname);
+}
+
+int librados::IoCtx::snap_list(std::vector<snap_t> *snaps)
+{
+ return io_ctx_impl->snap_list(snaps);
+}
+
+int librados::IoCtx::snap_rollback(const std::string& oid, const char *snapname)
+{
+ return io_ctx_impl->rollback(oid, snapname);
+}
+
+// Deprecated name kept for backward compatibility
+int librados::IoCtx::rollback(const std::string& oid, const char *snapname)
+{
+ return snap_rollback(oid, snapname);
+}
+
+int librados::IoCtx::selfmanaged_snap_create(uint64_t *snapid)
+{
+ return io_ctx_impl->selfmanaged_snap_create(snapid);
+}
+
+void librados::IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid,
+ AioCompletion *c)
+{
+ io_ctx_impl->aio_selfmanaged_snap_create(snapid, c->pc);
+}
+
+int librados::IoCtx::selfmanaged_snap_remove(uint64_t snapid)
+{
+ return io_ctx_impl->selfmanaged_snap_remove(snapid);
+}
+
+void librados::IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid,
+ AioCompletion *c)
+{
+ io_ctx_impl->aio_selfmanaged_snap_remove(snapid, c->pc);
+}
+
+int librados::IoCtx::selfmanaged_snap_rollback(const std::string& oid, uint64_t snapid)
+{
+ return io_ctx_impl->selfmanaged_snap_rollback_object(oid,
+ io_ctx_impl->snapc,
+ snapid);
+}
+
+int librados::IoCtx::lock_exclusive(const std::string &oid, const std::string &name,
+ const std::string &cookie,
+ const std::string &description,
+ struct timeval * duration, uint8_t flags)
+{
+ utime_t dur = utime_t();
+ if (duration)
+ dur.set_from_timeval(duration);
+
+ return rados::cls::lock::lock(this, oid, name, ClsLockType::EXCLUSIVE, cookie, "",
+ description, dur, flags);
+}
+
+int librados::IoCtx::lock_shared(const std::string &oid, const std::string &name,
+ const std::string &cookie, const std::string &tag,
+ const std::string &description,
+ struct timeval * duration, uint8_t flags)
+{
+ utime_t dur = utime_t();
+ if (duration)
+ dur.set_from_timeval(duration);
+
+ return rados::cls::lock::lock(this, oid, name, ClsLockType::SHARED, cookie, tag,
+ description, dur, flags);
+}
+
+int librados::IoCtx::unlock(const std::string &oid, const std::string &name,
+ const std::string &cookie)
+{
+ return rados::cls::lock::unlock(this, oid, name, cookie);
+}
+
+struct AioUnlockCompletion : public librados::ObjectOperationCompletion {
+ librados::AioCompletionImpl *completion;
+ AioUnlockCompletion(librados::AioCompletion *c) : completion(c->pc) {
+ completion->get();
+ };
+ void handle_completion(int r, bufferlist& outbl) override {
+ rados_callback_t cb = completion->callback_complete;
+ void *cb_arg = completion->callback_complete_arg;
+ cb(completion, cb_arg);
+ completion->lock.lock();
+ completion->callback_complete = NULL;
+ completion->cond.notify_all();
+ completion->put_unlock();
+ }
+};
+
+int librados::IoCtx::aio_unlock(const std::string &oid, const std::string &name,
+ const std::string &cookie, AioCompletion *c)
+{
+ return rados::cls::lock::aio_unlock(this, oid, name, cookie, c);
+}
+
+int librados::IoCtx::break_lock(const std::string &oid, const std::string &name,
+ const std::string &client, const std::string &cookie)
+{
+ entity_name_t locker;
+ if (!locker.parse(client))
+ return -EINVAL;
+ return rados::cls::lock::break_lock(this, oid, name, cookie, locker);
+}
+
+int librados::IoCtx::list_lockers(const std::string &oid, const std::string &name,
+ int *exclusive,
+ std::string *tag,
+ std::list<librados::locker_t> *lockers)
+{
+ std::list<librados::locker_t> tmp_lockers;
+ map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t> rados_lockers;
+ std::string tmp_tag;
+ ClsLockType tmp_type;
+ int r = rados::cls::lock::get_lock_info(this, oid, name, &rados_lockers, &tmp_type, &tmp_tag);
+ if (r < 0)
+ return r;
+
+ map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t>::iterator map_it;
+ for (map_it = rados_lockers.begin(); map_it != rados_lockers.end(); ++map_it) {
+ librados::locker_t locker;
+ locker.client = stringify(map_it->first.locker);
+ locker.cookie = map_it->first.cookie;
+ locker.address = stringify(map_it->second.addr);
+ tmp_lockers.push_back(locker);
+ }
+
+ if (lockers)
+ *lockers = tmp_lockers;
+ if (tag)
+ *tag = tmp_tag;
+ if (exclusive) {
+ if (tmp_type == ClsLockType::EXCLUSIVE)
+ *exclusive = 1;
+ else
+ *exclusive = 0;
+ }
+
+ return tmp_lockers.size();
+}
+
+librados::NObjectIterator librados::IoCtx::nobjects_begin(
+ const bufferlist &filter)
+{
+ rados_list_ctx_t listh;
+ rados_nobjects_list_open(io_ctx_impl, &listh);
+ NObjectIterator iter((ObjListCtx*)listh);
+ if (filter.length() > 0) {
+ iter.set_filter(filter);
+ }
+ iter.get_next();
+ return iter;
+}
+
+librados::NObjectIterator librados::IoCtx::nobjects_begin(
+ uint32_t pos, const bufferlist &filter)
+{
+ rados_list_ctx_t listh;
+ rados_nobjects_list_open(io_ctx_impl, &listh);
+ NObjectIterator iter((ObjListCtx*)listh);
+ if (filter.length() > 0) {
+ iter.set_filter(filter);
+ }
+ iter.seek(pos);
+ return iter;
+}
+
+librados::NObjectIterator librados::IoCtx::nobjects_begin(
+ const ObjectCursor& cursor, const bufferlist &filter)
+{
+ rados_list_ctx_t listh;
+ rados_nobjects_list_open(io_ctx_impl, &listh);
+ NObjectIterator iter((ObjListCtx*)listh);
+ if (filter.length() > 0) {
+ iter.set_filter(filter);
+ }
+ iter.seek(cursor);
+ return iter;
+}
+
+const librados::NObjectIterator& librados::IoCtx::nobjects_end() const
+{
+ return NObjectIterator::__EndObjectIterator;
+}
+
+int librados::IoCtx::hit_set_list(uint32_t hash, AioCompletion *c,
+ std::list< std::pair<time_t, time_t> > *pls)
+{
+ return io_ctx_impl->hit_set_list(hash, c->pc, pls);
+}
+
+int librados::IoCtx::hit_set_get(uint32_t hash, AioCompletion *c, time_t stamp,
+ bufferlist *pbl)
+{
+ return io_ctx_impl->hit_set_get(hash, c->pc, stamp, pbl);
+}
+
+
+
+uint64_t librados::IoCtx::get_last_version()
+{
+ return io_ctx_impl->last_version();
+}
+
+int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
+ bufferlist *pbl, size_t len, uint64_t off)
+{
+ return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off,
+ io_ctx_impl->snap_seq);
+}
+
+int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
+ bufferlist *pbl, size_t len, uint64_t off,
+ uint64_t snapid)
+{
+ return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off, snapid);
+}
+
+int librados::IoCtx::aio_exec(const std::string& oid,
+ librados::AioCompletion *c, const char *cls,
+ const char *method, bufferlist& inbl,
+ bufferlist *outbl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_exec(obj, c->pc, cls, method, inbl, outbl);
+}
+
+int librados::IoCtx::aio_cmpext(const std::string& oid,
+ librados::AioCompletion *c,
+ uint64_t off,
+ bufferlist& cmp_bl)
+{
+ return io_ctx_impl->aio_cmpext(oid, c->pc, off, cmp_bl);
+}
+
+int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
+ std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
+ size_t len, uint64_t off)
+{
+ return io_ctx_impl->aio_sparse_read(oid, c->pc,
+ m, data_bl, len, off,
+ io_ctx_impl->snap_seq);
+}
+
+int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
+ std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
+ size_t len, uint64_t off, uint64_t snapid)
+{
+ return io_ctx_impl->aio_sparse_read(oid, c->pc,
+ m, data_bl, len, off, snapid);
+}
+
+int librados::IoCtx::aio_write(const std::string& oid, librados::AioCompletion *c,
+ const bufferlist& bl, size_t len, uint64_t off)
+{
+ return io_ctx_impl->aio_write(oid, c->pc, bl, len, off);
+}
+
+int librados::IoCtx::aio_append(const std::string& oid, librados::AioCompletion *c,
+ const bufferlist& bl, size_t len)
+{
+ return io_ctx_impl->aio_append(oid, c->pc, bl, len);
+}
+
+int librados::IoCtx::aio_write_full(const std::string& oid, librados::AioCompletion *c,
+ const bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_write_full(obj, c->pc, bl);
+}
+
+int librados::IoCtx::aio_writesame(const std::string& oid, librados::AioCompletion *c,
+ const bufferlist& bl, size_t write_len,
+ uint64_t off)
+{
+ return io_ctx_impl->aio_writesame(oid, c->pc, bl, write_len, off);
+}
+
+
+int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c)
+{
+ return io_ctx_impl->aio_remove(oid, c->pc);
+}
+
+int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c, int flags)
+{
+ return io_ctx_impl->aio_remove(oid, c->pc, flags);
+}
+
+int librados::IoCtx::aio_flush_async(librados::AioCompletion *c)
+{
+ io_ctx_impl->flush_aio_writes_async(c->pc);
+ return 0;
+}
+
+int librados::IoCtx::aio_flush()
+{
+ io_ctx_impl->flush_aio_writes();
+ return 0;
+}
+
+struct AioGetxattrDataPP {
+ AioGetxattrDataPP(librados::AioCompletionImpl *c, bufferlist *_bl) :
+ bl(_bl), completion(c) {}
+ bufferlist *bl;
+ struct librados::CB_AioCompleteAndSafe completion;
+};
+
+static void rados_aio_getxattr_completepp(rados_completion_t c, void *arg) {
+ AioGetxattrDataPP *cdata = reinterpret_cast<AioGetxattrDataPP*>(arg);
+ int rc = rados_aio_get_return_value(c);
+ if (rc >= 0) {
+ rc = cdata->bl->length();
+ }
+ cdata->completion(rc);
+ delete cdata;
+}
+
+int librados::IoCtx::aio_getxattr(const std::string& oid, librados::AioCompletion *c,
+ const char *name, bufferlist& bl)
+{
+ // create data object to be passed to async callback
+ AioGetxattrDataPP *cdata = new AioGetxattrDataPP(c->pc, &bl);
+ if (!cdata) {
+ return -ENOMEM;
+ }
+ // create completion callback
+ librados::AioCompletionImpl *comp = new librados::AioCompletionImpl;
+ comp->set_complete_callback(cdata, rados_aio_getxattr_completepp);
+ // call actual getxattr from IoCtxImpl
+ object_t obj(oid);
+ return io_ctx_impl->aio_getxattr(obj, comp, name, bl);
+}
+
+int librados::IoCtx::aio_getxattrs(const std::string& oid, AioCompletion *c,
+ map<std::string, bufferlist>& attrset)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_getxattrs(obj, c->pc, attrset);
+}
+
+int librados::IoCtx::aio_setxattr(const std::string& oid, AioCompletion *c,
+ const char *name, bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_setxattr(obj, c->pc, name, bl);
+}
+
+int librados::IoCtx::aio_rmxattr(const std::string& oid, AioCompletion *c,
+ const char *name)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_rmxattr(obj, c->pc, name);
+}
+
+int librados::IoCtx::aio_stat(const std::string& oid, librados::AioCompletion *c,
+ uint64_t *psize, time_t *pmtime)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_stat(obj, c->pc, psize, pmtime);
+}
+
+int librados::IoCtx::aio_cancel(librados::AioCompletion *c)
+{
+ return io_ctx_impl->aio_cancel(c->pc);
+}
+
+int librados::IoCtx::watch(const string& oid, uint64_t ver, uint64_t *cookie,
+ librados::WatchCtx *ctx)
+{
+ object_t obj(oid);
+ return io_ctx_impl->watch(obj, cookie, ctx, NULL);
+}
+
+int librados::IoCtx::watch2(const string& oid, uint64_t *cookie,
+ librados::WatchCtx2 *ctx2)
+{
+ object_t obj(oid);
+ return io_ctx_impl->watch(obj, cookie, NULL, ctx2);
+}
+
+int librados::IoCtx::watch3(const string& oid, uint64_t *cookie,
+ librados::WatchCtx2 *ctx2, uint32_t timeout)
+{
+ object_t obj(oid);
+ return io_ctx_impl->watch(obj, cookie, NULL, ctx2, timeout);
+}
+
+int librados::IoCtx::aio_watch(const string& oid, AioCompletion *c,
+ uint64_t *cookie,
+ librados::WatchCtx2 *ctx2)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2);
+}
+
+int librados::IoCtx::aio_watch2(const string& oid, AioCompletion *c,
+ uint64_t *cookie,
+ librados::WatchCtx2 *ctx2,
+ uint32_t timeout)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2, timeout);
+}
+
+int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
+{
+ return io_ctx_impl->unwatch(handle);
+}
+
+int librados::IoCtx::unwatch2(uint64_t handle)
+{
+ return io_ctx_impl->unwatch(handle);
+}
+
+int librados::IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c)
+{
+ return io_ctx_impl->aio_unwatch(handle, c->pc);
+}
+
+int librados::IoCtx::watch_check(uint64_t handle)
+{
+ return io_ctx_impl->watch_check(handle);
+}
+
+int librados::IoCtx::notify(const string& oid, uint64_t ver, bufferlist& bl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->notify(obj, bl, 0, NULL, NULL, NULL);
+}
+
+int librados::IoCtx::notify2(const string& oid, bufferlist& bl,
+ uint64_t timeout_ms, bufferlist *preplybl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->notify(obj, bl, timeout_ms, preplybl, NULL, NULL);
+}
+
+int librados::IoCtx::aio_notify(const string& oid, AioCompletion *c,
+ bufferlist& bl, uint64_t timeout_ms,
+ bufferlist *preplybl)
+{
+ object_t obj(oid);
+ return io_ctx_impl->aio_notify(obj, c->pc, bl, timeout_ms, preplybl, NULL,
+ NULL);
+}
+
+void librados::IoCtx::decode_notify_response(bufferlist &bl,
+ std::vector<librados::notify_ack_t> *acks,
+ std::vector<librados::notify_timeout_t> *timeouts)
+{
+ map<pair<uint64_t,uint64_t>,bufferlist> acked;
+ set<pair<uint64_t,uint64_t>> missed;
+
+ auto iter = bl.cbegin();
+ decode(acked, iter);
+ decode(missed, iter);
+
+ for (auto &[who, payload] : acked) {
+ acks->emplace_back(librados::notify_ack_t{who.first, who.second, payload});
+ }
+ for (auto &[notifier_id, cookie] : missed) {
+ timeouts->emplace_back(librados::notify_timeout_t{notifier_id, cookie});
+ }
+}
+
+void librados::IoCtx::notify_ack(const std::string& o,
+ uint64_t notify_id, uint64_t handle,
+ bufferlist& bl)
+{
+ io_ctx_impl->notify_ack(o, notify_id, handle, bl);
+}
+
+int librados::IoCtx::list_watchers(const std::string& oid,
+ std::list<obj_watch_t> *out_watchers)
+{
+ ObjectReadOperation op;
+ int r;
+ op.list_watchers(out_watchers, &r);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+
+ return r;
+}
+
+int librados::IoCtx::list_snaps(const std::string& oid,
+ snap_set_t *out_snaps)
+{
+ ObjectReadOperation op;
+ int r;
+ if (io_ctx_impl->snap_seq != CEPH_SNAPDIR)
+ return -EINVAL;
+ op.list_snaps(out_snaps, &r);
+ bufferlist bl;
+ int ret = operate(oid, &op, &bl);
+ if (ret < 0)
+ return ret;
+
+ return r;
+}
+
+void librados::IoCtx::set_notify_timeout(uint32_t timeout)
+{
+ io_ctx_impl->set_notify_timeout(timeout);
+}
+
+int librados::IoCtx::set_alloc_hint(const std::string& o,
+ uint64_t expected_object_size,
+ uint64_t expected_write_size)
+{
+ object_t oid(o);
+ return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
+ expected_write_size, 0);
+}
+
+int librados::IoCtx::set_alloc_hint2(const std::string& o,
+ uint64_t expected_object_size,
+ uint64_t expected_write_size,
+ uint32_t flags)
+{
+ object_t oid(o);
+ return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
+ expected_write_size, flags);
+}
+
+void librados::IoCtx::set_assert_version(uint64_t ver)
+{
+ io_ctx_impl->set_assert_version(ver);
+}
+
+void librados::IoCtx::locator_set_key(const string& key)
+{
+ io_ctx_impl->oloc.key = key;
+}
+
+void librados::IoCtx::set_namespace(const string& nspace)
+{
+ io_ctx_impl->oloc.nspace = nspace;
+}
+
+std::string librados::IoCtx::get_namespace() const
+{
+ return io_ctx_impl->oloc.nspace;
+}
+
+int64_t librados::IoCtx::get_id()
+{
+ return io_ctx_impl->get_id();
+}
+
+uint32_t librados::IoCtx::get_object_hash_position(const std::string& oid)
+{
+ uint32_t hash;
+ int r = io_ctx_impl->get_object_hash_position(oid, &hash);
+ if (r < 0)
+ hash = 0;
+ return hash;
+}
+
+uint32_t librados::IoCtx::get_object_pg_hash_position(const std::string& oid)
+{
+ uint32_t hash;
+ int r = io_ctx_impl->get_object_pg_hash_position(oid, &hash);
+ if (r < 0)
+ hash = 0;
+ return hash;
+}
+
+int librados::IoCtx::get_object_hash_position2(
+ const std::string& oid, uint32_t *hash_position)
+{
+ return io_ctx_impl->get_object_hash_position(oid, hash_position);
+}
+
+int librados::IoCtx::get_object_pg_hash_position2(
+ const std::string& oid, uint32_t *pg_hash_position)
+{
+ return io_ctx_impl->get_object_pg_hash_position(oid, pg_hash_position);
+}
+
+librados::config_t librados::IoCtx::cct()
+{
+ return (config_t)io_ctx_impl->client->cct;
+}
+
+librados::IoCtx::IoCtx(IoCtxImpl *io_ctx_impl_)
+ : io_ctx_impl(io_ctx_impl_)
+{
+}
+
+void librados::IoCtx::set_osdmap_full_try()
+{
+ io_ctx_impl->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
+}
+
+void librados::IoCtx::unset_osdmap_full_try()
+{
+ io_ctx_impl->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
+}
+
+bool librados::IoCtx::get_pool_full_try()
+{
+ return (io_ctx_impl->extra_op_flags & CEPH_OSD_FLAG_FULL_TRY) != 0;
+}
+
+void librados::IoCtx::set_pool_full_try()
+{
+ io_ctx_impl->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
+}
+
+void librados::IoCtx::unset_pool_full_try()
+{
+ io_ctx_impl->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
+}
+
+///////////////////////////// Rados //////////////////////////////
+void librados::Rados::version(int *major, int *minor, int *extra)
+{
+ rados_version(major, minor, extra);
+}
+
+librados::Rados::Rados() : client(NULL)
+{
+}
+
+librados::Rados::Rados(IoCtx &ioctx)
+{
+ client = ioctx.io_ctx_impl->client;
+ ceph_assert(client != NULL);
+ client->get();
+}
+
+librados::Rados::~Rados()
+{
+ shutdown();
+}
+
+void librados::Rados::from_rados_t(rados_t cluster, Rados &rados) {
+ if (rados.client) {
+ rados.client->put();
+ }
+ rados.client = static_cast<RadosClient*>(cluster);
+ if (rados.client) {
+ rados.client->get();
+ }
+}
+
+int librados::Rados::init(const char * const id)
+{
+ return rados_create((rados_t *)&client, id);
+}
+
+int librados::Rados::init2(const char * const name,
+ const char * const clustername, uint64_t flags)
+{
+ return rados_create2((rados_t *)&client, clustername, name, flags);
+}
+
+int librados::Rados::init_with_context(config_t cct_)
+{
+ return rados_create_with_context((rados_t *)&client, (rados_config_t)cct_);
+}
+
+int librados::Rados::connect()
+{
+ return client->connect();
+}
+
+librados::config_t librados::Rados::cct()
+{
+ return (config_t)client->cct;
+}
+
+int librados::Rados::watch_flush()
+{
+ if (!client)
+ return -EINVAL;
+ return client->watch_flush();
+}
+
+int librados::Rados::aio_watch_flush(AioCompletion *c)
+{
+ if (!client)
+ return -EINVAL;
+ return client->async_watch_flush(c->pc);
+}
+
+void librados::Rados::shutdown()
+{
+ if (!client)
+ return;
+ if (client->put()) {
+ client->shutdown();
+ delete client;
+ client = NULL;
+ }
+}
+
+uint64_t librados::Rados::get_instance_id()
+{
+ return client->get_instance_id();
+}
+
+int librados::Rados::get_min_compatible_osd(int8_t* require_osd_release)
+{
+ return client->get_min_compatible_osd(require_osd_release);
+}
+
+int librados::Rados::get_min_compatible_client(int8_t* min_compat_client,
+ int8_t* require_min_compat_client)
+{
+ return client->get_min_compatible_client(min_compat_client,
+ require_min_compat_client);
+}
+
+int librados::Rados::conf_read_file(const char * const path) const
+{
+ return rados_conf_read_file((rados_t)client, path);
+}
+
+int librados::Rados::conf_parse_argv(int argc, const char ** argv) const
+{
+ return rados_conf_parse_argv((rados_t)client, argc, argv);
+}
+
+int librados::Rados::conf_parse_argv_remainder(int argc, const char ** argv,
+ const char ** remargv) const
+{
+ return rados_conf_parse_argv_remainder((rados_t)client, argc, argv, remargv);
+}
+
+int librados::Rados::conf_parse_env(const char *name) const
+{
+ return rados_conf_parse_env((rados_t)client, name);
+}
+
+int librados::Rados::conf_set(const char *option, const char *value)
+{
+ return rados_conf_set((rados_t)client, option, value);
+}
+
+int librados::Rados::conf_get(const char *option, std::string &val)
+{
+ char *str = NULL;
+ const auto& conf = client->cct->_conf;
+ int ret = conf.get_val(option, &str, -1);
+ if (ret) {
+ free(str);
+ return ret;
+ }
+ val = str;
+ free(str);
+ return 0;
+}
+
+int librados::Rados::service_daemon_register(
+ const std::string& service, ///< service name (e.g., 'rgw')
+ const std::string& name, ///< daemon name (e.g., 'gwfoo')
+ const std::map<std::string,std::string>& metadata) ///< static metadata about daemon
+{
+ return client->service_daemon_register(service, name, metadata);
+}
+
+int librados::Rados::service_daemon_update_status(
+ std::map<std::string,std::string>&& status)
+{
+ return client->service_daemon_update_status(std::move(status));
+}
+
+int librados::Rados::pool_create(const char *name)
+{
+ string str(name);
+ return client->pool_create(str);
+}
+
+int librados::Rados::pool_create(const char *name, uint64_t auid)
+{
+ if (auid != CEPH_AUTH_UID_DEFAULT) {
+ return -EINVAL;
+ }
+ string str(name);
+ return client->pool_create(str);
+}
+
+int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule)
+{
+ if (auid != CEPH_AUTH_UID_DEFAULT) {
+ return -EINVAL;
+ }
+ string str(name);
+ return client->pool_create(str, crush_rule);
+}
+
+int librados::Rados::pool_create_with_rule(const char *name, __u8 crush_rule)
+{
+ string str(name);
+ return client->pool_create(str, crush_rule);
+}
+
+int librados::Rados::pool_create_async(const char *name, PoolAsyncCompletion *c)
+{
+ string str(name);
+ return client->pool_create_async(str, c->pc);
+}
+
+int librados::Rados::pool_create_async(const char *name, uint64_t auid, PoolAsyncCompletion *c)
+{
+ if (auid != CEPH_AUTH_UID_DEFAULT) {
+ return -EINVAL;
+ }
+ string str(name);
+ return client->pool_create_async(str, c->pc);
+}
+
+int librados::Rados::pool_create_async(const char *name, uint64_t auid, __u8 crush_rule,
+ PoolAsyncCompletion *c)
+{
+ if (auid != CEPH_AUTH_UID_DEFAULT) {
+ return -EINVAL;
+ }
+ string str(name);
+ return client->pool_create_async(str, c->pc, crush_rule);
+}
+
+int librados::Rados::pool_create_with_rule_async(
+ const char *name, __u8 crush_rule,
+ PoolAsyncCompletion *c)
+{
+ string str(name);
+ return client->pool_create_async(str, c->pc, crush_rule);
+}
+
+int librados::Rados::pool_get_base_tier(int64_t pool_id, int64_t* base_tier)
+{
+ tracepoint(librados, rados_pool_get_base_tier_enter, (rados_t)client, pool_id);
+ int retval = client->pool_get_base_tier(pool_id, base_tier);
+ tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
+ return retval;
+}
+
+int librados::Rados::pool_delete(const char *name)
+{
+ return client->pool_delete(name);
+}
+
+int librados::Rados::pool_delete_async(const char *name, PoolAsyncCompletion *c)
+{
+ return client->pool_delete_async(name, c->pc);
+}
+
+int librados::Rados::pool_list(std::list<std::string>& v)
+{
+ std::list<std::pair<int64_t, std::string> > pools;
+ int r = client->pool_list(pools);
+ if (r < 0) {
+ return r;
+ }
+
+ v.clear();
+ for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin();
+ it != pools.end(); ++it) {
+ v.push_back(it->second);
+ }
+ return 0;
+}
+
+int librados::Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v)
+{
+ return client->pool_list(v);
+}
+
+int64_t librados::Rados::pool_lookup(const char *name)
+{
+ return client->lookup_pool(name);
+}
+
+int librados::Rados::pool_reverse_lookup(int64_t id, std::string *name)
+{
+ return client->pool_get_name(id, name, true);
+}
+
+int librados::Rados::mon_command(string cmd, const bufferlist& inbl,
+ bufferlist *outbl, string *outs)
+{
+ vector<string> cmdvec;
+ cmdvec.push_back(cmd);
+ return client->mon_command(cmdvec, inbl, outbl, outs);
+}
+
+int librados::Rados::osd_command(int osdid, std::string cmd, const bufferlist& inbl,
+ bufferlist *outbl, std::string *outs)
+{
+ vector<string> cmdvec;
+ cmdvec.push_back(cmd);
+ return client->osd_command(osdid, cmdvec, inbl, outbl, outs);
+}
+
+int librados::Rados::mgr_command(std::string cmd, const bufferlist& inbl,
+ bufferlist *outbl, std::string *outs)
+{
+ vector<string> cmdvec;
+ cmdvec.push_back(cmd);
+ return client->mgr_command(cmdvec, inbl, outbl, outs);
+}
+
+
+
+int librados::Rados::pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
+ bufferlist *outbl, std::string *outs)
+{
+ vector<string> cmdvec;
+ cmdvec.push_back(cmd);
+
+ pg_t pgid;
+ if (!pgid.parse(pgstr))
+ return -EINVAL;
+
+ return client->pg_command(pgid, cmdvec, inbl, outbl, outs);
+}
+
+int librados::Rados::ioctx_create(const char *name, IoCtx &io)
+{
+ rados_ioctx_t p;
+ int ret = rados_ioctx_create((rados_t)client, name, &p);
+ if (ret)
+ return ret;
+ io.close();
+ io.io_ctx_impl = (IoCtxImpl*)p;
+ return 0;
+}
+
+int librados::Rados::ioctx_create2(int64_t pool_id, IoCtx &io)
+{
+ rados_ioctx_t p;
+ int ret = rados_ioctx_create2((rados_t)client, pool_id, &p);
+ if (ret)
+ return ret;
+ io.close();
+ io.io_ctx_impl = (IoCtxImpl*)p;
+ return 0;
+}
+
+void librados::Rados::test_blocklist_self(bool set)
+{
+ client->blocklist_self(set);
+}
+
+int librados::Rados::get_pool_stats(std::list<string>& v,
+ stats_map& result)
+{
+ map<string,::pool_stat_t> rawresult;
+ bool per_pool = false;
+ int r = client->get_pool_stats(v, &rawresult, &per_pool);
+ for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
+ p != rawresult.end();
+ ++p) {
+ pool_stat_t& pv = result[p->first];
+ auto& pstat = p->second;
+ store_statfs_t &statfs = pstat.store_stats;
+ uint64_t allocated_bytes = pstat.get_allocated_data_bytes(per_pool) +
+ pstat.get_allocated_omap_bytes(per_pool);
+ // FIXME: raw_used_rate is unknown hence use 1.0 here
+ // meaning we keep net amount aggregated over all replicas
+ // Not a big deal so far since this field isn't exposed
+ uint64_t user_bytes = pstat.get_user_data_bytes(1.0, per_pool) +
+ pstat.get_user_omap_bytes(1.0, per_pool);
+
+ object_stat_sum_t *sum = &p->second.stats.sum;
+ pv.num_kb = shift_round_up(allocated_bytes, 10);
+ pv.num_bytes = allocated_bytes;
+ pv.num_objects = sum->num_objects;
+ pv.num_object_clones = sum->num_object_clones;
+ pv.num_object_copies = sum->num_object_copies;
+ pv.num_objects_missing_on_primary = sum->num_objects_missing_on_primary;
+ pv.num_objects_unfound = sum->num_objects_unfound;
+ pv.num_objects_degraded = sum->num_objects_degraded;
+ pv.num_rd = sum->num_rd;
+ pv.num_rd_kb = sum->num_rd_kb;
+ pv.num_wr = sum->num_wr;
+ pv.num_wr_kb = sum->num_wr_kb;
+ pv.num_user_bytes = user_bytes;
+ pv.compressed_bytes_orig = statfs.data_compressed_original;
+ pv.compressed_bytes = statfs.data_compressed;
+ pv.compressed_bytes_alloc = statfs.data_compressed_allocated;
+ }
+ return r;
+}
+
+int librados::Rados::get_pool_stats(std::list<string>& v,
+ std::map<string, stats_map>& result)
+{
+ stats_map m;
+ int r = get_pool_stats(v, m);
+ if (r < 0)
+ return r;
+ for (map<string,pool_stat_t>::iterator p = m.begin();
+ p != m.end();
+ ++p) {
+ result[p->first][string()] = p->second;
+ }
+ return r;
+}
+
+int librados::Rados::get_pool_stats(std::list<string>& v,
+ string& category, // unused
+ std::map<string, stats_map>& result)
+{
+ return -EOPNOTSUPP;
+}
+
+bool librados::Rados::get_pool_is_selfmanaged_snaps_mode(const std::string& pool)
+{
+ return client->get_pool_is_selfmanaged_snaps_mode(pool);
+}
+
+int librados::Rados::cluster_stat(cluster_stat_t& result)
+{
+ ceph_statfs stats;
+ int r = client->get_fs_stats(stats);
+ result.kb = stats.kb;
+ result.kb_used = stats.kb_used;
+ result.kb_avail = stats.kb_avail;
+ result.num_objects = stats.num_objects;
+ return r;
+}
+
+int librados::Rados::cluster_fsid(string *fsid)
+{
+ return client->get_fsid(fsid);
+}
+
+namespace librados {
+ struct PlacementGroupImpl {
+ pg_t pgid;
+ };
+
+ PlacementGroup::PlacementGroup()
+ : impl{new PlacementGroupImpl}
+ {}
+
+ PlacementGroup::PlacementGroup(const PlacementGroup& pg)
+ : impl{new PlacementGroupImpl}
+ {
+ impl->pgid = pg.impl->pgid;
+ }
+
+ PlacementGroup::~PlacementGroup()
+ {}
+
+ bool PlacementGroup::parse(const char* s)
+ {
+ return impl->pgid.parse(s);
+ }
+}
+
+std::ostream& librados::operator<<(std::ostream& out,
+ const librados::PlacementGroup& pg)
+{
+ return out << pg.impl->pgid;
+}
+
+int librados::Rados::get_inconsistent_pgs(int64_t pool_id,
+ std::vector<PlacementGroup>* pgs)
+{
+ std::vector<string> pgids;
+ if (auto ret = client->get_inconsistent_pgs(pool_id, &pgids); ret) {
+ return ret;
+ }
+ for (const auto& pgid : pgids) {
+ librados::PlacementGroup pg;
+ if (!pg.parse(pgid.c_str())) {
+ return -EINVAL;
+ }
+ pgs->emplace_back(pg);
+ }
+ return 0;
+}
+
+int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
+ const object_id_t &start_after,
+ unsigned max_return,
+ AioCompletion *c,
+ std::vector<inconsistent_obj_t>* objects,
+ uint32_t* interval)
+{
+ IoCtx ioctx;
+ const pg_t pgid = pg.impl->pgid;
+ int r = ioctx_create2(pgid.pool(), ioctx);
+ if (r < 0) {
+ return r;
+ }
+
+ return ioctx.io_ctx_impl->get_inconsistent_objects(pgid,
+ start_after,
+ max_return,
+ c->pc,
+ objects,
+ interval);
+}
+
+int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
+ const object_id_t &start_after,
+ unsigned max_return,
+ AioCompletion *c,
+ std::vector<inconsistent_snapset_t>* snapsets,
+ uint32_t* interval)
+{
+ IoCtx ioctx;
+ const pg_t pgid = pg.impl->pgid;
+ int r = ioctx_create2(pgid.pool(), ioctx);
+ if (r < 0) {
+ return r;
+ }
+
+ return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
+ start_after,
+ max_return,
+ c->pc,
+ snapsets,
+ interval);
+}
+
+int librados::Rados::wait_for_latest_osdmap()
+{
+ return client->wait_for_latest_osdmap();
+}
+
+int librados::Rados::blocklist_add(const std::string& client_address,
+ uint32_t expire_seconds)
+{
+ return client->blocklist_add(client_address, expire_seconds);
+}
+
+std::string librados::Rados::get_addrs() const {
+ return client->get_addrs();
+}
+
+librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
+{
+ PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
+ return new PoolAsyncCompletion(c);
+}
+
+librados::AioCompletion *librados::Rados::aio_create_completion()
+{
+ AioCompletionImpl *c = new AioCompletionImpl;
+ return new AioCompletion(c);
+}
+
+librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
+ callback_t cb_complete,
+ callback_t cb_safe)
+{
+ AioCompletionImpl *c;
+ int r = rados_aio_create_completion(cb_arg, cb_complete, cb_safe, (void**)&c);
+ ceph_assert(r == 0);
+ return new AioCompletion(c);
+}
+
+librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
+ callback_t cb_complete)
+{
+ AioCompletionImpl *c;
+ int r = rados_aio_create_completion2(cb_arg, cb_complete, (void**)&c);
+ ceph_assert(r == 0);
+ return new AioCompletion(c);
+}
+
+librados::ObjectOperation::ObjectOperation() : impl(new ObjectOperationImpl) {}
+
+librados::ObjectOperation::ObjectOperation(ObjectOperation&& rhs)
+ : impl(rhs.impl) {
+ rhs.impl = nullptr;
+}
+
+librados::ObjectOperation&
+librados::ObjectOperation::operator =(ObjectOperation&& rhs) {
+ delete impl;
+ impl = rhs.impl;
+ rhs.impl = nullptr;
+ return *this;
+}
+
+librados::ObjectOperation::~ObjectOperation() {
+ delete impl;
+}
+
+///////////////////////////// ListObject //////////////////////////////
+librados::ListObject::ListObject() : impl(NULL)
+{
+}
+
+librados::ListObject::ListObject(librados::ListObjectImpl *i): impl(i)
+{
+}
+
+librados::ListObject::ListObject(const ListObject& rhs)
+{
+ if (rhs.impl == NULL) {
+ impl = NULL;
+ return;
+ }
+ impl = new ListObjectImpl();
+ *impl = *(rhs.impl);
+}
+
+librados::ListObject& librados::ListObject::operator=(const ListObject& rhs)
+{
+ if (rhs.impl == NULL) {
+ delete impl;
+ impl = NULL;
+ return *this;
+ }
+ if (impl == NULL)
+ impl = new ListObjectImpl();
+ *impl = *(rhs.impl);
+ return *this;
+}
+
+librados::ListObject::~ListObject()
+{
+ if (impl)
+ delete impl;
+ impl = NULL;
+}
+
+const std::string& librados::ListObject::get_nspace() const
+{
+ return impl->get_nspace();
+}
+
+const std::string& librados::ListObject::get_oid() const
+{
+ return impl->get_oid();
+}
+
+const std::string& librados::ListObject::get_locator() const
+{
+ return impl->get_locator();
+}
+
+std::ostream& librados::operator<<(std::ostream& out, const librados::ListObject& lop)
+{
+ out << *(lop.impl);
+ return out;
+}
+
+librados::ObjectCursor::ObjectCursor()
+{
+ c_cursor = (rados_object_list_cursor)new hobject_t();
+}
+
+librados::ObjectCursor::~ObjectCursor()
+{
+ hobject_t *h = (hobject_t *)c_cursor;
+ delete h;
+}
+
+librados::ObjectCursor::ObjectCursor(rados_object_list_cursor c)
+{
+ if (!c) {
+ c_cursor = nullptr;
+ } else {
+ c_cursor = (rados_object_list_cursor)new hobject_t(*(hobject_t *)c);
+ }
+}
+
+librados::ObjectCursor& librados::ObjectCursor::operator=(const librados::ObjectCursor& rhs)
+{
+ if (rhs.c_cursor != nullptr) {
+ hobject_t *h = (hobject_t*)rhs.c_cursor;
+ c_cursor = (rados_object_list_cursor)(new hobject_t(*h));
+ } else {
+ c_cursor = nullptr;
+ }
+ return *this;
+}
+
+bool librados::ObjectCursor::operator<(const librados::ObjectCursor &rhs) const
+{
+ const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
+ const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
+ return lhs_hobj < rhs_hobj;
+}
+
+bool librados::ObjectCursor::operator==(const librados::ObjectCursor &rhs) const
+{
+ const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
+ const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
+ return cmp(lhs_hobj, rhs_hobj) == 0;
+}
+librados::ObjectCursor::ObjectCursor(const librados::ObjectCursor &rhs)
+{
+ *this = rhs;
+}
+
+librados::ObjectCursor librados::IoCtx::object_list_begin()
+{
+ hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_begin());
+ ObjectCursor oc;
+ oc.set((rados_object_list_cursor)h);
+ return oc;
+}
+
+
+librados::ObjectCursor librados::IoCtx::object_list_end()
+{
+ hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_end());
+ librados::ObjectCursor oc;
+ oc.set((rados_object_list_cursor)h);
+ return oc;
+}
+
+
+void librados::ObjectCursor::set(rados_object_list_cursor c)
+{
+ delete (hobject_t*)c_cursor;
+ c_cursor = c;
+}
+
+string librados::ObjectCursor::to_str() const
+{
+ stringstream ss;
+ ss << *(hobject_t *)c_cursor;
+ return ss.str();
+}
+
+bool librados::ObjectCursor::from_str(const string& s)
+{
+ if (s.empty()) {
+ *(hobject_t *)c_cursor = hobject_t();
+ return true;
+ }
+ return ((hobject_t *)c_cursor)->parse(s);
+}
+
+CEPH_RADOS_API std::ostream& librados::operator<<(std::ostream& os, const librados::ObjectCursor& oc)
+{
+ if (oc.c_cursor) {
+ os << *(hobject_t *)oc.c_cursor;
+ } else {
+ os << hobject_t();
+ }
+ return os;
+}
+
+bool librados::IoCtx::object_list_is_end(const ObjectCursor &oc)
+{
+ hobject_t *h = (hobject_t *)oc.c_cursor;
+ return h->is_max();
+}
+
+int librados::IoCtx::object_list(const ObjectCursor &start,
+ const ObjectCursor &finish,
+ const size_t result_item_count,
+ const bufferlist &filter,
+ std::vector<ObjectItem> *result,
+ ObjectCursor *next)
+{
+ ceph_assert(result != nullptr);
+ ceph_assert(next != nullptr);
+ result->clear();
+
+ ceph::async::waiter<boost::system::error_code,
+ std::vector<librados::ListObjectImpl>,
+ hobject_t> w;
+ io_ctx_impl->objecter->enumerate_objects<librados::ListObjectImpl>(
+ io_ctx_impl->poolid,
+ io_ctx_impl->oloc.nspace,
+ *((hobject_t*)start.c_cursor),
+ *((hobject_t*)finish.c_cursor),
+ result_item_count,
+ filter,
+ w);
+
+ auto [ec, obj_result, next_hash] = w.wait();
+ if (ec) {
+ next->set((rados_object_list_cursor)(new hobject_t(hobject_t::get_max())));
+ return ceph::from_error_code(ec);
+ }
+
+ next->set((rados_object_list_cursor)(new hobject_t(next_hash)));
+
+ for (auto i = obj_result.begin();
+ i != obj_result.end(); ++i) {
+ ObjectItem oi;
+ oi.oid = i->oid;
+ oi.nspace = i->nspace;
+ oi.locator = i->locator;
+ result->push_back(oi);
+ }
+
+ return obj_result.size();
+}
+
+void librados::IoCtx::object_list_slice(
+ const ObjectCursor start,
+ const ObjectCursor finish,
+ const size_t n,
+ const size_t m,
+ ObjectCursor *split_start,
+ ObjectCursor *split_finish)
+{
+ ceph_assert(split_start != nullptr);
+ ceph_assert(split_finish != nullptr);
+
+ io_ctx_impl->object_list_slice(
+ *((hobject_t*)(start.c_cursor)),
+ *((hobject_t*)(finish.c_cursor)),
+ n,
+ m,
+ (hobject_t*)(split_start->c_cursor),
+ (hobject_t*)(split_finish->c_cursor));
+}
+
+int librados::IoCtx::application_enable(const std::string& app_name,
+ bool force)
+{
+ return io_ctx_impl->application_enable(app_name, force);
+}
+
+int librados::IoCtx::application_enable_async(const std::string& app_name,
+ bool force,
+ PoolAsyncCompletion *c)
+{
+ io_ctx_impl->application_enable_async(app_name, force, c->pc);
+ return 0;
+}
+
+int librados::IoCtx::application_list(std::set<std::string> *app_names)
+{
+ return io_ctx_impl->application_list(app_names);
+}
+
+int librados::IoCtx::application_metadata_get(const std::string& app_name,
+ const std::string &key,
+ std::string* value)
+{
+ return io_ctx_impl->application_metadata_get(app_name, key, value);
+}
+
+int librados::IoCtx::application_metadata_set(const std::string& app_name,
+ const std::string &key,
+ const std::string& value)
+{
+ return io_ctx_impl->application_metadata_set(app_name, key, value);
+}
+
+int librados::IoCtx::application_metadata_remove(const std::string& app_name,
+ const std::string &key)
+{
+ return io_ctx_impl->application_metadata_remove(app_name, key);
+}
+
+int librados::IoCtx::application_metadata_list(const std::string& app_name,
+ std::map<std::string, std::string> *values)
+{
+ return io_ctx_impl->application_metadata_list(app_name, values);
+}