]> git.proxmox.com Git - ceph.git/blame - ceph/src/librados/librados_cxx.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / librados / librados_cxx.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2012 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include <limits.h>
16
17#include "common/config.h"
18#include "common/errno.h"
19#include "common/ceph_argparse.h"
20#include "common/ceph_json.h"
21#include "common/common_init.h"
22#include "common/TracepointProvider.h"
23#include "common/hobject.h"
24#include "include/rados/librados.h"
25#include "include/rados/librados.hpp"
26#include "include/types.h"
27#include <include/stringify.h>
28
29#include "librados/AioCompletionImpl.h"
30#include "librados/IoCtxImpl.h"
31#include "librados/PoolAsyncCompletionImpl.h"
32#include "librados/RadosClient.h"
33#include "librados/RadosXattrIter.h"
34#include "librados/ListObjectImpl.h"
35#include "librados/librados_util.h"
36#include "cls/lock/cls_lock_client.h"
37
38#include <string>
39#include <map>
40#include <set>
41#include <vector>
42#include <list>
43#include <stdexcept>
44#include <system_error>
45
46#ifdef WITH_LTTNG
47#define TRACEPOINT_DEFINE
48#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
49#include "tracing/librados.h"
50#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
51#undef TRACEPOINT_DEFINE
52#else
53#define tracepoint(...)
54#endif
55
56using std::string;
57using std::map;
58using std::set;
59using std::vector;
60using std::list;
61
62#define dout_subsys ceph_subsys_rados
63#undef dout_prefix
64#define dout_prefix *_dout << "librados: "
65
66static TracepointProvider::Traits tracepoint_traits("librados_tp.so", "rados_tracing");
67
68/*
69 * Structure of this file
70 *
71 * RadosClient and the related classes are the internal implementation of librados.
72 * Above that layer sits the C API, found in include/rados/librados.h, and
73 * the C++ API, found in include/rados/librados.hpp
74 *
75 * The C++ API sometimes implements things in terms of the C API.
76 * Both the C++ and C API rely on RadosClient.
77 *
78 * Visually:
79 * +--------------------------------------+
80 * | C++ API |
81 * +--------------------+ |
82 * | C API | |
83 * +--------------------+-----------------+
84 * | RadosClient |
85 * +--------------------------------------+
86 */
87
88namespace librados {
89
90struct ObjectOperationImpl {
91 ::ObjectOperation o;
92 real_time rt;
93 real_time *prt;
94
95 ObjectOperationImpl() : prt(NULL) {}
96};
97
98}
99
100size_t librados::ObjectOperation::size()
101{
102 ::ObjectOperation *o = &impl->o;
103 return o->size();
104}
105
106//deprcated
107void librados::ObjectOperation::set_op_flags(ObjectOperationFlags flags)
108{
109 set_op_flags2((int)flags);
110}
111
112void librados::ObjectOperation::set_op_flags2(int flags)
113{
114 impl->o.set_last_op_flags(get_op_flags(flags));
115}
116
117void librados::ObjectOperation::cmpext(uint64_t off,
118 const bufferlist &cmp_bl,
119 int *prval)
120{
121 ::ObjectOperation *o = &impl->o;
122 bufferlist c = cmp_bl;
123 o->cmpext(off, c, prval);
124}
125
126void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, const bufferlist& v)
127{
128 ::ObjectOperation *o = &impl->o;
129 o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_STRING, v);
130}
131
132void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, uint64_t v)
133{
134 ::ObjectOperation *o = &impl->o;
135 bufferlist bl;
136 encode(v, bl);
137 o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_U64, bl);
138}
139
140void librados::ObjectOperation::assert_version(uint64_t ver)
141{
142 ::ObjectOperation *o = &impl->o;
143 o->assert_version(ver);
144}
145
146void librados::ObjectOperation::assert_exists()
147{
148 ::ObjectOperation *o = &impl->o;
149 o->stat(NULL, (ceph::real_time*) NULL, NULL);
150}
151
152void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl)
153{
154 ::ObjectOperation *o = &impl->o;
155 o->call(cls, method, inbl);
156}
157
158void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, bufferlist *outbl, int *prval)
159{
160 ::ObjectOperation *o = &impl->o;
161 o->call(cls, method, inbl, outbl, NULL, prval);
162}
163
164class ObjectOpCompletionCtx : public Context {
165 librados::ObjectOperationCompletion *completion;
166 bufferlist bl;
167public:
168 explicit ObjectOpCompletionCtx(librados::ObjectOperationCompletion *c) : completion(c) {}
169 void finish(int r) override {
170 completion->handle_completion(r, bl);
171 delete completion;
172 }
173
174 bufferlist *outbl() {
175 return &bl;
176 }
177};
178
179void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, librados::ObjectOperationCompletion *completion)
180{
181 ::ObjectOperation *o = &impl->o;
182
183 ObjectOpCompletionCtx *ctx = new ObjectOpCompletionCtx(completion);
184
185 o->call(cls, method, inbl, ctx->outbl(), ctx, NULL);
186}
187
188void librados::ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval)
189{
190 ::ObjectOperation *o = &impl->o;
191 o->stat(psize, pmtime, prval);
192}
193
194void librados::ObjectReadOperation::stat2(uint64_t *psize, struct timespec *pts, int *prval)
195{
196 ::ObjectOperation *o = &impl->o;
197 o->stat(psize, pts, prval);
198}
199
200void librados::ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl, int *prval)
201{
202 ::ObjectOperation *o = &impl->o;
203 o->read(off, len, pbl, prval, NULL);
204}
205
206void librados::ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
207 std::map<uint64_t,uint64_t> *m,
208 bufferlist *data_bl, int *prval)
209{
210 ::ObjectOperation *o = &impl->o;
211 o->sparse_read(off, len, m, data_bl, prval);
212}
213
214void librados::ObjectReadOperation::checksum(rados_checksum_type_t type,
215 const bufferlist &init_value_bl,
216 uint64_t off, size_t len,
217 size_t chunk_size, bufferlist *pbl,
218 int *prval)
219{
220 ::ObjectOperation *o = &impl->o;
221 o->checksum(get_checksum_op_type(type), init_value_bl, off, len, chunk_size,
222 pbl, prval, nullptr);
223}
224
225void librados::ObjectReadOperation::getxattr(const char *name, bufferlist *pbl, int *prval)
226{
227 ::ObjectOperation *o = &impl->o;
228 o->getxattr(name, pbl, prval);
229}
230
231void librados::ObjectReadOperation::omap_get_vals(
232 const std::string &start_after,
233 const std::string &filter_prefix,
234 uint64_t max_return,
235 std::map<std::string, bufferlist> *out_vals,
236 int *prval)
237{
238 ::ObjectOperation *o = &impl->o;
239 o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, nullptr,
240 prval);
241}
242
243void librados::ObjectReadOperation::omap_get_vals2(
244 const std::string &start_after,
245 const std::string &filter_prefix,
246 uint64_t max_return,
247 std::map<std::string, bufferlist> *out_vals,
248 bool *pmore,
249 int *prval)
250{
251 ::ObjectOperation *o = &impl->o;
252 o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, pmore,
253 prval);
254}
255
256void librados::ObjectReadOperation::omap_get_vals(
257 const std::string &start_after,
258 uint64_t max_return,
259 std::map<std::string, bufferlist> *out_vals,
260 int *prval)
261{
262 ::ObjectOperation *o = &impl->o;
263 o->omap_get_vals(start_after, "", max_return, out_vals, nullptr, prval);
264}
265
266void librados::ObjectReadOperation::omap_get_vals2(
267 const std::string &start_after,
268 uint64_t max_return,
269 std::map<std::string, bufferlist> *out_vals,
270 bool *pmore,
271 int *prval)
272{
273 ::ObjectOperation *o = &impl->o;
274 o->omap_get_vals(start_after, "", max_return, out_vals, pmore, prval);
275}
276
277void librados::ObjectReadOperation::omap_get_keys(
278 const std::string &start_after,
279 uint64_t max_return,
280 std::set<std::string> *out_keys,
281 int *prval)
282{
283 ::ObjectOperation *o = &impl->o;
284 o->omap_get_keys(start_after, max_return, out_keys, nullptr, prval);
285}
286
287void librados::ObjectReadOperation::omap_get_keys2(
288 const std::string &start_after,
289 uint64_t max_return,
290 std::set<std::string> *out_keys,
291 bool *pmore,
292 int *prval)
293{
294 ::ObjectOperation *o = &impl->o;
295 o->omap_get_keys(start_after, max_return, out_keys, pmore, prval);
296}
297
298void librados::ObjectReadOperation::omap_get_header(bufferlist *bl, int *prval)
299{
300 ::ObjectOperation *o = &impl->o;
301 o->omap_get_header(bl, prval);
302}
303
304void librados::ObjectReadOperation::omap_get_vals_by_keys(
305 const std::set<std::string> &keys,
306 std::map<std::string, bufferlist> *map,
307 int *prval)
308{
309 ::ObjectOperation *o = &impl->o;
310 o->omap_get_vals_by_keys(keys, map, prval);
311}
312
313void librados::ObjectOperation::omap_cmp(
314 const std::map<std::string, pair<bufferlist, int> > &assertions,
315 int *prval)
316{
317 ::ObjectOperation *o = &impl->o;
318 o->omap_cmp(assertions, prval);
319}
320
321void librados::ObjectReadOperation::list_watchers(
322 list<obj_watch_t> *out_watchers,
323 int *prval)
324{
325 ::ObjectOperation *o = &impl->o;
326 o->list_watchers(out_watchers, prval);
327}
328
329void librados::ObjectReadOperation::list_snaps(
330 snap_set_t *out_snaps,
331 int *prval)
332{
333 ::ObjectOperation *o = &impl->o;
334 o->list_snaps(out_snaps, prval);
335}
336
337void librados::ObjectReadOperation::is_dirty(bool *is_dirty, int *prval)
338{
339 ::ObjectOperation *o = &impl->o;
340 o->is_dirty(is_dirty, prval);
341}
342
343int librados::IoCtx::omap_get_vals(const std::string& oid,
344 const std::string& orig_start_after,
345 const std::string& filter_prefix,
346 uint64_t max_return,
347 std::map<std::string, bufferlist> *out_vals)
348{
349 bool first = true;
350 string start_after = orig_start_after;
351 bool more = true;
352 while (max_return > 0 && more) {
353 std::map<std::string,bufferlist> out;
354 ObjectReadOperation op;
355 op.omap_get_vals2(start_after, filter_prefix, max_return, &out, &more,
356 nullptr);
357 bufferlist bl;
358 int ret = operate(oid, &op, &bl);
359 if (ret < 0) {
360 return ret;
361 }
362 if (more) {
363 if (out.empty()) {
364 return -EINVAL; // wth
365 }
366 start_after = out.rbegin()->first;
367 }
368 if (out.size() <= max_return) {
369 max_return -= out.size();
370 } else {
371 max_return = 0;
372 }
373 if (first) {
374 out_vals->swap(out);
375 first = false;
376 } else {
377 out_vals->insert(out.begin(), out.end());
378 out.clear();
379 }
380 }
381 return 0;
382}
383
384int librados::IoCtx::omap_get_vals2(
385 const std::string& oid,
386 const std::string& start_after,
387 const std::string& filter_prefix,
388 uint64_t max_return,
389 std::map<std::string, bufferlist> *out_vals,
390 bool *pmore)
391{
392 ObjectReadOperation op;
393 int r;
394 op.omap_get_vals2(start_after, filter_prefix, max_return, out_vals, pmore, &r);
395 bufferlist bl;
396 int ret = operate(oid, &op, &bl);
397 if (ret < 0)
398 return ret;
399 return r;
400}
401
402void librados::ObjectReadOperation::getxattrs(map<string, bufferlist> *pattrs, int *prval)
403{
404 ::ObjectOperation *o = &impl->o;
405 o->getxattrs(pattrs, prval);
406}
407
408void librados::ObjectWriteOperation::mtime(time_t *pt)
409{
410 if (pt) {
411 impl->rt = ceph::real_clock::from_time_t(*pt);
412 impl->prt = &impl->rt;
413 }
414}
415
416void librados::ObjectWriteOperation::mtime2(struct timespec *pts)
417{
418 if (pts) {
419 impl->rt = ceph::real_clock::from_timespec(*pts);
420 impl->prt = &impl->rt;
421 }
422}
423
424void librados::ObjectWriteOperation::create(bool exclusive)
425{
426 ::ObjectOperation *o = &impl->o;
427 o->create(exclusive);
428}
429
430void librados::ObjectWriteOperation::create(bool exclusive,
431 const std::string& category) // unused
432{
433 ::ObjectOperation *o = &impl->o;
434 o->create(exclusive);
435}
436
437void librados::ObjectWriteOperation::write(uint64_t off, const bufferlist& bl)
438{
439 ::ObjectOperation *o = &impl->o;
440 bufferlist c = bl;
441 o->write(off, c);
442}
443
444void librados::ObjectWriteOperation::write_full(const bufferlist& bl)
445{
446 ::ObjectOperation *o = &impl->o;
447 bufferlist c = bl;
448 o->write_full(c);
449}
450
451void librados::ObjectWriteOperation::writesame(uint64_t off, uint64_t write_len,
452 const bufferlist& bl)
453{
454 ::ObjectOperation *o = &impl->o;
455 bufferlist c = bl;
456 o->writesame(off, write_len, c);
457}
458
459void librados::ObjectWriteOperation::append(const bufferlist& bl)
460{
461 ::ObjectOperation *o = &impl->o;
462 bufferlist c = bl;
463 o->append(c);
464}
465
466void librados::ObjectWriteOperation::remove()
467{
468 ::ObjectOperation *o = &impl->o;
469 o->remove();
470}
471
472void librados::ObjectWriteOperation::truncate(uint64_t off)
473{
474 ::ObjectOperation *o = &impl->o;
475 o->truncate(off);
476}
477
478void librados::ObjectWriteOperation::zero(uint64_t off, uint64_t len)
479{
480 ::ObjectOperation *o = &impl->o;
481 o->zero(off, len);
482}
483
484void librados::ObjectWriteOperation::rmxattr(const char *name)
485{
486 ::ObjectOperation *o = &impl->o;
487 o->rmxattr(name);
488}
489
490void librados::ObjectWriteOperation::setxattr(const char *name, const bufferlist& v)
491{
492 ::ObjectOperation *o = &impl->o;
493 o->setxattr(name, v);
494}
495
496void librados::ObjectWriteOperation::setxattr(const char *name,
497 const buffer::list&& v)
498{
499 ::ObjectOperation *o = &impl->o;
500 o->setxattr(name, std::move(v));
501}
502
503void librados::ObjectWriteOperation::omap_set(
504 const map<string, bufferlist> &map)
505{
506 ::ObjectOperation *o = &impl->o;
507 o->omap_set(map);
508}
509
510void librados::ObjectWriteOperation::omap_set_header(const bufferlist &bl)
511{
512 bufferlist c = bl;
513 ::ObjectOperation *o = &impl->o;
514 o->omap_set_header(c);
515}
516
517void librados::ObjectWriteOperation::omap_clear()
518{
519 ::ObjectOperation *o = &impl->o;
520 o->omap_clear();
521}
522
523void librados::ObjectWriteOperation::omap_rm_keys(
524 const std::set<std::string> &to_rm)
525{
526 ::ObjectOperation *o = &impl->o;
527 o->omap_rm_keys(to_rm);
528}
529
530void librados::ObjectWriteOperation::copy_from(const std::string& src,
531 const IoCtx& src_ioctx,
532 uint64_t src_version,
533 uint32_t src_fadvise_flags)
534{
535 ::ObjectOperation *o = &impl->o;
536 o->copy_from(object_t(src), src_ioctx.io_ctx_impl->snap_seq,
537 src_ioctx.io_ctx_impl->oloc, src_version, 0, src_fadvise_flags);
538}
539
540void librados::ObjectWriteOperation::undirty()
541{
542 ::ObjectOperation *o = &impl->o;
543 o->undirty();
544}
545
546void librados::ObjectReadOperation::cache_flush()
547{
548 ::ObjectOperation *o = &impl->o;
549 o->cache_flush();
550}
551
552void librados::ObjectReadOperation::cache_try_flush()
553{
554 ::ObjectOperation *o = &impl->o;
555 o->cache_try_flush();
556}
557
558void librados::ObjectReadOperation::cache_evict()
559{
560 ::ObjectOperation *o = &impl->o;
561 o->cache_evict();
562}
563
564void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj,
565 const IoCtx& tgt_ioctx,
566 uint64_t tgt_version,
567 int flag)
568{
569 ::ObjectOperation *o = &impl->o;
570 o->set_redirect(object_t(tgt_obj), tgt_ioctx.io_ctx_impl->snap_seq,
571 tgt_ioctx.io_ctx_impl->oloc, tgt_version, flag);
572}
573
574void librados::ObjectWriteOperation::set_chunk(uint64_t src_offset,
575 uint64_t src_length,
576 const IoCtx& tgt_ioctx,
577 string tgt_oid,
578 uint64_t tgt_offset,
579 int flag)
580{
581 ::ObjectOperation *o = &impl->o;
582 o->set_chunk(src_offset, src_length,
583 tgt_ioctx.io_ctx_impl->oloc, object_t(tgt_oid), tgt_offset, flag);
584}
585
586void librados::ObjectWriteOperation::tier_promote()
587{
588 ::ObjectOperation *o = &impl->o;
589 o->tier_promote();
590}
591
592void librados::ObjectWriteOperation::unset_manifest()
593{
594 ::ObjectOperation *o = &impl->o;
595 o->unset_manifest();
596}
597
598void librados::ObjectWriteOperation::tmap_update(const bufferlist& cmdbl)
599{
600 ::ObjectOperation *o = &impl->o;
601 bufferlist c = cmdbl;
602 o->tmap_update(c);
603}
604
605void librados::ObjectWriteOperation::selfmanaged_snap_rollback(snap_t snapid)
606{
607 ::ObjectOperation *o = &impl->o;
608 o->rollback(snapid);
609}
610
611// You must specify the snapid not the name normally used with pool snapshots
612void librados::ObjectWriteOperation::snap_rollback(snap_t snapid)
613{
614 ::ObjectOperation *o = &impl->o;
615 o->rollback(snapid);
616}
617
618void librados::ObjectWriteOperation::set_alloc_hint(
619 uint64_t expected_object_size,
620 uint64_t expected_write_size)
621{
622 ::ObjectOperation *o = &impl->o;
623 o->set_alloc_hint(expected_object_size, expected_write_size, 0);
624}
625void librados::ObjectWriteOperation::set_alloc_hint2(
626 uint64_t expected_object_size,
627 uint64_t expected_write_size,
628 uint32_t flags)
629{
630 ::ObjectOperation *o = &impl->o;
631 o->set_alloc_hint(expected_object_size, expected_write_size, flags);
632}
633
634void librados::ObjectWriteOperation::cache_pin()
635{
636 ::ObjectOperation *o = &impl->o;
637 o->cache_pin();
638}
639
640void librados::ObjectWriteOperation::cache_unpin()
641{
642 ::ObjectOperation *o = &impl->o;
643 o->cache_unpin();
644}
645
646librados::WatchCtx::
647~WatchCtx()
648{
649}
650
651librados::WatchCtx2::
652~WatchCtx2()
653{
654}
655
656///////////////////////////// NObjectIteratorImpl /////////////////////////////
657librados::NObjectIteratorImpl::NObjectIteratorImpl(ObjListCtx *ctx_)
658 : ctx(ctx_)
659{
660}
661
662librados::NObjectIteratorImpl::~NObjectIteratorImpl()
663{
664 ctx.reset();
665}
666
667librados::NObjectIteratorImpl::NObjectIteratorImpl(const NObjectIteratorImpl &rhs)
668{
669 *this = rhs;
670}
671
672librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator=(const librados::NObjectIteratorImpl &rhs)
673{
674 if (&rhs == this)
675 return *this;
676 if (rhs.ctx.get() == NULL) {
677 ctx.reset();
678 return *this;
679 }
680 Objecter::NListContext *list_ctx = new Objecter::NListContext(*rhs.ctx->nlc);
681 ctx.reset(new ObjListCtx(rhs.ctx->ctx, list_ctx));
682 cur_obj = rhs.cur_obj;
683 return *this;
684}
685
686bool librados::NObjectIteratorImpl::operator==(const librados::NObjectIteratorImpl& rhs) const {
687
688 if (ctx.get() == NULL) {
689 if (rhs.ctx.get() == NULL)
690 return true;
691 return rhs.ctx->nlc->at_end();
692 }
693 if (rhs.ctx.get() == NULL) {
694 // Redundant but same as ObjectIterator version
695 if (ctx.get() == NULL)
696 return true;
697 return ctx->nlc->at_end();
698 }
699 return ctx.get() == rhs.ctx.get();
700}
701
702bool librados::NObjectIteratorImpl::operator!=(const librados::NObjectIteratorImpl& rhs) const {
703 return !(*this == rhs);
704}
705
706const librados::ListObject& librados::NObjectIteratorImpl::operator*() const {
707 return cur_obj;
708}
709
710const librados::ListObject* librados::NObjectIteratorImpl::operator->() const {
711 return &cur_obj;
712}
713
714librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator++()
715{
716 get_next();
717 return *this;
718}
719
720librados::NObjectIteratorImpl librados::NObjectIteratorImpl::operator++(int)
721{
722 librados::NObjectIteratorImpl ret(*this);
723 get_next();
724 return ret;
725}
726
727uint32_t librados::NObjectIteratorImpl::seek(uint32_t pos)
728{
729 uint32_t r = rados_nobjects_list_seek(ctx.get(), pos);
730 get_next();
731 return r;
732}
733
734uint32_t librados::NObjectIteratorImpl::seek(const ObjectCursor& cursor)
735{
736 uint32_t r = rados_nobjects_list_seek_cursor(ctx.get(), (rados_object_list_cursor)cursor.c_cursor);
737 get_next();
738 return r;
739}
740
741librados::ObjectCursor librados::NObjectIteratorImpl::get_cursor()
742{
743 librados::ObjListCtx *lh = (librados::ObjListCtx *)ctx.get();
744 librados::ObjectCursor oc;
745 oc.set(lh->ctx->nlist_get_cursor(lh->nlc));
746 return oc;
747}
748
749void librados::NObjectIteratorImpl::set_filter(const bufferlist &bl)
750{
751 ceph_assert(ctx);
752 ctx->nlc->filter = bl;
753}
754
755void librados::NObjectIteratorImpl::get_next()
756{
757 const char *entry, *key, *nspace;
758 if (ctx->nlc->at_end())
759 return;
760 int ret = rados_nobjects_list_next(ctx.get(), &entry, &key, &nspace);
761 if (ret == -ENOENT) {
762 return;
763 }
764 else if (ret) {
765 throw std::system_error(-ret, std::system_category(),
766 "rados_nobjects_list_next");
767 }
768
769 if (cur_obj.impl == NULL)
770 cur_obj.impl = new ListObjectImpl();
771 cur_obj.impl->nspace = nspace;
772 cur_obj.impl->oid = entry;
773 cur_obj.impl->locator = key ? key : string();
774}
775
776uint32_t librados::NObjectIteratorImpl::get_pg_hash_position() const
777{
778 return ctx->nlc->get_pg_hash_position();
779}
780
781///////////////////////////// NObjectIterator /////////////////////////////
782librados::NObjectIterator::NObjectIterator(ObjListCtx *ctx_)
783{
784 impl = new NObjectIteratorImpl(ctx_);
785}
786
787librados::NObjectIterator::~NObjectIterator()
788{
789 delete impl;
790}
791
792librados::NObjectIterator::NObjectIterator(const NObjectIterator &rhs)
793{
794 if (rhs.impl == NULL) {
795 impl = NULL;
796 return;
797 }
798 impl = new NObjectIteratorImpl();
799 *impl = *(rhs.impl);
800}
801
802librados::NObjectIterator& librados::NObjectIterator::operator=(const librados::NObjectIterator &rhs)
803{
804 if (rhs.impl == NULL) {
805 delete impl;
806 impl = NULL;
807 return *this;
808 }
809 if (impl == NULL)
810 impl = new NObjectIteratorImpl();
811 *impl = *(rhs.impl);
812 return *this;
813}
814
815bool librados::NObjectIterator::operator==(const librados::NObjectIterator& rhs) const
816{
817 if (impl && rhs.impl) {
818 return *impl == *(rhs.impl);
819 } else {
820 return impl == rhs.impl;
821 }
822}
823
824bool librados::NObjectIterator::operator!=(const librados::NObjectIterator& rhs) const
825{
826 return !(*this == rhs);
827}
828
829const librados::ListObject& librados::NObjectIterator::operator*() const {
830 ceph_assert(impl);
831 return *(impl->get_listobjectp());
832}
833
834const librados::ListObject* librados::NObjectIterator::operator->() const {
835 ceph_assert(impl);
836 return impl->get_listobjectp();
837}
838
839librados::NObjectIterator& librados::NObjectIterator::operator++()
840{
841 ceph_assert(impl);
842 impl->get_next();
843 return *this;
844}
845
846librados::NObjectIterator librados::NObjectIterator::operator++(int)
847{
848 librados::NObjectIterator ret(*this);
849 impl->get_next();
850 return ret;
851}
852
853uint32_t librados::NObjectIterator::seek(uint32_t pos)
854{
855 ceph_assert(impl);
856 return impl->seek(pos);
857}
858
859uint32_t librados::NObjectIterator::seek(const ObjectCursor& cursor)
860{
861 ceph_assert(impl);
862 return impl->seek(cursor);
863}
864
865librados::ObjectCursor librados::NObjectIterator::get_cursor()
866{
867 ceph_assert(impl);
868 return impl->get_cursor();
869}
870
871void librados::NObjectIterator::set_filter(const bufferlist &bl)
872{
873 impl->set_filter(bl);
874}
875
876void librados::NObjectIterator::get_next()
877{
878 ceph_assert(impl);
879 impl->get_next();
880}
881
882uint32_t librados::NObjectIterator::get_pg_hash_position() const
883{
884 ceph_assert(impl);
885 return impl->get_pg_hash_position();
886}
887
888const librados::NObjectIterator librados::NObjectIterator::__EndObjectIterator(NULL);
889
890///////////////////////////// PoolAsyncCompletion //////////////////////////////
891int librados::PoolAsyncCompletion::PoolAsyncCompletion::set_callback(void *cb_arg,
892 rados_callback_t cb)
893{
894 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
895 return c->set_callback(cb_arg, cb);
896}
897
898int librados::PoolAsyncCompletion::PoolAsyncCompletion::wait()
899{
900 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
901 return c->wait();
902}
903
904bool librados::PoolAsyncCompletion::PoolAsyncCompletion::is_complete()
905{
906 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
907 return c->is_complete();
908}
909
910int librados::PoolAsyncCompletion::PoolAsyncCompletion::get_return_value()
911{
912 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
913 return c->get_return_value();
914}
915
916void librados::PoolAsyncCompletion::PoolAsyncCompletion::release()
917{
918 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
919 c->release();
920 delete this;
921}
922
923///////////////////////////// AioCompletion //////////////////////////////
924int librados::AioCompletion::AioCompletion::set_complete_callback(void *cb_arg, rados_callback_t cb)
925{
926 AioCompletionImpl *c = (AioCompletionImpl *)pc;
927 return c->set_complete_callback(cb_arg, cb);
928}
929
930int librados::AioCompletion::AioCompletion::set_safe_callback(void *cb_arg, rados_callback_t cb)
931{
932 AioCompletionImpl *c = (AioCompletionImpl *)pc;
933 return c->set_safe_callback(cb_arg, cb);
934}
935
936int librados::AioCompletion::AioCompletion::wait_for_complete()
937{
938 AioCompletionImpl *c = (AioCompletionImpl *)pc;
939 return c->wait_for_complete();
940}
941
942int librados::AioCompletion::AioCompletion::wait_for_safe()
943{
944 AioCompletionImpl *c = (AioCompletionImpl *)pc;
945 return c->wait_for_safe();
946}
947
948bool librados::AioCompletion::AioCompletion::is_complete()
949{
950 AioCompletionImpl *c = (AioCompletionImpl *)pc;
951 return c->is_complete();
952}
953
954bool librados::AioCompletion::AioCompletion::is_safe()
955{
956 AioCompletionImpl *c = (AioCompletionImpl *)pc;
957 return c->is_safe();
958}
959
960int librados::AioCompletion::AioCompletion::wait_for_complete_and_cb()
961{
962 AioCompletionImpl *c = (AioCompletionImpl *)pc;
963 return c->wait_for_complete_and_cb();
964}
965
966int librados::AioCompletion::AioCompletion::wait_for_safe_and_cb()
967{
968 AioCompletionImpl *c = (AioCompletionImpl *)pc;
969 return c->wait_for_safe_and_cb();
970}
971
972bool librados::AioCompletion::AioCompletion::is_complete_and_cb()
973{
974 AioCompletionImpl *c = (AioCompletionImpl *)pc;
975 return c->is_complete_and_cb();
976}
977
978bool librados::AioCompletion::AioCompletion::is_safe_and_cb()
979{
980 AioCompletionImpl *c = (AioCompletionImpl *)pc;
981 return c->is_safe_and_cb();
982}
983
984int librados::AioCompletion::AioCompletion::get_return_value()
985{
986 AioCompletionImpl *c = (AioCompletionImpl *)pc;
987 return c->get_return_value();
988}
989
990int librados::AioCompletion::AioCompletion::get_version()
991{
992 AioCompletionImpl *c = (AioCompletionImpl *)pc;
993 return c->get_version();
994}
995
996uint64_t librados::AioCompletion::AioCompletion::get_version64()
997{
998 AioCompletionImpl *c = (AioCompletionImpl *)pc;
999 return c->get_version();
1000}
1001
1002void librados::AioCompletion::AioCompletion::release()
1003{
1004 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1005 c->release();
1006 delete this;
1007}
1008
1009///////////////////////////// IoCtx //////////////////////////////
1010librados::IoCtx::IoCtx() : io_ctx_impl(NULL)
1011{
1012}
1013
1014void librados::IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io)
1015{
1016 IoCtxImpl *io_ctx_impl = (IoCtxImpl*)p;
1017
1018 io.io_ctx_impl = io_ctx_impl;
1019 if (io_ctx_impl) {
1020 io_ctx_impl->get();
1021 }
1022}
1023
1024librados::IoCtx::IoCtx(const IoCtx& rhs)
1025{
1026 io_ctx_impl = rhs.io_ctx_impl;
1027 if (io_ctx_impl) {
1028 io_ctx_impl->get();
1029 }
1030}
1031
1032librados::IoCtx& librados::IoCtx::operator=(const IoCtx& rhs)
1033{
1034 if (io_ctx_impl)
1035 io_ctx_impl->put();
1036 io_ctx_impl = rhs.io_ctx_impl;
1037 io_ctx_impl->get();
1038 return *this;
1039}
1040
1041librados::IoCtx::IoCtx(IoCtx&& rhs) noexcept
1042 : io_ctx_impl(std::exchange(rhs.io_ctx_impl, nullptr))
1043{
1044}
1045
1046librados::IoCtx& librados::IoCtx::operator=(IoCtx&& rhs) noexcept
1047{
1048 if (io_ctx_impl)
1049 io_ctx_impl->put();
1050 io_ctx_impl = std::exchange(rhs.io_ctx_impl, nullptr);
1051 return *this;
1052}
1053
1054librados::IoCtx::~IoCtx()
1055{
1056 close();
1057}
1058
1059void librados::IoCtx::close()
1060{
1061 if (io_ctx_impl)
1062 io_ctx_impl->put();
1063 io_ctx_impl = 0;
1064}
1065
1066void librados::IoCtx::dup(const IoCtx& rhs)
1067{
1068 if (io_ctx_impl)
1069 io_ctx_impl->put();
1070 io_ctx_impl = new IoCtxImpl();
1071 io_ctx_impl->get();
1072 io_ctx_impl->dup(*rhs.io_ctx_impl);
1073}
1074
1075int librados::IoCtx::set_auid(uint64_t auid_)
1076{
1077 return -EOPNOTSUPP;
1078}
1079
1080int librados::IoCtx::set_auid_async(uint64_t auid_, PoolAsyncCompletion *c)
1081{
1082 return -EOPNOTSUPP;
1083}
1084
1085int librados::IoCtx::get_auid(uint64_t *auid_)
1086{
1087 return -EOPNOTSUPP;
1088}
1089
1090bool librados::IoCtx::pool_requires_alignment()
1091{
1092 return io_ctx_impl->client->pool_requires_alignment(get_id());
1093}
1094
1095int librados::IoCtx::pool_requires_alignment2(bool *requires)
1096{
1097 return io_ctx_impl->client->pool_requires_alignment2(get_id(), requires);
1098}
1099
1100uint64_t librados::IoCtx::pool_required_alignment()
1101{
1102 return io_ctx_impl->client->pool_required_alignment(get_id());
1103}
1104
1105int librados::IoCtx::pool_required_alignment2(uint64_t *alignment)
1106{
1107 return io_ctx_impl->client->pool_required_alignment2(get_id(), alignment);
1108}
1109
1110std::string librados::IoCtx::get_pool_name()
1111{
1112 std::string s;
1113 io_ctx_impl->client->pool_get_name(get_id(), &s);
1114 return s;
1115}
1116
1117std::string librados::IoCtx::get_pool_name() const
1118{
1119 return io_ctx_impl->get_cached_pool_name();
1120}
1121
1122uint64_t librados::IoCtx::get_instance_id() const
1123{
1124 return io_ctx_impl->client->get_instance_id();
1125}
1126
1127int librados::IoCtx::create(const std::string& oid, bool exclusive)
1128{
1129 object_t obj(oid);
1130 return io_ctx_impl->create(obj, exclusive);
1131}
1132
1133int librados::IoCtx::create(const std::string& oid, bool exclusive,
1134 const std::string& category) // unused
1135{
1136 object_t obj(oid);
1137 return io_ctx_impl->create(obj, exclusive);
1138}
1139
1140int librados::IoCtx::write(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1141{
1142 object_t obj(oid);
1143 return io_ctx_impl->write(obj, bl, len, off);
1144}
1145
1146int librados::IoCtx::append(const std::string& oid, bufferlist& bl, size_t len)
1147{
1148 object_t obj(oid);
1149 return io_ctx_impl->append(obj, bl, len);
1150}
1151
1152int librados::IoCtx::write_full(const std::string& oid, bufferlist& bl)
1153{
1154 object_t obj(oid);
1155 return io_ctx_impl->write_full(obj, bl);
1156}
1157
1158int librados::IoCtx::writesame(const std::string& oid, bufferlist& bl,
1159 size_t write_len, uint64_t off)
1160{
1161 object_t obj(oid);
1162 return io_ctx_impl->writesame(obj, bl, write_len, off);
1163}
1164
1165
1166int librados::IoCtx::read(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1167{
1168 object_t obj(oid);
1169 return io_ctx_impl->read(obj, bl, len, off);
1170}
1171
1172int librados::IoCtx::checksum(const std::string& oid,
1173 rados_checksum_type_t type,
1174 const bufferlist &init_value_bl, size_t len,
1175 uint64_t off, size_t chunk_size, bufferlist *pbl)
1176{
1177 object_t obj(oid);
1178 return io_ctx_impl->checksum(obj, get_checksum_op_type(type), init_value_bl,
1179 len, off, chunk_size, pbl);
1180}
1181
1182int librados::IoCtx::remove(const std::string& oid)
1183{
1184 object_t obj(oid);
1185 return io_ctx_impl->remove(obj);
1186}
1187
1188int librados::IoCtx::remove(const std::string& oid, int flags)
1189{
1190 object_t obj(oid);
1191 return io_ctx_impl->remove(obj, flags);
1192}
1193
1194int librados::IoCtx::trunc(const std::string& oid, uint64_t size)
1195{
1196 object_t obj(oid);
1197 return io_ctx_impl->trunc(obj, size);
1198}
1199
1200int librados::IoCtx::mapext(const std::string& oid, uint64_t off, size_t len,
1201 std::map<uint64_t,uint64_t>& m)
1202{
1203 object_t obj(oid);
1204 return io_ctx_impl->mapext(obj, off, len, m);
1205}
1206
1207int librados::IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl)
1208{
1209 object_t obj(oid);
1210 return io_ctx_impl->cmpext(obj, off, cmp_bl);
1211}
1212
1213int librados::IoCtx::sparse_read(const std::string& oid, std::map<uint64_t,uint64_t>& m,
1214 bufferlist& bl, size_t len, uint64_t off)
1215{
1216 object_t obj(oid);
1217 return io_ctx_impl->sparse_read(obj, m, bl, len, off);
1218}
1219
1220int librados::IoCtx::getxattr(const std::string& oid, const char *name, bufferlist& bl)
1221{
1222 object_t obj(oid);
1223 return io_ctx_impl->getxattr(obj, name, bl);
1224}
1225
1226int librados::IoCtx::getxattrs(const std::string& oid, map<std::string, bufferlist>& attrset)
1227{
1228 object_t obj(oid);
1229 return io_ctx_impl->getxattrs(obj, attrset);
1230}
1231
1232int librados::IoCtx::setxattr(const std::string& oid, const char *name, bufferlist& bl)
1233{
1234 object_t obj(oid);
1235 return io_ctx_impl->setxattr(obj, name, bl);
1236}
1237
1238int librados::IoCtx::rmxattr(const std::string& oid, const char *name)
1239{
1240 object_t obj(oid);
1241 return io_ctx_impl->rmxattr(obj, name);
1242}
1243
1244int librados::IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtime)
1245{
1246 object_t obj(oid);
1247 return io_ctx_impl->stat(obj, psize, pmtime);
1248}
1249
1250int librados::IoCtx::stat2(const std::string& oid, uint64_t *psize, struct timespec *pts)
1251{
1252 object_t obj(oid);
1253 return io_ctx_impl->stat2(obj, psize, pts);
1254}
1255
1256int librados::IoCtx::exec(const std::string& oid, const char *cls, const char *method,
1257 bufferlist& inbl, bufferlist& outbl)
1258{
1259 object_t obj(oid);
1260 return io_ctx_impl->exec(obj, cls, method, inbl, outbl);
1261}
1262
1263int librados::IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl)
1264{
1265 object_t obj(oid);
1266 return io_ctx_impl->tmap_update(obj, cmdbl);
1267}
1268
1269int librados::IoCtx::omap_get_vals(const std::string& oid,
1270 const std::string& start_after,
1271 uint64_t max_return,
1272 std::map<std::string, bufferlist> *out_vals)
1273{
1274 return omap_get_vals(oid, start_after, string(), max_return, out_vals);
1275}
1276
1277int librados::IoCtx::omap_get_vals2(
1278 const std::string& oid,
1279 const std::string& start_after,
1280 uint64_t max_return,
1281 std::map<std::string, bufferlist> *out_vals,
1282 bool *pmore)
1283{
1284 ObjectReadOperation op;
1285 int r;
1286 op.omap_get_vals2(start_after, max_return, out_vals, pmore, &r);
1287 bufferlist bl;
1288 int ret = operate(oid, &op, &bl);
1289 if (ret < 0)
1290 return ret;
1291 return r;
1292}
1293
1294int librados::IoCtx::omap_get_keys(const std::string& oid,
1295 const std::string& orig_start_after,
1296 uint64_t max_return,
1297 std::set<std::string> *out_keys)
1298{
1299 bool first = true;
1300 string start_after = orig_start_after;
1301 bool more = true;
1302 while (max_return > 0 && more) {
1303 std::set<std::string> out;
1304 ObjectReadOperation op;
1305 op.omap_get_keys2(start_after, max_return, &out, &more, nullptr);
1306 bufferlist bl;
1307 int ret = operate(oid, &op, &bl);
1308 if (ret < 0) {
1309 return ret;
1310 }
1311 if (more) {
1312 if (out.empty()) {
1313 return -EINVAL; // wth
1314 }
1315 start_after = *out.rbegin();
1316 }
1317 if (out.size() <= max_return) {
1318 max_return -= out.size();
1319 } else {
1320 max_return = 0;
1321 }
1322 if (first) {
1323 out_keys->swap(out);
1324 first = false;
1325 } else {
1326 out_keys->insert(out.begin(), out.end());
1327 out.clear();
1328 }
1329 }
1330 return 0;
1331}
1332
1333int librados::IoCtx::omap_get_keys2(
1334 const std::string& oid,
1335 const std::string& start_after,
1336 uint64_t max_return,
1337 std::set<std::string> *out_keys,
1338 bool *pmore)
1339{
1340 ObjectReadOperation op;
1341 int r;
1342 op.omap_get_keys2(start_after, max_return, out_keys, pmore, &r);
1343 bufferlist bl;
1344 int ret = operate(oid, &op, &bl);
1345 if (ret < 0)
1346 return ret;
1347 return r;
1348}
1349
1350int librados::IoCtx::omap_get_header(const std::string& oid,
1351 bufferlist *bl)
1352{
1353 ObjectReadOperation op;
1354 int r;
1355 op.omap_get_header(bl, &r);
1356 bufferlist b;
1357 int ret = operate(oid, &op, &b);
1358 if (ret < 0)
1359 return ret;
1360
1361 return r;
1362}
1363
1364int librados::IoCtx::omap_get_vals_by_keys(const std::string& oid,
1365 const std::set<std::string>& keys,
1366 std::map<std::string, bufferlist> *vals)
1367{
1368 ObjectReadOperation op;
1369 int r;
1370 bufferlist bl;
1371 op.omap_get_vals_by_keys(keys, vals, &r);
1372 int ret = operate(oid, &op, &bl);
1373 if (ret < 0)
1374 return ret;
1375
1376 return r;
1377}
1378
1379int librados::IoCtx::omap_set(const std::string& oid,
1380 const map<string, bufferlist>& m)
1381{
1382 ObjectWriteOperation op;
1383 op.omap_set(m);
1384 return operate(oid, &op);
1385}
1386
1387int librados::IoCtx::omap_set_header(const std::string& oid,
1388 const bufferlist& bl)
1389{
1390 ObjectWriteOperation op;
1391 op.omap_set_header(bl);
1392 return operate(oid, &op);
1393}
1394
1395int librados::IoCtx::omap_clear(const std::string& oid)
1396{
1397 ObjectWriteOperation op;
1398 op.omap_clear();
1399 return operate(oid, &op);
1400}
1401
1402int librados::IoCtx::omap_rm_keys(const std::string& oid,
1403 const std::set<std::string>& keys)
1404{
1405 ObjectWriteOperation op;
1406 op.omap_rm_keys(keys);
1407 return operate(oid, &op);
1408}
1409
1410int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o)
1411{
1412 object_t obj(oid);
1413 return io_ctx_impl->operate(obj, &o->impl->o, (ceph::real_time *)o->impl->prt);
1414}
1415
1416int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl)
1417{
1418 object_t obj(oid);
1419 return io_ctx_impl->operate_read(obj, &o->impl->o, pbl);
1420}
1421
1422int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1423 librados::ObjectWriteOperation *o)
1424{
1425 object_t obj(oid);
1426 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1427 io_ctx_impl->snapc, 0);
1428}
1429int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1430 ObjectWriteOperation *o, int flags)
1431{
1432 object_t obj(oid);
1433 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1434 io_ctx_impl->snapc,
1435 translate_flags(flags));
1436}
1437
1438int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1439 librados::ObjectWriteOperation *o,
1440 snap_t snap_seq, std::vector<snap_t>& snaps)
1441{
1442 object_t obj(oid);
1443 vector<snapid_t> snv;
1444 snv.resize(snaps.size());
1445 for (size_t i = 0; i < snaps.size(); ++i)
1446 snv[i] = snaps[i];
1447 SnapContext snapc(snap_seq, snv);
1448 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1449 snapc, 0);
1450}
1451
1452int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1453 librados::ObjectWriteOperation *o,
1454 snap_t snap_seq, std::vector<snap_t>& snaps,
1455 const blkin_trace_info *trace_info)
1456{
1457 object_t obj(oid);
1458 vector<snapid_t> snv;
1459 snv.resize(snaps.size());
1460 for (size_t i = 0; i < snaps.size(); ++i)
1461 snv[i] = snaps[i];
1462 SnapContext snapc(snap_seq, snv);
1463 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1464 snapc, 0, trace_info);
1465}
1466
1467int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1468 librados::ObjectWriteOperation *o,
1469 snap_t snap_seq, std::vector<snap_t>& snaps, int flags,
1470 const blkin_trace_info *trace_info)
1471{
1472 object_t obj(oid);
1473 vector<snapid_t> snv;
1474 snv.resize(snaps.size());
1475 for (size_t i = 0; i < snaps.size(); ++i)
1476 snv[i] = snaps[i];
1477 SnapContext snapc(snap_seq, snv);
1478 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc, snapc,
1479 translate_flags(flags), trace_info);
1480}
1481
1482int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1483 librados::ObjectReadOperation *o,
1484 bufferlist *pbl)
1485{
1486 object_t obj(oid);
1487 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1488 0, pbl);
1489}
1490
1491// deprecated
1492int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1493 librados::ObjectReadOperation *o,
1494 snap_t snapid_unused_deprecated,
1495 int flags, bufferlist *pbl)
1496{
1497 object_t obj(oid);
1498 int op_flags = 0;
1499 if (flags & OPERATION_BALANCE_READS)
1500 op_flags |= CEPH_OSD_FLAG_BALANCE_READS;
1501 if (flags & OPERATION_LOCALIZE_READS)
1502 op_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
1503 if (flags & OPERATION_ORDER_READS_WRITES)
1504 op_flags |= CEPH_OSD_FLAG_RWORDERED;
1505
1506 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1507 op_flags, pbl);
1508}
1509
1510int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1511 librados::ObjectReadOperation *o,
1512 int flags, bufferlist *pbl)
1513{
1514 object_t obj(oid);
1515 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1516 translate_flags(flags), pbl);
1517}
1518
1519int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1520 librados::ObjectReadOperation *o,
1521 int flags, bufferlist *pbl, const blkin_trace_info *trace_info)
1522{
1523 object_t obj(oid);
1524 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1525 translate_flags(flags), pbl, trace_info);
1526}
1527
1528void librados::IoCtx::snap_set_read(snap_t seq)
1529{
1530 io_ctx_impl->set_snap_read(seq);
1531}
1532
1533int librados::IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq, vector<snap_t>& snaps)
1534{
1535 vector<snapid_t> snv;
1536 snv.resize(snaps.size());
1537 for (unsigned i=0; i<snaps.size(); i++)
1538 snv[i] = snaps[i];
1539 return io_ctx_impl->set_snap_write_context(seq, snv);
1540}
1541
1542int librados::IoCtx::snap_create(const char *snapname)
1543{
1544 return io_ctx_impl->snap_create(snapname);
1545}
1546
1547int librados::IoCtx::snap_lookup(const char *name, snap_t *snapid)
1548{
1549 return io_ctx_impl->snap_lookup(name, snapid);
1550}
1551
1552int librados::IoCtx::snap_get_stamp(snap_t snapid, time_t *t)
1553{
1554 return io_ctx_impl->snap_get_stamp(snapid, t);
1555}
1556
1557int librados::IoCtx::snap_get_name(snap_t snapid, std::string *s)
1558{
1559 return io_ctx_impl->snap_get_name(snapid, s);
1560}
1561
1562int librados::IoCtx::snap_remove(const char *snapname)
1563{
1564 return io_ctx_impl->snap_remove(snapname);
1565}
1566
1567int librados::IoCtx::snap_list(std::vector<snap_t> *snaps)
1568{
1569 return io_ctx_impl->snap_list(snaps);
1570}
1571
1572int librados::IoCtx::snap_rollback(const std::string& oid, const char *snapname)
1573{
1574 return io_ctx_impl->rollback(oid, snapname);
1575}
1576
1577// Deprecated name kept for backward compatibility
1578int librados::IoCtx::rollback(const std::string& oid, const char *snapname)
1579{
1580 return snap_rollback(oid, snapname);
1581}
1582
1583int librados::IoCtx::selfmanaged_snap_create(uint64_t *snapid)
1584{
1585 return io_ctx_impl->selfmanaged_snap_create(snapid);
1586}
1587
1588void librados::IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid,
1589 AioCompletion *c)
1590{
1591 io_ctx_impl->aio_selfmanaged_snap_create(snapid, c->pc);
1592}
1593
1594int librados::IoCtx::selfmanaged_snap_remove(uint64_t snapid)
1595{
1596 return io_ctx_impl->selfmanaged_snap_remove(snapid);
1597}
1598
1599void librados::IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid,
1600 AioCompletion *c)
1601{
1602 io_ctx_impl->aio_selfmanaged_snap_remove(snapid, c->pc);
1603}
1604
1605int librados::IoCtx::selfmanaged_snap_rollback(const std::string& oid, uint64_t snapid)
1606{
1607 return io_ctx_impl->selfmanaged_snap_rollback_object(oid,
1608 io_ctx_impl->snapc,
1609 snapid);
1610}
1611
1612int librados::IoCtx::lock_exclusive(const std::string &oid, const std::string &name,
1613 const std::string &cookie,
1614 const std::string &description,
1615 struct timeval * duration, uint8_t flags)
1616{
1617 utime_t dur = utime_t();
1618 if (duration)
1619 dur.set_from_timeval(duration);
1620
1621 return rados::cls::lock::lock(this, oid, name, LOCK_EXCLUSIVE, cookie, "",
1622 description, dur, flags);
1623}
1624
1625int librados::IoCtx::lock_shared(const std::string &oid, const std::string &name,
1626 const std::string &cookie, const std::string &tag,
1627 const std::string &description,
1628 struct timeval * duration, uint8_t flags)
1629{
1630 utime_t dur = utime_t();
1631 if (duration)
1632 dur.set_from_timeval(duration);
1633
1634 return rados::cls::lock::lock(this, oid, name, LOCK_SHARED, cookie, tag,
1635 description, dur, flags);
1636}
1637
1638int librados::IoCtx::unlock(const std::string &oid, const std::string &name,
1639 const std::string &cookie)
1640{
1641 return rados::cls::lock::unlock(this, oid, name, cookie);
1642}
1643
1644struct AioUnlockCompletion : public librados::ObjectOperationCompletion {
1645 librados::AioCompletionImpl *completion;
1646 AioUnlockCompletion(librados::AioCompletion *c) : completion(c->pc) {
1647 completion->get();
1648 };
1649 void handle_completion(int r, bufferlist& outbl) override {
1650 rados_callback_t cb = completion->callback_complete;
1651 void *cb_arg = completion->callback_complete_arg;
1652 cb(completion, cb_arg);
1653 completion->lock.Lock();
1654 completion->callback_complete = NULL;
1655 completion->cond.Signal();
1656 completion->put_unlock();
1657 }
1658};
1659
1660int librados::IoCtx::aio_unlock(const std::string &oid, const std::string &name,
1661 const std::string &cookie, AioCompletion *c)
1662{
1663 return rados::cls::lock::aio_unlock(this, oid, name, cookie, c);
1664}
1665
1666int librados::IoCtx::break_lock(const std::string &oid, const std::string &name,
1667 const std::string &client, const std::string &cookie)
1668{
1669 entity_name_t locker;
1670 if (!locker.parse(client))
1671 return -EINVAL;
1672 return rados::cls::lock::break_lock(this, oid, name, cookie, locker);
1673}
1674
1675int librados::IoCtx::list_lockers(const std::string &oid, const std::string &name,
1676 int *exclusive,
1677 std::string *tag,
1678 std::list<librados::locker_t> *lockers)
1679{
1680 std::list<librados::locker_t> tmp_lockers;
1681 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t> rados_lockers;
1682 std::string tmp_tag;
1683 ClsLockType tmp_type;
1684 int r = rados::cls::lock::get_lock_info(this, oid, name, &rados_lockers, &tmp_type, &tmp_tag);
1685 if (r < 0)
1686 return r;
1687
1688 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t>::iterator map_it;
1689 for (map_it = rados_lockers.begin(); map_it != rados_lockers.end(); ++map_it) {
1690 librados::locker_t locker;
1691 locker.client = stringify(map_it->first.locker);
1692 locker.cookie = map_it->first.cookie;
1693 locker.address = stringify(map_it->second.addr);
1694 tmp_lockers.push_back(locker);
1695 }
1696
1697 if (lockers)
1698 *lockers = tmp_lockers;
1699 if (tag)
1700 *tag = tmp_tag;
1701 if (exclusive) {
1702 if (tmp_type == LOCK_EXCLUSIVE)
1703 *exclusive = 1;
1704 else
1705 *exclusive = 0;
1706 }
1707
1708 return tmp_lockers.size();
1709}
1710
1711librados::NObjectIterator librados::IoCtx::nobjects_begin(
1712 const bufferlist &filter)
1713{
1714 rados_list_ctx_t listh;
1715 rados_nobjects_list_open(io_ctx_impl, &listh);
1716 NObjectIterator iter((ObjListCtx*)listh);
1717 if (filter.length() > 0) {
1718 iter.set_filter(filter);
1719 }
1720 iter.get_next();
1721 return iter;
1722}
1723
1724librados::NObjectIterator librados::IoCtx::nobjects_begin(
1725 uint32_t pos, const bufferlist &filter)
1726{
1727 rados_list_ctx_t listh;
1728 rados_nobjects_list_open(io_ctx_impl, &listh);
1729 NObjectIterator iter((ObjListCtx*)listh);
1730 if (filter.length() > 0) {
1731 iter.set_filter(filter);
1732 }
1733 iter.seek(pos);
1734 return iter;
1735}
1736
1737librados::NObjectIterator librados::IoCtx::nobjects_begin(
1738 const ObjectCursor& cursor, const bufferlist &filter)
1739{
1740 rados_list_ctx_t listh;
1741 rados_nobjects_list_open(io_ctx_impl, &listh);
1742 NObjectIterator iter((ObjListCtx*)listh);
1743 if (filter.length() > 0) {
1744 iter.set_filter(filter);
1745 }
1746 iter.seek(cursor);
1747 return iter;
1748}
1749
1750const librados::NObjectIterator& librados::IoCtx::nobjects_end() const
1751{
1752 return NObjectIterator::__EndObjectIterator;
1753}
1754
1755int librados::IoCtx::hit_set_list(uint32_t hash, AioCompletion *c,
1756 std::list< std::pair<time_t, time_t> > *pls)
1757{
1758 return io_ctx_impl->hit_set_list(hash, c->pc, pls);
1759}
1760
1761int librados::IoCtx::hit_set_get(uint32_t hash, AioCompletion *c, time_t stamp,
1762 bufferlist *pbl)
1763{
1764 return io_ctx_impl->hit_set_get(hash, c->pc, stamp, pbl);
1765}
1766
1767
1768
1769uint64_t librados::IoCtx::get_last_version()
1770{
1771 return io_ctx_impl->last_version();
1772}
1773
1774int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1775 bufferlist *pbl, size_t len, uint64_t off)
1776{
1777 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off,
1778 io_ctx_impl->snap_seq);
1779}
1780
1781int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1782 bufferlist *pbl, size_t len, uint64_t off,
1783 uint64_t snapid)
1784{
1785 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off, snapid);
1786}
1787
1788int librados::IoCtx::aio_exec(const std::string& oid,
1789 librados::AioCompletion *c, const char *cls,
1790 const char *method, bufferlist& inbl,
1791 bufferlist *outbl)
1792{
1793 object_t obj(oid);
1794 return io_ctx_impl->aio_exec(obj, c->pc, cls, method, inbl, outbl);
1795}
1796
1797int librados::IoCtx::aio_cmpext(const std::string& oid,
1798 librados::AioCompletion *c,
1799 uint64_t off,
1800 bufferlist& cmp_bl)
1801{
1802 return io_ctx_impl->aio_cmpext(oid, c->pc, off, cmp_bl);
1803}
1804
1805int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1806 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1807 size_t len, uint64_t off)
1808{
1809 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1810 m, data_bl, len, off,
1811 io_ctx_impl->snap_seq);
1812}
1813
1814int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1815 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1816 size_t len, uint64_t off, uint64_t snapid)
1817{
1818 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1819 m, data_bl, len, off, snapid);
1820}
1821
1822int librados::IoCtx::aio_write(const std::string& oid, librados::AioCompletion *c,
1823 const bufferlist& bl, size_t len, uint64_t off)
1824{
1825 return io_ctx_impl->aio_write(oid, c->pc, bl, len, off);
1826}
1827
1828int librados::IoCtx::aio_append(const std::string& oid, librados::AioCompletion *c,
1829 const bufferlist& bl, size_t len)
1830{
1831 return io_ctx_impl->aio_append(oid, c->pc, bl, len);
1832}
1833
1834int librados::IoCtx::aio_write_full(const std::string& oid, librados::AioCompletion *c,
1835 const bufferlist& bl)
1836{
1837 object_t obj(oid);
1838 return io_ctx_impl->aio_write_full(obj, c->pc, bl);
1839}
1840
1841int librados::IoCtx::aio_writesame(const std::string& oid, librados::AioCompletion *c,
1842 const bufferlist& bl, size_t write_len,
1843 uint64_t off)
1844{
1845 return io_ctx_impl->aio_writesame(oid, c->pc, bl, write_len, off);
1846}
1847
1848
1849int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c)
1850{
1851 return io_ctx_impl->aio_remove(oid, c->pc);
1852}
1853
1854int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c, int flags)
1855{
1856 return io_ctx_impl->aio_remove(oid, c->pc, flags);
1857}
1858
1859int librados::IoCtx::aio_flush_async(librados::AioCompletion *c)
1860{
1861 io_ctx_impl->flush_aio_writes_async(c->pc);
1862 return 0;
1863}
1864
1865int librados::IoCtx::aio_flush()
1866{
1867 io_ctx_impl->flush_aio_writes();
1868 return 0;
1869}
1870
1871struct AioGetxattrDataPP {
1872 AioGetxattrDataPP(librados::AioCompletionImpl *c, bufferlist *_bl) :
1873 bl(_bl), completion(c) {}
1874 bufferlist *bl;
1875 struct librados::C_AioCompleteAndSafe completion;
1876};
1877
1878static void rados_aio_getxattr_completepp(rados_completion_t c, void *arg) {
1879 AioGetxattrDataPP *cdata = reinterpret_cast<AioGetxattrDataPP*>(arg);
1880 int rc = rados_aio_get_return_value(c);
1881 if (rc >= 0) {
1882 rc = cdata->bl->length();
1883 }
1884 cdata->completion.finish(rc);
1885 delete cdata;
1886}
1887
1888int librados::IoCtx::aio_getxattr(const std::string& oid, librados::AioCompletion *c,
1889 const char *name, bufferlist& bl)
1890{
1891 // create data object to be passed to async callback
1892 AioGetxattrDataPP *cdata = new AioGetxattrDataPP(c->pc, &bl);
1893 if (!cdata) {
1894 return -ENOMEM;
1895 }
1896 // create completion callback
1897 librados::AioCompletionImpl *comp = new librados::AioCompletionImpl;
1898 comp->set_complete_callback(cdata, rados_aio_getxattr_completepp);
1899 // call actual getxattr from IoCtxImpl
1900 object_t obj(oid);
1901 return io_ctx_impl->aio_getxattr(obj, comp, name, bl);
1902}
1903
1904int librados::IoCtx::aio_getxattrs(const std::string& oid, AioCompletion *c,
1905 map<std::string, bufferlist>& attrset)
1906{
1907 object_t obj(oid);
1908 return io_ctx_impl->aio_getxattrs(obj, c->pc, attrset);
1909}
1910
1911int librados::IoCtx::aio_setxattr(const std::string& oid, AioCompletion *c,
1912 const char *name, bufferlist& bl)
1913{
1914 object_t obj(oid);
1915 return io_ctx_impl->aio_setxattr(obj, c->pc, name, bl);
1916}
1917
1918int librados::IoCtx::aio_rmxattr(const std::string& oid, AioCompletion *c,
1919 const char *name)
1920{
1921 object_t obj(oid);
1922 return io_ctx_impl->aio_rmxattr(obj, c->pc, name);
1923}
1924
1925int librados::IoCtx::aio_stat(const std::string& oid, librados::AioCompletion *c,
1926 uint64_t *psize, time_t *pmtime)
1927{
1928 object_t obj(oid);
1929 return io_ctx_impl->aio_stat(obj, c->pc, psize, pmtime);
1930}
1931
1932int librados::IoCtx::aio_cancel(librados::AioCompletion *c)
1933{
1934 return io_ctx_impl->aio_cancel(c->pc);
1935}
1936
1937int librados::IoCtx::watch(const string& oid, uint64_t ver, uint64_t *cookie,
1938 librados::WatchCtx *ctx)
1939{
1940 object_t obj(oid);
1941 return io_ctx_impl->watch(obj, cookie, ctx, NULL);
1942}
1943
1944int librados::IoCtx::watch2(const string& oid, uint64_t *cookie,
1945 librados::WatchCtx2 *ctx2)
1946{
1947 object_t obj(oid);
1948 return io_ctx_impl->watch(obj, cookie, NULL, ctx2);
1949}
1950
1951int librados::IoCtx::watch3(const string& oid, uint64_t *cookie,
1952 librados::WatchCtx2 *ctx2, uint32_t timeout)
1953{
1954 object_t obj(oid);
1955 return io_ctx_impl->watch(obj, cookie, NULL, ctx2, timeout);
1956}
1957
1958int librados::IoCtx::aio_watch(const string& oid, AioCompletion *c,
1959 uint64_t *cookie,
1960 librados::WatchCtx2 *ctx2)
1961{
1962 object_t obj(oid);
1963 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2);
1964}
1965
1966int librados::IoCtx::aio_watch2(const string& oid, AioCompletion *c,
1967 uint64_t *cookie,
1968 librados::WatchCtx2 *ctx2,
1969 uint32_t timeout)
1970{
1971 object_t obj(oid);
1972 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2, timeout);
1973}
1974
1975int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
1976{
1977 return io_ctx_impl->unwatch(handle);
1978}
1979
1980int librados::IoCtx::unwatch2(uint64_t handle)
1981{
1982 return io_ctx_impl->unwatch(handle);
1983}
1984
1985int librados::IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c)
1986{
1987 return io_ctx_impl->aio_unwatch(handle, c->pc);
1988}
1989
1990int librados::IoCtx::watch_check(uint64_t handle)
1991{
1992 return io_ctx_impl->watch_check(handle);
1993}
1994
1995int librados::IoCtx::notify(const string& oid, uint64_t ver, bufferlist& bl)
1996{
1997 object_t obj(oid);
1998 return io_ctx_impl->notify(obj, bl, 0, NULL, NULL, NULL);
1999}
2000
2001int librados::IoCtx::notify2(const string& oid, bufferlist& bl,
2002 uint64_t timeout_ms, bufferlist *preplybl)
2003{
2004 object_t obj(oid);
2005 return io_ctx_impl->notify(obj, bl, timeout_ms, preplybl, NULL, NULL);
2006}
2007
2008int librados::IoCtx::aio_notify(const string& oid, AioCompletion *c,
2009 bufferlist& bl, uint64_t timeout_ms,
2010 bufferlist *preplybl)
2011{
2012 object_t obj(oid);
2013 return io_ctx_impl->aio_notify(obj, c->pc, bl, timeout_ms, preplybl, NULL,
2014 NULL);
2015}
2016
2017void librados::IoCtx::notify_ack(const std::string& o,
2018 uint64_t notify_id, uint64_t handle,
2019 bufferlist& bl)
2020{
2021 io_ctx_impl->notify_ack(o, notify_id, handle, bl);
2022}
2023
2024int librados::IoCtx::list_watchers(const std::string& oid,
2025 std::list<obj_watch_t> *out_watchers)
2026{
2027 ObjectReadOperation op;
2028 int r;
2029 op.list_watchers(out_watchers, &r);
2030 bufferlist bl;
2031 int ret = operate(oid, &op, &bl);
2032 if (ret < 0)
2033 return ret;
2034
2035 return r;
2036}
2037
2038int librados::IoCtx::list_snaps(const std::string& oid,
2039 snap_set_t *out_snaps)
2040{
2041 ObjectReadOperation op;
2042 int r;
2043 if (io_ctx_impl->snap_seq != CEPH_SNAPDIR)
2044 return -EINVAL;
2045 op.list_snaps(out_snaps, &r);
2046 bufferlist bl;
2047 int ret = operate(oid, &op, &bl);
2048 if (ret < 0)
2049 return ret;
2050
2051 return r;
2052}
2053
2054void librados::IoCtx::set_notify_timeout(uint32_t timeout)
2055{
2056 io_ctx_impl->set_notify_timeout(timeout);
2057}
2058
2059int librados::IoCtx::set_alloc_hint(const std::string& o,
2060 uint64_t expected_object_size,
2061 uint64_t expected_write_size)
2062{
2063 object_t oid(o);
2064 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2065 expected_write_size, 0);
2066}
2067
2068int librados::IoCtx::set_alloc_hint2(const std::string& o,
2069 uint64_t expected_object_size,
2070 uint64_t expected_write_size,
2071 uint32_t flags)
2072{
2073 object_t oid(o);
2074 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2075 expected_write_size, flags);
2076}
2077
2078void librados::IoCtx::set_assert_version(uint64_t ver)
2079{
2080 io_ctx_impl->set_assert_version(ver);
2081}
2082
2083void librados::IoCtx::locator_set_key(const string& key)
2084{
2085 io_ctx_impl->oloc.key = key;
2086}
2087
2088void librados::IoCtx::set_namespace(const string& nspace)
2089{
2090 io_ctx_impl->oloc.nspace = nspace;
2091}
2092
2093std::string librados::IoCtx::get_namespace() const
2094{
2095 return io_ctx_impl->oloc.nspace;
2096}
2097
2098int64_t librados::IoCtx::get_id()
2099{
2100 return io_ctx_impl->get_id();
2101}
2102
2103uint32_t librados::IoCtx::get_object_hash_position(const std::string& oid)
2104{
2105 uint32_t hash;
2106 int r = io_ctx_impl->get_object_hash_position(oid, &hash);
2107 if (r < 0)
2108 hash = 0;
2109 return hash;
2110}
2111
2112uint32_t librados::IoCtx::get_object_pg_hash_position(const std::string& oid)
2113{
2114 uint32_t hash;
2115 int r = io_ctx_impl->get_object_pg_hash_position(oid, &hash);
2116 if (r < 0)
2117 hash = 0;
2118 return hash;
2119}
2120
2121int librados::IoCtx::get_object_hash_position2(
2122 const std::string& oid, uint32_t *hash_position)
2123{
2124 return io_ctx_impl->get_object_hash_position(oid, hash_position);
2125}
2126
2127int librados::IoCtx::get_object_pg_hash_position2(
2128 const std::string& oid, uint32_t *pg_hash_position)
2129{
2130 return io_ctx_impl->get_object_pg_hash_position(oid, pg_hash_position);
2131}
2132
2133librados::config_t librados::IoCtx::cct()
2134{
2135 return (config_t)io_ctx_impl->client->cct;
2136}
2137
2138librados::IoCtx::IoCtx(IoCtxImpl *io_ctx_impl_)
2139 : io_ctx_impl(io_ctx_impl_)
2140{
2141}
2142
2143void librados::IoCtx::set_osdmap_full_try()
2144{
2145 io_ctx_impl->objecter->set_osdmap_full_try();
2146}
2147
2148void librados::IoCtx::unset_osdmap_full_try()
2149{
2150 io_ctx_impl->objecter->unset_osdmap_full_try();
2151}
2152
2153///////////////////////////// Rados //////////////////////////////
2154void librados::Rados::version(int *major, int *minor, int *extra)
2155{
2156 rados_version(major, minor, extra);
2157}
2158
2159librados::Rados::Rados() : client(NULL)
2160{
2161}
2162
2163librados::Rados::Rados(IoCtx &ioctx)
2164{
2165 client = ioctx.io_ctx_impl->client;
2166 ceph_assert(client != NULL);
2167 client->get();
2168}
2169
2170librados::Rados::~Rados()
2171{
2172 shutdown();
2173}
2174
2175int librados::Rados::init(const char * const id)
2176{
2177 return rados_create((rados_t *)&client, id);
2178}
2179
2180int librados::Rados::init2(const char * const name,
2181 const char * const clustername, uint64_t flags)
2182{
2183 return rados_create2((rados_t *)&client, clustername, name, flags);
2184}
2185
2186int librados::Rados::init_with_context(config_t cct_)
2187{
2188 return rados_create_with_context((rados_t *)&client, (rados_config_t)cct_);
2189}
2190
2191int librados::Rados::connect()
2192{
2193 return client->connect();
2194}
2195
2196librados::config_t librados::Rados::cct()
2197{
2198 return (config_t)client->cct;
2199}
2200
2201int librados::Rados::watch_flush()
2202{
2203 if (!client)
2204 return -EINVAL;
2205 return client->watch_flush();
2206}
2207
2208int librados::Rados::aio_watch_flush(AioCompletion *c)
2209{
2210 if (!client)
2211 return -EINVAL;
2212 return client->async_watch_flush(c->pc);
2213}
2214
2215void librados::Rados::shutdown()
2216{
2217 if (!client)
2218 return;
2219 if (client->put()) {
2220 client->shutdown();
2221 delete client;
2222 client = NULL;
2223 }
2224}
2225
2226uint64_t librados::Rados::get_instance_id()
2227{
2228 return client->get_instance_id();
2229}
2230
2231int librados::Rados::get_min_compatible_osd(int8_t* require_osd_release)
2232{
2233 return client->get_min_compatible_osd(require_osd_release);
2234}
2235
2236int librados::Rados::get_min_compatible_client(int8_t* min_compat_client,
2237 int8_t* require_min_compat_client)
2238{
2239 return client->get_min_compatible_client(min_compat_client,
2240 require_min_compat_client);
2241}
2242
2243int librados::Rados::conf_read_file(const char * const path) const
2244{
2245 return rados_conf_read_file((rados_t)client, path);
2246}
2247
2248int librados::Rados::conf_parse_argv(int argc, const char ** argv) const
2249{
2250 return rados_conf_parse_argv((rados_t)client, argc, argv);
2251}
2252
2253int librados::Rados::conf_parse_argv_remainder(int argc, const char ** argv,
2254 const char ** remargv) const
2255{
2256 return rados_conf_parse_argv_remainder((rados_t)client, argc, argv, remargv);
2257}
2258
2259int librados::Rados::conf_parse_env(const char *name) const
2260{
2261 return rados_conf_parse_env((rados_t)client, name);
2262}
2263
2264int librados::Rados::conf_set(const char *option, const char *value)
2265{
2266 return rados_conf_set((rados_t)client, option, value);
2267}
2268
2269int librados::Rados::conf_get(const char *option, std::string &val)
2270{
2271 char *str = NULL;
2272 const auto& conf = client->cct->_conf;
2273 int ret = conf.get_val(option, &str, -1);
2274 if (ret) {
2275 free(str);
2276 return ret;
2277 }
2278 val = str;
2279 free(str);
2280 return 0;
2281}
2282
2283int librados::Rados::service_daemon_register(
2284 const std::string& service, ///< service name (e.g., 'rgw')
2285 const std::string& name, ///< daemon name (e.g., 'gwfoo')
2286 const std::map<std::string,std::string>& metadata) ///< static metadata about daemon
2287{
2288 return client->service_daemon_register(service, name, metadata);
2289}
2290
2291int librados::Rados::service_daemon_update_status(
2292 std::map<std::string,std::string>&& status)
2293{
2294 return client->service_daemon_update_status(std::move(status));
2295}
2296
2297int librados::Rados::pool_create(const char *name)
2298{
2299 string str(name);
2300 return client->pool_create(str);
2301}
2302
2303int librados::Rados::pool_create(const char *name, uint64_t auid)
2304{
2305 if (auid != CEPH_AUTH_UID_DEFAULT) {
2306 return -EINVAL;
2307 }
2308 string str(name);
2309 return client->pool_create(str);
2310}
2311
2312int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule)
2313{
2314 if (auid != CEPH_AUTH_UID_DEFAULT) {
2315 return -EINVAL;
2316 }
2317 string str(name);
2318 return client->pool_create(str, crush_rule);
2319}
2320
2321int librados::Rados::pool_create_with_rule(const char *name, __u8 crush_rule)
2322{
2323 string str(name);
2324 return client->pool_create(str, crush_rule);
2325}
2326
2327int librados::Rados::pool_create_async(const char *name, PoolAsyncCompletion *c)
2328{
2329 string str(name);
2330 return client->pool_create_async(str, c->pc);
2331}
2332
2333int librados::Rados::pool_create_async(const char *name, uint64_t auid, PoolAsyncCompletion *c)
2334{
2335 if (auid != CEPH_AUTH_UID_DEFAULT) {
2336 return -EINVAL;
2337 }
2338 string str(name);
2339 return client->pool_create_async(str, c->pc);
2340}
2341
2342int librados::Rados::pool_create_async(const char *name, uint64_t auid, __u8 crush_rule,
2343 PoolAsyncCompletion *c)
2344{
2345 if (auid != CEPH_AUTH_UID_DEFAULT) {
2346 return -EINVAL;
2347 }
2348 string str(name);
2349 return client->pool_create_async(str, c->pc, crush_rule);
2350}
2351
2352int librados::Rados::pool_create_with_rule_async(
2353 const char *name, __u8 crush_rule,
2354 PoolAsyncCompletion *c)
2355{
2356 string str(name);
2357 return client->pool_create_async(str, c->pc, crush_rule);
2358}
2359
2360int librados::Rados::pool_get_base_tier(int64_t pool_id, int64_t* base_tier)
2361{
2362 tracepoint(librados, rados_pool_get_base_tier_enter, (rados_t)client, pool_id);
2363 int retval = client->pool_get_base_tier(pool_id, base_tier);
2364 tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
2365 return retval;
2366}
2367
2368int librados::Rados::pool_delete(const char *name)
2369{
2370 return client->pool_delete(name);
2371}
2372
2373int librados::Rados::pool_delete_async(const char *name, PoolAsyncCompletion *c)
2374{
2375 return client->pool_delete_async(name, c->pc);
2376}
2377
2378int librados::Rados::pool_list(std::list<std::string>& v)
2379{
2380 std::list<std::pair<int64_t, std::string> > pools;
2381 int r = client->pool_list(pools);
2382 if (r < 0) {
2383 return r;
2384 }
2385
2386 v.clear();
2387 for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin();
2388 it != pools.end(); ++it) {
2389 v.push_back(it->second);
2390 }
2391 return 0;
2392}
2393
2394int librados::Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v)
2395{
2396 return client->pool_list(v);
2397}
2398
2399int64_t librados::Rados::pool_lookup(const char *name)
2400{
2401 return client->lookup_pool(name);
2402}
2403
2404int librados::Rados::pool_reverse_lookup(int64_t id, std::string *name)
2405{
2406 return client->pool_get_name(id, name);
2407}
2408
2409int librados::Rados::mon_command(string cmd, const bufferlist& inbl,
2410 bufferlist *outbl, string *outs)
2411{
2412 vector<string> cmdvec;
2413 cmdvec.push_back(cmd);
2414 return client->mon_command(cmdvec, inbl, outbl, outs);
2415}
2416
2417int librados::Rados::osd_command(int osdid, std::string cmd, const bufferlist& inbl,
2418 bufferlist *outbl, std::string *outs)
2419{
2420 vector<string> cmdvec;
2421 cmdvec.push_back(cmd);
2422 return client->osd_command(osdid, cmdvec, inbl, outbl, outs);
2423}
2424
2425int librados::Rados::mgr_command(std::string cmd, const bufferlist& inbl,
2426 bufferlist *outbl, std::string *outs)
2427{
2428 vector<string> cmdvec;
2429 cmdvec.push_back(cmd);
2430 return client->mgr_command(cmdvec, inbl, outbl, outs);
2431}
2432
2433
2434
2435int librados::Rados::pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
2436 bufferlist *outbl, std::string *outs)
2437{
2438 vector<string> cmdvec;
2439 cmdvec.push_back(cmd);
2440
2441 pg_t pgid;
2442 if (!pgid.parse(pgstr))
2443 return -EINVAL;
2444
2445 return client->pg_command(pgid, cmdvec, inbl, outbl, outs);
2446}
2447
2448int librados::Rados::ioctx_create(const char *name, IoCtx &io)
2449{
2450 rados_ioctx_t p;
2451 int ret = rados_ioctx_create((rados_t)client, name, &p);
2452 if (ret)
2453 return ret;
2454 io.close();
2455 io.io_ctx_impl = (IoCtxImpl*)p;
2456 return 0;
2457}
2458
2459int librados::Rados::ioctx_create2(int64_t pool_id, IoCtx &io)
2460{
2461 rados_ioctx_t p;
2462 int ret = rados_ioctx_create2((rados_t)client, pool_id, &p);
2463 if (ret)
2464 return ret;
2465 io.close();
2466 io.io_ctx_impl = (IoCtxImpl*)p;
2467 return 0;
2468}
2469
2470void librados::Rados::test_blacklist_self(bool set)
2471{
2472 client->blacklist_self(set);
2473}
2474
2475int librados::Rados::get_pool_stats(std::list<string>& v,
2476 stats_map& result)
2477{
2478 map<string,::pool_stat_t> rawresult;
2479 int r = client->get_pool_stats(v, rawresult);
2480 for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
2481 p != rawresult.end();
2482 ++p) {
2483 pool_stat_t& pv = result[p->first];
2484 auto& pstat = p->second;
2485 store_statfs_t &statfs = pstat.store_stats;
2486 uint64_t allocated_bytes = pstat.get_allocated_bytes();
2487 // FIXME: raw_used_rate is unknown hence use 1.0 here
2488 // meaning we keep net amount aggregated over all replicas
2489 // Not a big deal so far since this field isn't exposed
2490 uint64_t user_bytes = pstat.get_user_bytes(1.0);
2491
2492 object_stat_sum_t *sum = &p->second.stats.sum;
2493 pv.num_kb = shift_round_up(allocated_bytes, 10);
2494 pv.num_bytes = allocated_bytes;
2495 pv.num_objects = sum->num_objects;
2496 pv.num_object_clones = sum->num_object_clones;
2497 pv.num_object_copies = sum->num_object_copies;
2498 pv.num_objects_missing_on_primary = sum->num_objects_missing_on_primary;
2499 pv.num_objects_unfound = sum->num_objects_unfound;
2500 pv.num_objects_degraded = sum->num_objects_degraded;
2501 pv.num_rd = sum->num_rd;
2502 pv.num_rd_kb = sum->num_rd_kb;
2503 pv.num_wr = sum->num_wr;
2504 pv.num_wr_kb = sum->num_wr_kb;
2505 pv.num_user_bytes = user_bytes;
2506 pv.compressed_bytes_orig = statfs.data_compressed_original;
2507 pv.compressed_bytes = statfs.data_compressed;
2508 pv.compressed_bytes_alloc = statfs.data_compressed_allocated;
2509 }
2510 return r;
2511}
2512
2513int librados::Rados::get_pool_stats(std::list<string>& v,
2514 std::map<string, stats_map>& result)
2515{
2516 stats_map m;
2517 int r = get_pool_stats(v, m);
2518 if (r < 0)
2519 return r;
2520 for (map<string,pool_stat_t>::iterator p = m.begin();
2521 p != m.end();
2522 ++p) {
2523 result[p->first][string()] = p->second;
2524 }
2525 return r;
2526}
2527
2528int librados::Rados::get_pool_stats(std::list<string>& v,
2529 string& category, // unused
2530 std::map<string, stats_map>& result)
2531{
2532 return -EOPNOTSUPP;
2533}
2534
2535bool librados::Rados::get_pool_is_selfmanaged_snaps_mode(const std::string& pool)
2536{
2537 return client->get_pool_is_selfmanaged_snaps_mode(pool);
2538}
2539
2540int librados::Rados::cluster_stat(cluster_stat_t& result)
2541{
2542 ceph_statfs stats;
2543 int r = client->get_fs_stats(stats);
2544 result.kb = stats.kb;
2545 result.kb_used = stats.kb_used;
2546 result.kb_avail = stats.kb_avail;
2547 result.num_objects = stats.num_objects;
2548 return r;
2549}
2550
2551int librados::Rados::cluster_fsid(string *fsid)
2552{
2553 return client->get_fsid(fsid);
2554}
2555
2556namespace librados {
2557 struct PlacementGroupImpl {
2558 pg_t pgid;
2559 };
2560
2561 PlacementGroup::PlacementGroup()
2562 : impl{new PlacementGroupImpl}
2563 {}
2564
2565 PlacementGroup::PlacementGroup(const PlacementGroup& pg)
2566 : impl{new PlacementGroupImpl}
2567 {
2568 impl->pgid = pg.impl->pgid;
2569 }
2570
2571 PlacementGroup::~PlacementGroup()
2572 {}
2573
2574 bool PlacementGroup::parse(const char* s)
2575 {
2576 return impl->pgid.parse(s);
2577 }
2578}
2579
2580std::ostream& librados::operator<<(std::ostream& out,
2581 const librados::PlacementGroup& pg)
2582{
2583 return out << pg.impl->pgid;
2584}
2585
2586int librados::Rados::get_inconsistent_pgs(int64_t pool_id,
2587 std::vector<PlacementGroup>* pgs)
2588{
2589 std::vector<string> pgids;
2590 if (auto ret = client->get_inconsistent_pgs(pool_id, &pgids); ret) {
2591 return ret;
2592 }
2593 for (const auto& pgid : pgids) {
2594 librados::PlacementGroup pg;
2595 if (!pg.parse(pgid.c_str())) {
2596 return -EINVAL;
2597 }
2598 pgs->emplace_back(pg);
2599 }
2600 return 0;
2601}
2602
2603int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
2604 const object_id_t &start_after,
2605 unsigned max_return,
2606 AioCompletion *c,
2607 std::vector<inconsistent_obj_t>* objects,
2608 uint32_t* interval)
2609{
2610 IoCtx ioctx;
2611 const pg_t pgid = pg.impl->pgid;
2612 int r = ioctx_create2(pgid.pool(), ioctx);
2613 if (r < 0) {
2614 return r;
2615 }
2616
2617 return ioctx.io_ctx_impl->get_inconsistent_objects(pgid,
2618 start_after,
2619 max_return,
2620 c->pc,
2621 objects,
2622 interval);
2623}
2624
2625int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
2626 const object_id_t &start_after,
2627 unsigned max_return,
2628 AioCompletion *c,
2629 std::vector<inconsistent_snapset_t>* snapsets,
2630 uint32_t* interval)
2631{
2632 IoCtx ioctx;
2633 const pg_t pgid = pg.impl->pgid;
2634 int r = ioctx_create2(pgid.pool(), ioctx);
2635 if (r < 0) {
2636 return r;
2637 }
2638
2639 return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
2640 start_after,
2641 max_return,
2642 c->pc,
2643 snapsets,
2644 interval);
2645}
2646
2647int librados::Rados::wait_for_latest_osdmap()
2648{
2649 return client->wait_for_latest_osdmap();
2650}
2651
2652int librados::Rados::blacklist_add(const std::string& client_address,
2653 uint32_t expire_seconds)
2654{
2655 return client->blacklist_add(client_address, expire_seconds);
2656}
2657
2658librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
2659{
2660 PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
2661 return new PoolAsyncCompletion(c);
2662}
2663
2664librados::AioCompletion *librados::Rados::aio_create_completion()
2665{
2666 AioCompletionImpl *c = new AioCompletionImpl;
2667 return new AioCompletion(c);
2668}
2669
2670librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
2671 callback_t cb_complete,
2672 callback_t cb_safe)
2673{
2674 AioCompletionImpl *c;
2675 int r = rados_aio_create_completion(cb_arg, cb_complete, cb_safe, (void**)&c);
2676 ceph_assert(r == 0);
2677 return new AioCompletion(c);
2678}
2679
2680librados::ObjectOperation::ObjectOperation()
2681{
2682 impl = new ObjectOperationImpl;
2683}
2684
2685librados::ObjectOperation::~ObjectOperation()
2686{
2687 delete impl;
2688}
2689
2690///////////////////////////// ListObject //////////////////////////////
2691librados::ListObject::ListObject() : impl(NULL)
2692{
2693}
2694
2695librados::ListObject::ListObject(librados::ListObjectImpl *i): impl(i)
2696{
2697}
2698
2699librados::ListObject::ListObject(const ListObject& rhs)
2700{
2701 if (rhs.impl == NULL) {
2702 impl = NULL;
2703 return;
2704 }
2705 impl = new ListObjectImpl();
2706 *impl = *(rhs.impl);
2707}
2708
2709librados::ListObject& librados::ListObject::operator=(const ListObject& rhs)
2710{
2711 if (rhs.impl == NULL) {
2712 delete impl;
2713 impl = NULL;
2714 return *this;
2715 }
2716 if (impl == NULL)
2717 impl = new ListObjectImpl();
2718 *impl = *(rhs.impl);
2719 return *this;
2720}
2721
2722librados::ListObject::~ListObject()
2723{
2724 if (impl)
2725 delete impl;
2726 impl = NULL;
2727}
2728
2729const std::string& librados::ListObject::get_nspace() const
2730{
2731 return impl->get_nspace();
2732}
2733
2734const std::string& librados::ListObject::get_oid() const
2735{
2736 return impl->get_oid();
2737}
2738
2739const std::string& librados::ListObject::get_locator() const
2740{
2741 return impl->get_locator();
2742}
2743
2744std::ostream& librados::operator<<(std::ostream& out, const librados::ListObject& lop)
2745{
2746 out << *(lop.impl);
2747 return out;
2748}
2749
2750librados::ObjectCursor::ObjectCursor()
2751{
2752 c_cursor = (rados_object_list_cursor)new hobject_t();
2753}
2754
2755librados::ObjectCursor::~ObjectCursor()
2756{
2757 hobject_t *h = (hobject_t *)c_cursor;
2758 delete h;
2759}
2760
2761librados::ObjectCursor::ObjectCursor(rados_object_list_cursor c)
2762{
2763 if (!c) {
2764 c_cursor = nullptr;
2765 } else {
2766 c_cursor = (rados_object_list_cursor)new hobject_t(*(hobject_t *)c);
2767 }
2768}
2769
2770librados::ObjectCursor& librados::ObjectCursor::operator=(const librados::ObjectCursor& rhs)
2771{
2772 if (rhs.c_cursor != nullptr) {
2773 hobject_t *h = (hobject_t*)rhs.c_cursor;
2774 c_cursor = (rados_object_list_cursor)(new hobject_t(*h));
2775 } else {
2776 c_cursor = nullptr;
2777 }
2778 return *this;
2779}
2780
2781bool librados::ObjectCursor::operator<(const librados::ObjectCursor &rhs) const
2782{
2783 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
2784 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
2785 return lhs_hobj < rhs_hobj;
2786}
2787
2788bool librados::ObjectCursor::operator==(const librados::ObjectCursor &rhs) const
2789{
2790 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
2791 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
2792 return cmp(lhs_hobj, rhs_hobj) == 0;
2793}
2794librados::ObjectCursor::ObjectCursor(const librados::ObjectCursor &rhs)
2795{
2796 *this = rhs;
2797}
2798
2799librados::ObjectCursor librados::IoCtx::object_list_begin()
2800{
2801 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_begin());
2802 ObjectCursor oc;
2803 oc.set((rados_object_list_cursor)h);
2804 return oc;
2805}
2806
2807
2808librados::ObjectCursor librados::IoCtx::object_list_end()
2809{
2810 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_end());
2811 librados::ObjectCursor oc;
2812 oc.set((rados_object_list_cursor)h);
2813 return oc;
2814}
2815
2816
2817void librados::ObjectCursor::set(rados_object_list_cursor c)
2818{
2819 delete (hobject_t*)c_cursor;
2820 c_cursor = c;
2821}
2822
2823string librados::ObjectCursor::to_str() const
2824{
2825 stringstream ss;
2826 ss << *(hobject_t *)c_cursor;
2827 return ss.str();
2828}
2829
2830bool librados::ObjectCursor::from_str(const string& s)
2831{
2832 if (s.empty()) {
2833 *(hobject_t *)c_cursor = hobject_t();
2834 return true;
2835 }
2836 return ((hobject_t *)c_cursor)->parse(s);
2837}
2838
2839CEPH_RADOS_API std::ostream& librados::operator<<(std::ostream& os, const librados::ObjectCursor& oc)
2840{
2841 if (oc.c_cursor) {
2842 os << *(hobject_t *)oc.c_cursor;
2843 } else {
2844 os << hobject_t();
2845 }
2846 return os;
2847}
2848
2849bool librados::IoCtx::object_list_is_end(const ObjectCursor &oc)
2850{
2851 hobject_t *h = (hobject_t *)oc.c_cursor;
2852 return h->is_max();
2853}
2854
2855int librados::IoCtx::object_list(const ObjectCursor &start,
2856 const ObjectCursor &finish,
2857 const size_t result_item_count,
2858 const bufferlist &filter,
2859 std::vector<ObjectItem> *result,
2860 ObjectCursor *next)
2861{
2862 ceph_assert(result != nullptr);
2863 ceph_assert(next != nullptr);
2864 result->clear();
2865
2866 C_SaferCond cond;
2867 hobject_t next_hash;
2868 std::list<librados::ListObjectImpl> obj_result;
2869 io_ctx_impl->objecter->enumerate_objects(
2870 io_ctx_impl->poolid,
2871 io_ctx_impl->oloc.nspace,
2872 *((hobject_t*)start.c_cursor),
2873 *((hobject_t*)finish.c_cursor),
2874 result_item_count,
2875 filter,
2876 &obj_result,
2877 &next_hash,
2878 &cond);
2879
2880 int r = cond.wait();
2881 if (r < 0) {
2882 next->set((rados_object_list_cursor)(new hobject_t(hobject_t::get_max())));
2883 return r;
2884 }
2885
2886 next->set((rados_object_list_cursor)(new hobject_t(next_hash)));
2887
2888 for (std::list<librados::ListObjectImpl>::iterator i = obj_result.begin();
2889 i != obj_result.end(); ++i) {
2890 ObjectItem oi;
2891 oi.oid = i->oid;
2892 oi.nspace = i->nspace;
2893 oi.locator = i->locator;
2894 result->push_back(oi);
2895 }
2896
2897 return obj_result.size();
2898}
2899
2900void librados::IoCtx::object_list_slice(
2901 const ObjectCursor start,
2902 const ObjectCursor finish,
2903 const size_t n,
2904 const size_t m,
2905 ObjectCursor *split_start,
2906 ObjectCursor *split_finish)
2907{
2908 ceph_assert(split_start != nullptr);
2909 ceph_assert(split_finish != nullptr);
2910
2911 io_ctx_impl->object_list_slice(
2912 *((hobject_t*)(start.c_cursor)),
2913 *((hobject_t*)(finish.c_cursor)),
2914 n,
2915 m,
2916 (hobject_t*)(split_start->c_cursor),
2917 (hobject_t*)(split_finish->c_cursor));
2918}
2919
2920int librados::IoCtx::application_enable(const std::string& app_name,
2921 bool force)
2922{
2923 return io_ctx_impl->application_enable(app_name, force);
2924}
2925
2926int librados::IoCtx::application_enable_async(const std::string& app_name,
2927 bool force,
2928 PoolAsyncCompletion *c)
2929{
2930 io_ctx_impl->application_enable_async(app_name, force, c->pc);
2931 return 0;
2932}
2933
2934int librados::IoCtx::application_list(std::set<std::string> *app_names)
2935{
2936 return io_ctx_impl->application_list(app_names);
2937}
2938
2939int librados::IoCtx::application_metadata_get(const std::string& app_name,
2940 const std::string &key,
2941 std::string* value)
2942{
2943 return io_ctx_impl->application_metadata_get(app_name, key, value);
2944}
2945
2946int librados::IoCtx::application_metadata_set(const std::string& app_name,
2947 const std::string &key,
2948 const std::string& value)
2949{
2950 return io_ctx_impl->application_metadata_set(app_name, key, value);
2951}
2952
2953int librados::IoCtx::application_metadata_remove(const std::string& app_name,
2954 const std::string &key)
2955{
2956 return io_ctx_impl->application_metadata_remove(app_name, key);
2957}
2958
2959int librados::IoCtx::application_metadata_list(const std::string& app_name,
2960 std::map<std::string, std::string> *values)
2961{
2962 return io_ctx_impl->application_metadata_list(app_name, values);
2963}