]> git.proxmox.com Git - ceph.git/blame - ceph/src/librados/librados_cxx.cc
import ceph 14.2.5
[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
eafe8130
TL
1059bool librados::IoCtx::is_valid() const {
1060 return io_ctx_impl != nullptr;
1061}
1062
11fdf7f2
TL
1063void librados::IoCtx::close()
1064{
1065 if (io_ctx_impl)
1066 io_ctx_impl->put();
1067 io_ctx_impl = 0;
1068}
1069
1070void librados::IoCtx::dup(const IoCtx& rhs)
1071{
1072 if (io_ctx_impl)
1073 io_ctx_impl->put();
1074 io_ctx_impl = new IoCtxImpl();
1075 io_ctx_impl->get();
1076 io_ctx_impl->dup(*rhs.io_ctx_impl);
1077}
1078
1079int librados::IoCtx::set_auid(uint64_t auid_)
1080{
1081 return -EOPNOTSUPP;
1082}
1083
1084int librados::IoCtx::set_auid_async(uint64_t auid_, PoolAsyncCompletion *c)
1085{
1086 return -EOPNOTSUPP;
1087}
1088
1089int librados::IoCtx::get_auid(uint64_t *auid_)
1090{
1091 return -EOPNOTSUPP;
1092}
1093
1094bool librados::IoCtx::pool_requires_alignment()
1095{
1096 return io_ctx_impl->client->pool_requires_alignment(get_id());
1097}
1098
1099int librados::IoCtx::pool_requires_alignment2(bool *requires)
1100{
1101 return io_ctx_impl->client->pool_requires_alignment2(get_id(), requires);
1102}
1103
1104uint64_t librados::IoCtx::pool_required_alignment()
1105{
1106 return io_ctx_impl->client->pool_required_alignment(get_id());
1107}
1108
1109int librados::IoCtx::pool_required_alignment2(uint64_t *alignment)
1110{
1111 return io_ctx_impl->client->pool_required_alignment2(get_id(), alignment);
1112}
1113
1114std::string librados::IoCtx::get_pool_name()
1115{
1116 std::string s;
1117 io_ctx_impl->client->pool_get_name(get_id(), &s);
1118 return s;
1119}
1120
1121std::string librados::IoCtx::get_pool_name() const
1122{
1123 return io_ctx_impl->get_cached_pool_name();
1124}
1125
1126uint64_t librados::IoCtx::get_instance_id() const
1127{
1128 return io_ctx_impl->client->get_instance_id();
1129}
1130
1131int librados::IoCtx::create(const std::string& oid, bool exclusive)
1132{
1133 object_t obj(oid);
1134 return io_ctx_impl->create(obj, exclusive);
1135}
1136
1137int librados::IoCtx::create(const std::string& oid, bool exclusive,
1138 const std::string& category) // unused
1139{
1140 object_t obj(oid);
1141 return io_ctx_impl->create(obj, exclusive);
1142}
1143
1144int librados::IoCtx::write(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1145{
1146 object_t obj(oid);
1147 return io_ctx_impl->write(obj, bl, len, off);
1148}
1149
1150int librados::IoCtx::append(const std::string& oid, bufferlist& bl, size_t len)
1151{
1152 object_t obj(oid);
1153 return io_ctx_impl->append(obj, bl, len);
1154}
1155
1156int librados::IoCtx::write_full(const std::string& oid, bufferlist& bl)
1157{
1158 object_t obj(oid);
1159 return io_ctx_impl->write_full(obj, bl);
1160}
1161
1162int librados::IoCtx::writesame(const std::string& oid, bufferlist& bl,
1163 size_t write_len, uint64_t off)
1164{
1165 object_t obj(oid);
1166 return io_ctx_impl->writesame(obj, bl, write_len, off);
1167}
1168
1169
1170int librados::IoCtx::read(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1171{
1172 object_t obj(oid);
1173 return io_ctx_impl->read(obj, bl, len, off);
1174}
1175
1176int librados::IoCtx::checksum(const std::string& oid,
1177 rados_checksum_type_t type,
1178 const bufferlist &init_value_bl, size_t len,
1179 uint64_t off, size_t chunk_size, bufferlist *pbl)
1180{
1181 object_t obj(oid);
1182 return io_ctx_impl->checksum(obj, get_checksum_op_type(type), init_value_bl,
1183 len, off, chunk_size, pbl);
1184}
1185
1186int librados::IoCtx::remove(const std::string& oid)
1187{
1188 object_t obj(oid);
1189 return io_ctx_impl->remove(obj);
1190}
1191
1192int librados::IoCtx::remove(const std::string& oid, int flags)
1193{
1194 object_t obj(oid);
1195 return io_ctx_impl->remove(obj, flags);
1196}
1197
1198int librados::IoCtx::trunc(const std::string& oid, uint64_t size)
1199{
1200 object_t obj(oid);
1201 return io_ctx_impl->trunc(obj, size);
1202}
1203
1204int librados::IoCtx::mapext(const std::string& oid, uint64_t off, size_t len,
1205 std::map<uint64_t,uint64_t>& m)
1206{
1207 object_t obj(oid);
1208 return io_ctx_impl->mapext(obj, off, len, m);
1209}
1210
1211int librados::IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl)
1212{
1213 object_t obj(oid);
1214 return io_ctx_impl->cmpext(obj, off, cmp_bl);
1215}
1216
1217int librados::IoCtx::sparse_read(const std::string& oid, std::map<uint64_t,uint64_t>& m,
1218 bufferlist& bl, size_t len, uint64_t off)
1219{
1220 object_t obj(oid);
1221 return io_ctx_impl->sparse_read(obj, m, bl, len, off);
1222}
1223
1224int librados::IoCtx::getxattr(const std::string& oid, const char *name, bufferlist& bl)
1225{
1226 object_t obj(oid);
1227 return io_ctx_impl->getxattr(obj, name, bl);
1228}
1229
1230int librados::IoCtx::getxattrs(const std::string& oid, map<std::string, bufferlist>& attrset)
1231{
1232 object_t obj(oid);
1233 return io_ctx_impl->getxattrs(obj, attrset);
1234}
1235
1236int librados::IoCtx::setxattr(const std::string& oid, const char *name, bufferlist& bl)
1237{
1238 object_t obj(oid);
1239 return io_ctx_impl->setxattr(obj, name, bl);
1240}
1241
1242int librados::IoCtx::rmxattr(const std::string& oid, const char *name)
1243{
1244 object_t obj(oid);
1245 return io_ctx_impl->rmxattr(obj, name);
1246}
1247
1248int librados::IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtime)
1249{
1250 object_t obj(oid);
1251 return io_ctx_impl->stat(obj, psize, pmtime);
1252}
1253
1254int librados::IoCtx::stat2(const std::string& oid, uint64_t *psize, struct timespec *pts)
1255{
1256 object_t obj(oid);
1257 return io_ctx_impl->stat2(obj, psize, pts);
1258}
1259
1260int librados::IoCtx::exec(const std::string& oid, const char *cls, const char *method,
1261 bufferlist& inbl, bufferlist& outbl)
1262{
1263 object_t obj(oid);
1264 return io_ctx_impl->exec(obj, cls, method, inbl, outbl);
1265}
1266
1267int librados::IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl)
1268{
1269 object_t obj(oid);
1270 return io_ctx_impl->tmap_update(obj, cmdbl);
1271}
1272
1273int librados::IoCtx::omap_get_vals(const std::string& oid,
1274 const std::string& start_after,
1275 uint64_t max_return,
1276 std::map<std::string, bufferlist> *out_vals)
1277{
1278 return omap_get_vals(oid, start_after, string(), max_return, out_vals);
1279}
1280
1281int librados::IoCtx::omap_get_vals2(
1282 const std::string& oid,
1283 const std::string& start_after,
1284 uint64_t max_return,
1285 std::map<std::string, bufferlist> *out_vals,
1286 bool *pmore)
1287{
1288 ObjectReadOperation op;
1289 int r;
1290 op.omap_get_vals2(start_after, max_return, out_vals, pmore, &r);
1291 bufferlist bl;
1292 int ret = operate(oid, &op, &bl);
1293 if (ret < 0)
1294 return ret;
1295 return r;
1296}
1297
1298int librados::IoCtx::omap_get_keys(const std::string& oid,
1299 const std::string& orig_start_after,
1300 uint64_t max_return,
1301 std::set<std::string> *out_keys)
1302{
1303 bool first = true;
1304 string start_after = orig_start_after;
1305 bool more = true;
1306 while (max_return > 0 && more) {
1307 std::set<std::string> out;
1308 ObjectReadOperation op;
1309 op.omap_get_keys2(start_after, max_return, &out, &more, nullptr);
1310 bufferlist bl;
1311 int ret = operate(oid, &op, &bl);
1312 if (ret < 0) {
1313 return ret;
1314 }
1315 if (more) {
1316 if (out.empty()) {
1317 return -EINVAL; // wth
1318 }
1319 start_after = *out.rbegin();
1320 }
1321 if (out.size() <= max_return) {
1322 max_return -= out.size();
1323 } else {
1324 max_return = 0;
1325 }
1326 if (first) {
1327 out_keys->swap(out);
1328 first = false;
1329 } else {
1330 out_keys->insert(out.begin(), out.end());
1331 out.clear();
1332 }
1333 }
1334 return 0;
1335}
1336
1337int librados::IoCtx::omap_get_keys2(
1338 const std::string& oid,
1339 const std::string& start_after,
1340 uint64_t max_return,
1341 std::set<std::string> *out_keys,
1342 bool *pmore)
1343{
1344 ObjectReadOperation op;
1345 int r;
1346 op.omap_get_keys2(start_after, max_return, out_keys, pmore, &r);
1347 bufferlist bl;
1348 int ret = operate(oid, &op, &bl);
1349 if (ret < 0)
1350 return ret;
1351 return r;
1352}
1353
1354int librados::IoCtx::omap_get_header(const std::string& oid,
1355 bufferlist *bl)
1356{
1357 ObjectReadOperation op;
1358 int r;
1359 op.omap_get_header(bl, &r);
1360 bufferlist b;
1361 int ret = operate(oid, &op, &b);
1362 if (ret < 0)
1363 return ret;
1364
1365 return r;
1366}
1367
1368int librados::IoCtx::omap_get_vals_by_keys(const std::string& oid,
1369 const std::set<std::string>& keys,
1370 std::map<std::string, bufferlist> *vals)
1371{
1372 ObjectReadOperation op;
1373 int r;
1374 bufferlist bl;
1375 op.omap_get_vals_by_keys(keys, vals, &r);
1376 int ret = operate(oid, &op, &bl);
1377 if (ret < 0)
1378 return ret;
1379
1380 return r;
1381}
1382
1383int librados::IoCtx::omap_set(const std::string& oid,
1384 const map<string, bufferlist>& m)
1385{
1386 ObjectWriteOperation op;
1387 op.omap_set(m);
1388 return operate(oid, &op);
1389}
1390
1391int librados::IoCtx::omap_set_header(const std::string& oid,
1392 const bufferlist& bl)
1393{
1394 ObjectWriteOperation op;
1395 op.omap_set_header(bl);
1396 return operate(oid, &op);
1397}
1398
1399int librados::IoCtx::omap_clear(const std::string& oid)
1400{
1401 ObjectWriteOperation op;
1402 op.omap_clear();
1403 return operate(oid, &op);
1404}
1405
1406int librados::IoCtx::omap_rm_keys(const std::string& oid,
1407 const std::set<std::string>& keys)
1408{
1409 ObjectWriteOperation op;
1410 op.omap_rm_keys(keys);
1411 return operate(oid, &op);
1412}
1413
1414int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o)
1415{
1416 object_t obj(oid);
1417 return io_ctx_impl->operate(obj, &o->impl->o, (ceph::real_time *)o->impl->prt);
1418}
1419
1420int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl)
1421{
1422 object_t obj(oid);
1423 return io_ctx_impl->operate_read(obj, &o->impl->o, pbl);
1424}
1425
1426int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1427 librados::ObjectWriteOperation *o)
1428{
1429 object_t obj(oid);
1430 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1431 io_ctx_impl->snapc, 0);
1432}
1433int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1434 ObjectWriteOperation *o, int flags)
1435{
1436 object_t obj(oid);
1437 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1438 io_ctx_impl->snapc,
1439 translate_flags(flags));
1440}
1441
1442int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1443 librados::ObjectWriteOperation *o,
1444 snap_t snap_seq, std::vector<snap_t>& snaps)
1445{
1446 object_t obj(oid);
1447 vector<snapid_t> snv;
1448 snv.resize(snaps.size());
1449 for (size_t i = 0; i < snaps.size(); ++i)
1450 snv[i] = snaps[i];
1451 SnapContext snapc(snap_seq, snv);
1452 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1453 snapc, 0);
1454}
1455
1456int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1457 librados::ObjectWriteOperation *o,
1458 snap_t snap_seq, std::vector<snap_t>& snaps,
1459 const blkin_trace_info *trace_info)
1460{
1461 object_t obj(oid);
1462 vector<snapid_t> snv;
1463 snv.resize(snaps.size());
1464 for (size_t i = 0; i < snaps.size(); ++i)
1465 snv[i] = snaps[i];
1466 SnapContext snapc(snap_seq, snv);
1467 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1468 snapc, 0, trace_info);
1469}
1470
1471int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1472 librados::ObjectWriteOperation *o,
1473 snap_t snap_seq, std::vector<snap_t>& snaps, int flags,
1474 const blkin_trace_info *trace_info)
1475{
1476 object_t obj(oid);
1477 vector<snapid_t> snv;
1478 snv.resize(snaps.size());
1479 for (size_t i = 0; i < snaps.size(); ++i)
1480 snv[i] = snaps[i];
1481 SnapContext snapc(snap_seq, snv);
1482 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc, snapc,
1483 translate_flags(flags), trace_info);
1484}
1485
1486int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1487 librados::ObjectReadOperation *o,
1488 bufferlist *pbl)
1489{
1490 object_t obj(oid);
1491 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1492 0, pbl);
1493}
1494
1495// deprecated
1496int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1497 librados::ObjectReadOperation *o,
1498 snap_t snapid_unused_deprecated,
1499 int flags, bufferlist *pbl)
1500{
1501 object_t obj(oid);
1502 int op_flags = 0;
1503 if (flags & OPERATION_BALANCE_READS)
1504 op_flags |= CEPH_OSD_FLAG_BALANCE_READS;
1505 if (flags & OPERATION_LOCALIZE_READS)
1506 op_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
1507 if (flags & OPERATION_ORDER_READS_WRITES)
1508 op_flags |= CEPH_OSD_FLAG_RWORDERED;
1509
1510 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1511 op_flags, pbl);
1512}
1513
1514int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1515 librados::ObjectReadOperation *o,
1516 int flags, bufferlist *pbl)
1517{
1518 object_t obj(oid);
1519 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1520 translate_flags(flags), pbl);
1521}
1522
1523int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1524 librados::ObjectReadOperation *o,
1525 int flags, bufferlist *pbl, const blkin_trace_info *trace_info)
1526{
1527 object_t obj(oid);
1528 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1529 translate_flags(flags), pbl, trace_info);
1530}
1531
1532void librados::IoCtx::snap_set_read(snap_t seq)
1533{
1534 io_ctx_impl->set_snap_read(seq);
1535}
1536
1537int librados::IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq, vector<snap_t>& snaps)
1538{
1539 vector<snapid_t> snv;
1540 snv.resize(snaps.size());
1541 for (unsigned i=0; i<snaps.size(); i++)
1542 snv[i] = snaps[i];
1543 return io_ctx_impl->set_snap_write_context(seq, snv);
1544}
1545
1546int librados::IoCtx::snap_create(const char *snapname)
1547{
1548 return io_ctx_impl->snap_create(snapname);
1549}
1550
1551int librados::IoCtx::snap_lookup(const char *name, snap_t *snapid)
1552{
1553 return io_ctx_impl->snap_lookup(name, snapid);
1554}
1555
1556int librados::IoCtx::snap_get_stamp(snap_t snapid, time_t *t)
1557{
1558 return io_ctx_impl->snap_get_stamp(snapid, t);
1559}
1560
1561int librados::IoCtx::snap_get_name(snap_t snapid, std::string *s)
1562{
1563 return io_ctx_impl->snap_get_name(snapid, s);
1564}
1565
1566int librados::IoCtx::snap_remove(const char *snapname)
1567{
1568 return io_ctx_impl->snap_remove(snapname);
1569}
1570
1571int librados::IoCtx::snap_list(std::vector<snap_t> *snaps)
1572{
1573 return io_ctx_impl->snap_list(snaps);
1574}
1575
1576int librados::IoCtx::snap_rollback(const std::string& oid, const char *snapname)
1577{
1578 return io_ctx_impl->rollback(oid, snapname);
1579}
1580
1581// Deprecated name kept for backward compatibility
1582int librados::IoCtx::rollback(const std::string& oid, const char *snapname)
1583{
1584 return snap_rollback(oid, snapname);
1585}
1586
1587int librados::IoCtx::selfmanaged_snap_create(uint64_t *snapid)
1588{
1589 return io_ctx_impl->selfmanaged_snap_create(snapid);
1590}
1591
1592void librados::IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid,
1593 AioCompletion *c)
1594{
1595 io_ctx_impl->aio_selfmanaged_snap_create(snapid, c->pc);
1596}
1597
1598int librados::IoCtx::selfmanaged_snap_remove(uint64_t snapid)
1599{
1600 return io_ctx_impl->selfmanaged_snap_remove(snapid);
1601}
1602
1603void librados::IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid,
1604 AioCompletion *c)
1605{
1606 io_ctx_impl->aio_selfmanaged_snap_remove(snapid, c->pc);
1607}
1608
1609int librados::IoCtx::selfmanaged_snap_rollback(const std::string& oid, uint64_t snapid)
1610{
1611 return io_ctx_impl->selfmanaged_snap_rollback_object(oid,
1612 io_ctx_impl->snapc,
1613 snapid);
1614}
1615
1616int librados::IoCtx::lock_exclusive(const std::string &oid, const std::string &name,
1617 const std::string &cookie,
1618 const std::string &description,
1619 struct timeval * duration, uint8_t flags)
1620{
1621 utime_t dur = utime_t();
1622 if (duration)
1623 dur.set_from_timeval(duration);
1624
1625 return rados::cls::lock::lock(this, oid, name, LOCK_EXCLUSIVE, cookie, "",
1626 description, dur, flags);
1627}
1628
1629int librados::IoCtx::lock_shared(const std::string &oid, const std::string &name,
1630 const std::string &cookie, const std::string &tag,
1631 const std::string &description,
1632 struct timeval * duration, uint8_t flags)
1633{
1634 utime_t dur = utime_t();
1635 if (duration)
1636 dur.set_from_timeval(duration);
1637
1638 return rados::cls::lock::lock(this, oid, name, LOCK_SHARED, cookie, tag,
1639 description, dur, flags);
1640}
1641
1642int librados::IoCtx::unlock(const std::string &oid, const std::string &name,
1643 const std::string &cookie)
1644{
1645 return rados::cls::lock::unlock(this, oid, name, cookie);
1646}
1647
1648struct AioUnlockCompletion : public librados::ObjectOperationCompletion {
1649 librados::AioCompletionImpl *completion;
1650 AioUnlockCompletion(librados::AioCompletion *c) : completion(c->pc) {
1651 completion->get();
1652 };
1653 void handle_completion(int r, bufferlist& outbl) override {
1654 rados_callback_t cb = completion->callback_complete;
1655 void *cb_arg = completion->callback_complete_arg;
1656 cb(completion, cb_arg);
1657 completion->lock.Lock();
1658 completion->callback_complete = NULL;
1659 completion->cond.Signal();
1660 completion->put_unlock();
1661 }
1662};
1663
1664int librados::IoCtx::aio_unlock(const std::string &oid, const std::string &name,
1665 const std::string &cookie, AioCompletion *c)
1666{
1667 return rados::cls::lock::aio_unlock(this, oid, name, cookie, c);
1668}
1669
1670int librados::IoCtx::break_lock(const std::string &oid, const std::string &name,
1671 const std::string &client, const std::string &cookie)
1672{
1673 entity_name_t locker;
1674 if (!locker.parse(client))
1675 return -EINVAL;
1676 return rados::cls::lock::break_lock(this, oid, name, cookie, locker);
1677}
1678
1679int librados::IoCtx::list_lockers(const std::string &oid, const std::string &name,
1680 int *exclusive,
1681 std::string *tag,
1682 std::list<librados::locker_t> *lockers)
1683{
1684 std::list<librados::locker_t> tmp_lockers;
1685 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t> rados_lockers;
1686 std::string tmp_tag;
1687 ClsLockType tmp_type;
1688 int r = rados::cls::lock::get_lock_info(this, oid, name, &rados_lockers, &tmp_type, &tmp_tag);
1689 if (r < 0)
1690 return r;
1691
1692 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t>::iterator map_it;
1693 for (map_it = rados_lockers.begin(); map_it != rados_lockers.end(); ++map_it) {
1694 librados::locker_t locker;
1695 locker.client = stringify(map_it->first.locker);
1696 locker.cookie = map_it->first.cookie;
1697 locker.address = stringify(map_it->second.addr);
1698 tmp_lockers.push_back(locker);
1699 }
1700
1701 if (lockers)
1702 *lockers = tmp_lockers;
1703 if (tag)
1704 *tag = tmp_tag;
1705 if (exclusive) {
1706 if (tmp_type == LOCK_EXCLUSIVE)
1707 *exclusive = 1;
1708 else
1709 *exclusive = 0;
1710 }
1711
1712 return tmp_lockers.size();
1713}
1714
1715librados::NObjectIterator librados::IoCtx::nobjects_begin(
1716 const bufferlist &filter)
1717{
1718 rados_list_ctx_t listh;
1719 rados_nobjects_list_open(io_ctx_impl, &listh);
1720 NObjectIterator iter((ObjListCtx*)listh);
1721 if (filter.length() > 0) {
1722 iter.set_filter(filter);
1723 }
1724 iter.get_next();
1725 return iter;
1726}
1727
1728librados::NObjectIterator librados::IoCtx::nobjects_begin(
1729 uint32_t pos, const bufferlist &filter)
1730{
1731 rados_list_ctx_t listh;
1732 rados_nobjects_list_open(io_ctx_impl, &listh);
1733 NObjectIterator iter((ObjListCtx*)listh);
1734 if (filter.length() > 0) {
1735 iter.set_filter(filter);
1736 }
1737 iter.seek(pos);
1738 return iter;
1739}
1740
1741librados::NObjectIterator librados::IoCtx::nobjects_begin(
1742 const ObjectCursor& cursor, const bufferlist &filter)
1743{
1744 rados_list_ctx_t listh;
1745 rados_nobjects_list_open(io_ctx_impl, &listh);
1746 NObjectIterator iter((ObjListCtx*)listh);
1747 if (filter.length() > 0) {
1748 iter.set_filter(filter);
1749 }
1750 iter.seek(cursor);
1751 return iter;
1752}
1753
1754const librados::NObjectIterator& librados::IoCtx::nobjects_end() const
1755{
1756 return NObjectIterator::__EndObjectIterator;
1757}
1758
1759int librados::IoCtx::hit_set_list(uint32_t hash, AioCompletion *c,
1760 std::list< std::pair<time_t, time_t> > *pls)
1761{
1762 return io_ctx_impl->hit_set_list(hash, c->pc, pls);
1763}
1764
1765int librados::IoCtx::hit_set_get(uint32_t hash, AioCompletion *c, time_t stamp,
1766 bufferlist *pbl)
1767{
1768 return io_ctx_impl->hit_set_get(hash, c->pc, stamp, pbl);
1769}
1770
1771
1772
1773uint64_t librados::IoCtx::get_last_version()
1774{
1775 return io_ctx_impl->last_version();
1776}
1777
1778int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1779 bufferlist *pbl, size_t len, uint64_t off)
1780{
1781 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off,
1782 io_ctx_impl->snap_seq);
1783}
1784
1785int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1786 bufferlist *pbl, size_t len, uint64_t off,
1787 uint64_t snapid)
1788{
1789 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off, snapid);
1790}
1791
1792int librados::IoCtx::aio_exec(const std::string& oid,
1793 librados::AioCompletion *c, const char *cls,
1794 const char *method, bufferlist& inbl,
1795 bufferlist *outbl)
1796{
1797 object_t obj(oid);
1798 return io_ctx_impl->aio_exec(obj, c->pc, cls, method, inbl, outbl);
1799}
1800
1801int librados::IoCtx::aio_cmpext(const std::string& oid,
1802 librados::AioCompletion *c,
1803 uint64_t off,
1804 bufferlist& cmp_bl)
1805{
1806 return io_ctx_impl->aio_cmpext(oid, c->pc, off, cmp_bl);
1807}
1808
1809int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1810 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1811 size_t len, uint64_t off)
1812{
1813 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1814 m, data_bl, len, off,
1815 io_ctx_impl->snap_seq);
1816}
1817
1818int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1819 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1820 size_t len, uint64_t off, uint64_t snapid)
1821{
1822 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1823 m, data_bl, len, off, snapid);
1824}
1825
1826int librados::IoCtx::aio_write(const std::string& oid, librados::AioCompletion *c,
1827 const bufferlist& bl, size_t len, uint64_t off)
1828{
1829 return io_ctx_impl->aio_write(oid, c->pc, bl, len, off);
1830}
1831
1832int librados::IoCtx::aio_append(const std::string& oid, librados::AioCompletion *c,
1833 const bufferlist& bl, size_t len)
1834{
1835 return io_ctx_impl->aio_append(oid, c->pc, bl, len);
1836}
1837
1838int librados::IoCtx::aio_write_full(const std::string& oid, librados::AioCompletion *c,
1839 const bufferlist& bl)
1840{
1841 object_t obj(oid);
1842 return io_ctx_impl->aio_write_full(obj, c->pc, bl);
1843}
1844
1845int librados::IoCtx::aio_writesame(const std::string& oid, librados::AioCompletion *c,
1846 const bufferlist& bl, size_t write_len,
1847 uint64_t off)
1848{
1849 return io_ctx_impl->aio_writesame(oid, c->pc, bl, write_len, off);
1850}
1851
1852
1853int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c)
1854{
1855 return io_ctx_impl->aio_remove(oid, c->pc);
1856}
1857
1858int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c, int flags)
1859{
1860 return io_ctx_impl->aio_remove(oid, c->pc, flags);
1861}
1862
1863int librados::IoCtx::aio_flush_async(librados::AioCompletion *c)
1864{
1865 io_ctx_impl->flush_aio_writes_async(c->pc);
1866 return 0;
1867}
1868
1869int librados::IoCtx::aio_flush()
1870{
1871 io_ctx_impl->flush_aio_writes();
1872 return 0;
1873}
1874
1875struct AioGetxattrDataPP {
1876 AioGetxattrDataPP(librados::AioCompletionImpl *c, bufferlist *_bl) :
1877 bl(_bl), completion(c) {}
1878 bufferlist *bl;
1879 struct librados::C_AioCompleteAndSafe completion;
1880};
1881
1882static void rados_aio_getxattr_completepp(rados_completion_t c, void *arg) {
1883 AioGetxattrDataPP *cdata = reinterpret_cast<AioGetxattrDataPP*>(arg);
1884 int rc = rados_aio_get_return_value(c);
1885 if (rc >= 0) {
1886 rc = cdata->bl->length();
1887 }
1888 cdata->completion.finish(rc);
1889 delete cdata;
1890}
1891
1892int librados::IoCtx::aio_getxattr(const std::string& oid, librados::AioCompletion *c,
1893 const char *name, bufferlist& bl)
1894{
1895 // create data object to be passed to async callback
1896 AioGetxattrDataPP *cdata = new AioGetxattrDataPP(c->pc, &bl);
1897 if (!cdata) {
1898 return -ENOMEM;
1899 }
1900 // create completion callback
1901 librados::AioCompletionImpl *comp = new librados::AioCompletionImpl;
1902 comp->set_complete_callback(cdata, rados_aio_getxattr_completepp);
1903 // call actual getxattr from IoCtxImpl
1904 object_t obj(oid);
1905 return io_ctx_impl->aio_getxattr(obj, comp, name, bl);
1906}
1907
1908int librados::IoCtx::aio_getxattrs(const std::string& oid, AioCompletion *c,
1909 map<std::string, bufferlist>& attrset)
1910{
1911 object_t obj(oid);
1912 return io_ctx_impl->aio_getxattrs(obj, c->pc, attrset);
1913}
1914
1915int librados::IoCtx::aio_setxattr(const std::string& oid, AioCompletion *c,
1916 const char *name, bufferlist& bl)
1917{
1918 object_t obj(oid);
1919 return io_ctx_impl->aio_setxattr(obj, c->pc, name, bl);
1920}
1921
1922int librados::IoCtx::aio_rmxattr(const std::string& oid, AioCompletion *c,
1923 const char *name)
1924{
1925 object_t obj(oid);
1926 return io_ctx_impl->aio_rmxattr(obj, c->pc, name);
1927}
1928
1929int librados::IoCtx::aio_stat(const std::string& oid, librados::AioCompletion *c,
1930 uint64_t *psize, time_t *pmtime)
1931{
1932 object_t obj(oid);
1933 return io_ctx_impl->aio_stat(obj, c->pc, psize, pmtime);
1934}
1935
1936int librados::IoCtx::aio_cancel(librados::AioCompletion *c)
1937{
1938 return io_ctx_impl->aio_cancel(c->pc);
1939}
1940
1941int librados::IoCtx::watch(const string& oid, uint64_t ver, uint64_t *cookie,
1942 librados::WatchCtx *ctx)
1943{
1944 object_t obj(oid);
1945 return io_ctx_impl->watch(obj, cookie, ctx, NULL);
1946}
1947
1948int librados::IoCtx::watch2(const string& oid, uint64_t *cookie,
1949 librados::WatchCtx2 *ctx2)
1950{
1951 object_t obj(oid);
1952 return io_ctx_impl->watch(obj, cookie, NULL, ctx2);
1953}
1954
1955int librados::IoCtx::watch3(const string& oid, uint64_t *cookie,
1956 librados::WatchCtx2 *ctx2, uint32_t timeout)
1957{
1958 object_t obj(oid);
1959 return io_ctx_impl->watch(obj, cookie, NULL, ctx2, timeout);
1960}
1961
1962int librados::IoCtx::aio_watch(const string& oid, AioCompletion *c,
1963 uint64_t *cookie,
1964 librados::WatchCtx2 *ctx2)
1965{
1966 object_t obj(oid);
1967 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2);
1968}
1969
1970int librados::IoCtx::aio_watch2(const string& oid, AioCompletion *c,
1971 uint64_t *cookie,
1972 librados::WatchCtx2 *ctx2,
1973 uint32_t timeout)
1974{
1975 object_t obj(oid);
1976 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2, timeout);
1977}
1978
1979int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
1980{
1981 return io_ctx_impl->unwatch(handle);
1982}
1983
1984int librados::IoCtx::unwatch2(uint64_t handle)
1985{
1986 return io_ctx_impl->unwatch(handle);
1987}
1988
1989int librados::IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c)
1990{
1991 return io_ctx_impl->aio_unwatch(handle, c->pc);
1992}
1993
1994int librados::IoCtx::watch_check(uint64_t handle)
1995{
1996 return io_ctx_impl->watch_check(handle);
1997}
1998
1999int librados::IoCtx::notify(const string& oid, uint64_t ver, bufferlist& bl)
2000{
2001 object_t obj(oid);
2002 return io_ctx_impl->notify(obj, bl, 0, NULL, NULL, NULL);
2003}
2004
2005int librados::IoCtx::notify2(const string& oid, bufferlist& bl,
2006 uint64_t timeout_ms, bufferlist *preplybl)
2007{
2008 object_t obj(oid);
2009 return io_ctx_impl->notify(obj, bl, timeout_ms, preplybl, NULL, NULL);
2010}
2011
2012int librados::IoCtx::aio_notify(const string& oid, AioCompletion *c,
2013 bufferlist& bl, uint64_t timeout_ms,
2014 bufferlist *preplybl)
2015{
2016 object_t obj(oid);
2017 return io_ctx_impl->aio_notify(obj, c->pc, bl, timeout_ms, preplybl, NULL,
2018 NULL);
2019}
2020
2021void librados::IoCtx::notify_ack(const std::string& o,
2022 uint64_t notify_id, uint64_t handle,
2023 bufferlist& bl)
2024{
2025 io_ctx_impl->notify_ack(o, notify_id, handle, bl);
2026}
2027
2028int librados::IoCtx::list_watchers(const std::string& oid,
2029 std::list<obj_watch_t> *out_watchers)
2030{
2031 ObjectReadOperation op;
2032 int r;
2033 op.list_watchers(out_watchers, &r);
2034 bufferlist bl;
2035 int ret = operate(oid, &op, &bl);
2036 if (ret < 0)
2037 return ret;
2038
2039 return r;
2040}
2041
2042int librados::IoCtx::list_snaps(const std::string& oid,
2043 snap_set_t *out_snaps)
2044{
2045 ObjectReadOperation op;
2046 int r;
2047 if (io_ctx_impl->snap_seq != CEPH_SNAPDIR)
2048 return -EINVAL;
2049 op.list_snaps(out_snaps, &r);
2050 bufferlist bl;
2051 int ret = operate(oid, &op, &bl);
2052 if (ret < 0)
2053 return ret;
2054
2055 return r;
2056}
2057
2058void librados::IoCtx::set_notify_timeout(uint32_t timeout)
2059{
2060 io_ctx_impl->set_notify_timeout(timeout);
2061}
2062
2063int librados::IoCtx::set_alloc_hint(const std::string& o,
2064 uint64_t expected_object_size,
2065 uint64_t expected_write_size)
2066{
2067 object_t oid(o);
2068 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2069 expected_write_size, 0);
2070}
2071
2072int librados::IoCtx::set_alloc_hint2(const std::string& o,
2073 uint64_t expected_object_size,
2074 uint64_t expected_write_size,
2075 uint32_t flags)
2076{
2077 object_t oid(o);
2078 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2079 expected_write_size, flags);
2080}
2081
2082void librados::IoCtx::set_assert_version(uint64_t ver)
2083{
2084 io_ctx_impl->set_assert_version(ver);
2085}
2086
2087void librados::IoCtx::locator_set_key(const string& key)
2088{
2089 io_ctx_impl->oloc.key = key;
2090}
2091
2092void librados::IoCtx::set_namespace(const string& nspace)
2093{
2094 io_ctx_impl->oloc.nspace = nspace;
2095}
2096
2097std::string librados::IoCtx::get_namespace() const
2098{
2099 return io_ctx_impl->oloc.nspace;
2100}
2101
2102int64_t librados::IoCtx::get_id()
2103{
2104 return io_ctx_impl->get_id();
2105}
2106
2107uint32_t librados::IoCtx::get_object_hash_position(const std::string& oid)
2108{
2109 uint32_t hash;
2110 int r = io_ctx_impl->get_object_hash_position(oid, &hash);
2111 if (r < 0)
2112 hash = 0;
2113 return hash;
2114}
2115
2116uint32_t librados::IoCtx::get_object_pg_hash_position(const std::string& oid)
2117{
2118 uint32_t hash;
2119 int r = io_ctx_impl->get_object_pg_hash_position(oid, &hash);
2120 if (r < 0)
2121 hash = 0;
2122 return hash;
2123}
2124
2125int librados::IoCtx::get_object_hash_position2(
2126 const std::string& oid, uint32_t *hash_position)
2127{
2128 return io_ctx_impl->get_object_hash_position(oid, hash_position);
2129}
2130
2131int librados::IoCtx::get_object_pg_hash_position2(
2132 const std::string& oid, uint32_t *pg_hash_position)
2133{
2134 return io_ctx_impl->get_object_pg_hash_position(oid, pg_hash_position);
2135}
2136
2137librados::config_t librados::IoCtx::cct()
2138{
2139 return (config_t)io_ctx_impl->client->cct;
2140}
2141
2142librados::IoCtx::IoCtx(IoCtxImpl *io_ctx_impl_)
2143 : io_ctx_impl(io_ctx_impl_)
2144{
2145}
2146
2147void librados::IoCtx::set_osdmap_full_try()
2148{
2149 io_ctx_impl->objecter->set_osdmap_full_try();
2150}
2151
2152void librados::IoCtx::unset_osdmap_full_try()
2153{
2154 io_ctx_impl->objecter->unset_osdmap_full_try();
2155}
2156
2157///////////////////////////// Rados //////////////////////////////
2158void librados::Rados::version(int *major, int *minor, int *extra)
2159{
2160 rados_version(major, minor, extra);
2161}
2162
2163librados::Rados::Rados() : client(NULL)
2164{
2165}
2166
2167librados::Rados::Rados(IoCtx &ioctx)
2168{
2169 client = ioctx.io_ctx_impl->client;
2170 ceph_assert(client != NULL);
2171 client->get();
2172}
2173
2174librados::Rados::~Rados()
2175{
2176 shutdown();
2177}
2178
eafe8130
TL
2179void librados::Rados::from_rados_t(rados_t cluster, Rados &rados) {
2180 if (rados.client) {
2181 rados.client->put();
2182 }
2183 rados.client = static_cast<RadosClient*>(cluster);
2184 if (rados.client) {
2185 rados.client->get();
2186 }
2187}
2188
11fdf7f2
TL
2189int librados::Rados::init(const char * const id)
2190{
2191 return rados_create((rados_t *)&client, id);
2192}
2193
2194int librados::Rados::init2(const char * const name,
2195 const char * const clustername, uint64_t flags)
2196{
2197 return rados_create2((rados_t *)&client, clustername, name, flags);
2198}
2199
2200int librados::Rados::init_with_context(config_t cct_)
2201{
2202 return rados_create_with_context((rados_t *)&client, (rados_config_t)cct_);
2203}
2204
2205int librados::Rados::connect()
2206{
2207 return client->connect();
2208}
2209
2210librados::config_t librados::Rados::cct()
2211{
2212 return (config_t)client->cct;
2213}
2214
2215int librados::Rados::watch_flush()
2216{
2217 if (!client)
2218 return -EINVAL;
2219 return client->watch_flush();
2220}
2221
2222int librados::Rados::aio_watch_flush(AioCompletion *c)
2223{
2224 if (!client)
2225 return -EINVAL;
2226 return client->async_watch_flush(c->pc);
2227}
2228
2229void librados::Rados::shutdown()
2230{
2231 if (!client)
2232 return;
2233 if (client->put()) {
2234 client->shutdown();
2235 delete client;
2236 client = NULL;
2237 }
2238}
2239
2240uint64_t librados::Rados::get_instance_id()
2241{
2242 return client->get_instance_id();
2243}
2244
2245int librados::Rados::get_min_compatible_osd(int8_t* require_osd_release)
2246{
2247 return client->get_min_compatible_osd(require_osd_release);
2248}
2249
2250int librados::Rados::get_min_compatible_client(int8_t* min_compat_client,
2251 int8_t* require_min_compat_client)
2252{
2253 return client->get_min_compatible_client(min_compat_client,
2254 require_min_compat_client);
2255}
2256
2257int librados::Rados::conf_read_file(const char * const path) const
2258{
2259 return rados_conf_read_file((rados_t)client, path);
2260}
2261
2262int librados::Rados::conf_parse_argv(int argc, const char ** argv) const
2263{
2264 return rados_conf_parse_argv((rados_t)client, argc, argv);
2265}
2266
2267int librados::Rados::conf_parse_argv_remainder(int argc, const char ** argv,
2268 const char ** remargv) const
2269{
2270 return rados_conf_parse_argv_remainder((rados_t)client, argc, argv, remargv);
2271}
2272
2273int librados::Rados::conf_parse_env(const char *name) const
2274{
2275 return rados_conf_parse_env((rados_t)client, name);
2276}
2277
2278int librados::Rados::conf_set(const char *option, const char *value)
2279{
2280 return rados_conf_set((rados_t)client, option, value);
2281}
2282
2283int librados::Rados::conf_get(const char *option, std::string &val)
2284{
2285 char *str = NULL;
2286 const auto& conf = client->cct->_conf;
2287 int ret = conf.get_val(option, &str, -1);
2288 if (ret) {
2289 free(str);
2290 return ret;
2291 }
2292 val = str;
2293 free(str);
2294 return 0;
2295}
2296
2297int librados::Rados::service_daemon_register(
2298 const std::string& service, ///< service name (e.g., 'rgw')
2299 const std::string& name, ///< daemon name (e.g., 'gwfoo')
2300 const std::map<std::string,std::string>& metadata) ///< static metadata about daemon
2301{
2302 return client->service_daemon_register(service, name, metadata);
2303}
2304
2305int librados::Rados::service_daemon_update_status(
2306 std::map<std::string,std::string>&& status)
2307{
2308 return client->service_daemon_update_status(std::move(status));
2309}
2310
2311int librados::Rados::pool_create(const char *name)
2312{
2313 string str(name);
2314 return client->pool_create(str);
2315}
2316
2317int librados::Rados::pool_create(const char *name, uint64_t auid)
2318{
2319 if (auid != CEPH_AUTH_UID_DEFAULT) {
2320 return -EINVAL;
2321 }
2322 string str(name);
2323 return client->pool_create(str);
2324}
2325
2326int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule)
2327{
2328 if (auid != CEPH_AUTH_UID_DEFAULT) {
2329 return -EINVAL;
2330 }
2331 string str(name);
2332 return client->pool_create(str, crush_rule);
2333}
2334
2335int librados::Rados::pool_create_with_rule(const char *name, __u8 crush_rule)
2336{
2337 string str(name);
2338 return client->pool_create(str, crush_rule);
2339}
2340
2341int librados::Rados::pool_create_async(const char *name, PoolAsyncCompletion *c)
2342{
2343 string str(name);
2344 return client->pool_create_async(str, c->pc);
2345}
2346
2347int librados::Rados::pool_create_async(const char *name, uint64_t auid, PoolAsyncCompletion *c)
2348{
2349 if (auid != CEPH_AUTH_UID_DEFAULT) {
2350 return -EINVAL;
2351 }
2352 string str(name);
2353 return client->pool_create_async(str, c->pc);
2354}
2355
2356int librados::Rados::pool_create_async(const char *name, uint64_t auid, __u8 crush_rule,
2357 PoolAsyncCompletion *c)
2358{
2359 if (auid != CEPH_AUTH_UID_DEFAULT) {
2360 return -EINVAL;
2361 }
2362 string str(name);
2363 return client->pool_create_async(str, c->pc, crush_rule);
2364}
2365
2366int librados::Rados::pool_create_with_rule_async(
2367 const char *name, __u8 crush_rule,
2368 PoolAsyncCompletion *c)
2369{
2370 string str(name);
2371 return client->pool_create_async(str, c->pc, crush_rule);
2372}
2373
2374int librados::Rados::pool_get_base_tier(int64_t pool_id, int64_t* base_tier)
2375{
2376 tracepoint(librados, rados_pool_get_base_tier_enter, (rados_t)client, pool_id);
2377 int retval = client->pool_get_base_tier(pool_id, base_tier);
2378 tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
2379 return retval;
2380}
2381
2382int librados::Rados::pool_delete(const char *name)
2383{
2384 return client->pool_delete(name);
2385}
2386
2387int librados::Rados::pool_delete_async(const char *name, PoolAsyncCompletion *c)
2388{
2389 return client->pool_delete_async(name, c->pc);
2390}
2391
2392int librados::Rados::pool_list(std::list<std::string>& v)
2393{
2394 std::list<std::pair<int64_t, std::string> > pools;
2395 int r = client->pool_list(pools);
2396 if (r < 0) {
2397 return r;
2398 }
2399
2400 v.clear();
2401 for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin();
2402 it != pools.end(); ++it) {
2403 v.push_back(it->second);
2404 }
2405 return 0;
2406}
2407
2408int librados::Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v)
2409{
2410 return client->pool_list(v);
2411}
2412
2413int64_t librados::Rados::pool_lookup(const char *name)
2414{
2415 return client->lookup_pool(name);
2416}
2417
2418int librados::Rados::pool_reverse_lookup(int64_t id, std::string *name)
2419{
2420 return client->pool_get_name(id, name);
2421}
2422
2423int librados::Rados::mon_command(string cmd, const bufferlist& inbl,
2424 bufferlist *outbl, string *outs)
2425{
2426 vector<string> cmdvec;
2427 cmdvec.push_back(cmd);
2428 return client->mon_command(cmdvec, inbl, outbl, outs);
2429}
2430
2431int librados::Rados::osd_command(int osdid, std::string cmd, const bufferlist& inbl,
2432 bufferlist *outbl, std::string *outs)
2433{
2434 vector<string> cmdvec;
2435 cmdvec.push_back(cmd);
2436 return client->osd_command(osdid, cmdvec, inbl, outbl, outs);
2437}
2438
2439int librados::Rados::mgr_command(std::string cmd, const bufferlist& inbl,
2440 bufferlist *outbl, std::string *outs)
2441{
2442 vector<string> cmdvec;
2443 cmdvec.push_back(cmd);
2444 return client->mgr_command(cmdvec, inbl, outbl, outs);
2445}
2446
2447
2448
2449int librados::Rados::pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
2450 bufferlist *outbl, std::string *outs)
2451{
2452 vector<string> cmdvec;
2453 cmdvec.push_back(cmd);
2454
2455 pg_t pgid;
2456 if (!pgid.parse(pgstr))
2457 return -EINVAL;
2458
2459 return client->pg_command(pgid, cmdvec, inbl, outbl, outs);
2460}
2461
2462int librados::Rados::ioctx_create(const char *name, IoCtx &io)
2463{
2464 rados_ioctx_t p;
2465 int ret = rados_ioctx_create((rados_t)client, name, &p);
2466 if (ret)
2467 return ret;
2468 io.close();
2469 io.io_ctx_impl = (IoCtxImpl*)p;
2470 return 0;
2471}
2472
2473int librados::Rados::ioctx_create2(int64_t pool_id, IoCtx &io)
2474{
2475 rados_ioctx_t p;
2476 int ret = rados_ioctx_create2((rados_t)client, pool_id, &p);
2477 if (ret)
2478 return ret;
2479 io.close();
2480 io.io_ctx_impl = (IoCtxImpl*)p;
2481 return 0;
2482}
2483
2484void librados::Rados::test_blacklist_self(bool set)
2485{
2486 client->blacklist_self(set);
2487}
2488
2489int librados::Rados::get_pool_stats(std::list<string>& v,
2490 stats_map& result)
2491{
2492 map<string,::pool_stat_t> rawresult;
81eedcae
TL
2493 bool per_pool = false;
2494 int r = client->get_pool_stats(v, &rawresult, &per_pool);
11fdf7f2
TL
2495 for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
2496 p != rawresult.end();
2497 ++p) {
2498 pool_stat_t& pv = result[p->first];
2499 auto& pstat = p->second;
2500 store_statfs_t &statfs = pstat.store_stats;
81eedcae 2501 uint64_t allocated_bytes = pstat.get_allocated_bytes(per_pool);
11fdf7f2
TL
2502 // FIXME: raw_used_rate is unknown hence use 1.0 here
2503 // meaning we keep net amount aggregated over all replicas
2504 // Not a big deal so far since this field isn't exposed
81eedcae 2505 uint64_t user_bytes = pstat.get_user_bytes(1.0, per_pool);
11fdf7f2
TL
2506
2507 object_stat_sum_t *sum = &p->second.stats.sum;
2508 pv.num_kb = shift_round_up(allocated_bytes, 10);
2509 pv.num_bytes = allocated_bytes;
2510 pv.num_objects = sum->num_objects;
2511 pv.num_object_clones = sum->num_object_clones;
2512 pv.num_object_copies = sum->num_object_copies;
2513 pv.num_objects_missing_on_primary = sum->num_objects_missing_on_primary;
2514 pv.num_objects_unfound = sum->num_objects_unfound;
2515 pv.num_objects_degraded = sum->num_objects_degraded;
2516 pv.num_rd = sum->num_rd;
2517 pv.num_rd_kb = sum->num_rd_kb;
2518 pv.num_wr = sum->num_wr;
2519 pv.num_wr_kb = sum->num_wr_kb;
2520 pv.num_user_bytes = user_bytes;
2521 pv.compressed_bytes_orig = statfs.data_compressed_original;
2522 pv.compressed_bytes = statfs.data_compressed;
2523 pv.compressed_bytes_alloc = statfs.data_compressed_allocated;
2524 }
2525 return r;
2526}
2527
2528int librados::Rados::get_pool_stats(std::list<string>& v,
2529 std::map<string, stats_map>& result)
2530{
2531 stats_map m;
2532 int r = get_pool_stats(v, m);
2533 if (r < 0)
2534 return r;
2535 for (map<string,pool_stat_t>::iterator p = m.begin();
2536 p != m.end();
2537 ++p) {
2538 result[p->first][string()] = p->second;
2539 }
2540 return r;
2541}
2542
2543int librados::Rados::get_pool_stats(std::list<string>& v,
2544 string& category, // unused
2545 std::map<string, stats_map>& result)
2546{
2547 return -EOPNOTSUPP;
2548}
2549
2550bool librados::Rados::get_pool_is_selfmanaged_snaps_mode(const std::string& pool)
2551{
2552 return client->get_pool_is_selfmanaged_snaps_mode(pool);
2553}
2554
2555int librados::Rados::cluster_stat(cluster_stat_t& result)
2556{
2557 ceph_statfs stats;
2558 int r = client->get_fs_stats(stats);
2559 result.kb = stats.kb;
2560 result.kb_used = stats.kb_used;
2561 result.kb_avail = stats.kb_avail;
2562 result.num_objects = stats.num_objects;
2563 return r;
2564}
2565
2566int librados::Rados::cluster_fsid(string *fsid)
2567{
2568 return client->get_fsid(fsid);
2569}
2570
2571namespace librados {
2572 struct PlacementGroupImpl {
2573 pg_t pgid;
2574 };
2575
2576 PlacementGroup::PlacementGroup()
2577 : impl{new PlacementGroupImpl}
2578 {}
2579
2580 PlacementGroup::PlacementGroup(const PlacementGroup& pg)
2581 : impl{new PlacementGroupImpl}
2582 {
2583 impl->pgid = pg.impl->pgid;
2584 }
2585
2586 PlacementGroup::~PlacementGroup()
2587 {}
2588
2589 bool PlacementGroup::parse(const char* s)
2590 {
2591 return impl->pgid.parse(s);
2592 }
2593}
2594
2595std::ostream& librados::operator<<(std::ostream& out,
2596 const librados::PlacementGroup& pg)
2597{
2598 return out << pg.impl->pgid;
2599}
2600
2601int librados::Rados::get_inconsistent_pgs(int64_t pool_id,
2602 std::vector<PlacementGroup>* pgs)
2603{
2604 std::vector<string> pgids;
2605 if (auto ret = client->get_inconsistent_pgs(pool_id, &pgids); ret) {
2606 return ret;
2607 }
2608 for (const auto& pgid : pgids) {
2609 librados::PlacementGroup pg;
2610 if (!pg.parse(pgid.c_str())) {
2611 return -EINVAL;
2612 }
2613 pgs->emplace_back(pg);
2614 }
2615 return 0;
2616}
2617
2618int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
2619 const object_id_t &start_after,
2620 unsigned max_return,
2621 AioCompletion *c,
2622 std::vector<inconsistent_obj_t>* objects,
2623 uint32_t* interval)
2624{
2625 IoCtx ioctx;
2626 const pg_t pgid = pg.impl->pgid;
2627 int r = ioctx_create2(pgid.pool(), ioctx);
2628 if (r < 0) {
2629 return r;
2630 }
2631
2632 return ioctx.io_ctx_impl->get_inconsistent_objects(pgid,
2633 start_after,
2634 max_return,
2635 c->pc,
2636 objects,
2637 interval);
2638}
2639
2640int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
2641 const object_id_t &start_after,
2642 unsigned max_return,
2643 AioCompletion *c,
2644 std::vector<inconsistent_snapset_t>* snapsets,
2645 uint32_t* interval)
2646{
2647 IoCtx ioctx;
2648 const pg_t pgid = pg.impl->pgid;
2649 int r = ioctx_create2(pgid.pool(), ioctx);
2650 if (r < 0) {
2651 return r;
2652 }
2653
2654 return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
2655 start_after,
2656 max_return,
2657 c->pc,
2658 snapsets,
2659 interval);
2660}
2661
2662int librados::Rados::wait_for_latest_osdmap()
2663{
2664 return client->wait_for_latest_osdmap();
2665}
2666
2667int librados::Rados::blacklist_add(const std::string& client_address,
2668 uint32_t expire_seconds)
2669{
2670 return client->blacklist_add(client_address, expire_seconds);
2671}
2672
2673librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
2674{
2675 PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
2676 return new PoolAsyncCompletion(c);
2677}
2678
2679librados::AioCompletion *librados::Rados::aio_create_completion()
2680{
2681 AioCompletionImpl *c = new AioCompletionImpl;
2682 return new AioCompletion(c);
2683}
2684
2685librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
2686 callback_t cb_complete,
2687 callback_t cb_safe)
2688{
2689 AioCompletionImpl *c;
2690 int r = rados_aio_create_completion(cb_arg, cb_complete, cb_safe, (void**)&c);
2691 ceph_assert(r == 0);
2692 return new AioCompletion(c);
2693}
2694
2695librados::ObjectOperation::ObjectOperation()
2696{
2697 impl = new ObjectOperationImpl;
2698}
2699
2700librados::ObjectOperation::~ObjectOperation()
2701{
2702 delete impl;
2703}
2704
2705///////////////////////////// ListObject //////////////////////////////
2706librados::ListObject::ListObject() : impl(NULL)
2707{
2708}
2709
2710librados::ListObject::ListObject(librados::ListObjectImpl *i): impl(i)
2711{
2712}
2713
2714librados::ListObject::ListObject(const ListObject& rhs)
2715{
2716 if (rhs.impl == NULL) {
2717 impl = NULL;
2718 return;
2719 }
2720 impl = new ListObjectImpl();
2721 *impl = *(rhs.impl);
2722}
2723
2724librados::ListObject& librados::ListObject::operator=(const ListObject& rhs)
2725{
2726 if (rhs.impl == NULL) {
2727 delete impl;
2728 impl = NULL;
2729 return *this;
2730 }
2731 if (impl == NULL)
2732 impl = new ListObjectImpl();
2733 *impl = *(rhs.impl);
2734 return *this;
2735}
2736
2737librados::ListObject::~ListObject()
2738{
2739 if (impl)
2740 delete impl;
2741 impl = NULL;
2742}
2743
2744const std::string& librados::ListObject::get_nspace() const
2745{
2746 return impl->get_nspace();
2747}
2748
2749const std::string& librados::ListObject::get_oid() const
2750{
2751 return impl->get_oid();
2752}
2753
2754const std::string& librados::ListObject::get_locator() const
2755{
2756 return impl->get_locator();
2757}
2758
2759std::ostream& librados::operator<<(std::ostream& out, const librados::ListObject& lop)
2760{
2761 out << *(lop.impl);
2762 return out;
2763}
2764
2765librados::ObjectCursor::ObjectCursor()
2766{
2767 c_cursor = (rados_object_list_cursor)new hobject_t();
2768}
2769
2770librados::ObjectCursor::~ObjectCursor()
2771{
2772 hobject_t *h = (hobject_t *)c_cursor;
2773 delete h;
2774}
2775
2776librados::ObjectCursor::ObjectCursor(rados_object_list_cursor c)
2777{
2778 if (!c) {
2779 c_cursor = nullptr;
2780 } else {
2781 c_cursor = (rados_object_list_cursor)new hobject_t(*(hobject_t *)c);
2782 }
2783}
2784
2785librados::ObjectCursor& librados::ObjectCursor::operator=(const librados::ObjectCursor& rhs)
2786{
2787 if (rhs.c_cursor != nullptr) {
2788 hobject_t *h = (hobject_t*)rhs.c_cursor;
2789 c_cursor = (rados_object_list_cursor)(new hobject_t(*h));
2790 } else {
2791 c_cursor = nullptr;
2792 }
2793 return *this;
2794}
2795
2796bool librados::ObjectCursor::operator<(const librados::ObjectCursor &rhs) const
2797{
2798 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
2799 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
2800 return lhs_hobj < rhs_hobj;
2801}
2802
2803bool librados::ObjectCursor::operator==(const librados::ObjectCursor &rhs) const
2804{
2805 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
2806 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
2807 return cmp(lhs_hobj, rhs_hobj) == 0;
2808}
2809librados::ObjectCursor::ObjectCursor(const librados::ObjectCursor &rhs)
2810{
2811 *this = rhs;
2812}
2813
2814librados::ObjectCursor librados::IoCtx::object_list_begin()
2815{
2816 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_begin());
2817 ObjectCursor oc;
2818 oc.set((rados_object_list_cursor)h);
2819 return oc;
2820}
2821
2822
2823librados::ObjectCursor librados::IoCtx::object_list_end()
2824{
2825 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_end());
2826 librados::ObjectCursor oc;
2827 oc.set((rados_object_list_cursor)h);
2828 return oc;
2829}
2830
2831
2832void librados::ObjectCursor::set(rados_object_list_cursor c)
2833{
2834 delete (hobject_t*)c_cursor;
2835 c_cursor = c;
2836}
2837
2838string librados::ObjectCursor::to_str() const
2839{
2840 stringstream ss;
2841 ss << *(hobject_t *)c_cursor;
2842 return ss.str();
2843}
2844
2845bool librados::ObjectCursor::from_str(const string& s)
2846{
2847 if (s.empty()) {
2848 *(hobject_t *)c_cursor = hobject_t();
2849 return true;
2850 }
2851 return ((hobject_t *)c_cursor)->parse(s);
2852}
2853
2854CEPH_RADOS_API std::ostream& librados::operator<<(std::ostream& os, const librados::ObjectCursor& oc)
2855{
2856 if (oc.c_cursor) {
2857 os << *(hobject_t *)oc.c_cursor;
2858 } else {
2859 os << hobject_t();
2860 }
2861 return os;
2862}
2863
2864bool librados::IoCtx::object_list_is_end(const ObjectCursor &oc)
2865{
2866 hobject_t *h = (hobject_t *)oc.c_cursor;
2867 return h->is_max();
2868}
2869
2870int librados::IoCtx::object_list(const ObjectCursor &start,
2871 const ObjectCursor &finish,
2872 const size_t result_item_count,
2873 const bufferlist &filter,
2874 std::vector<ObjectItem> *result,
2875 ObjectCursor *next)
2876{
2877 ceph_assert(result != nullptr);
2878 ceph_assert(next != nullptr);
2879 result->clear();
2880
2881 C_SaferCond cond;
2882 hobject_t next_hash;
2883 std::list<librados::ListObjectImpl> obj_result;
2884 io_ctx_impl->objecter->enumerate_objects(
2885 io_ctx_impl->poolid,
2886 io_ctx_impl->oloc.nspace,
2887 *((hobject_t*)start.c_cursor),
2888 *((hobject_t*)finish.c_cursor),
2889 result_item_count,
2890 filter,
2891 &obj_result,
2892 &next_hash,
2893 &cond);
2894
2895 int r = cond.wait();
2896 if (r < 0) {
2897 next->set((rados_object_list_cursor)(new hobject_t(hobject_t::get_max())));
2898 return r;
2899 }
2900
2901 next->set((rados_object_list_cursor)(new hobject_t(next_hash)));
2902
2903 for (std::list<librados::ListObjectImpl>::iterator i = obj_result.begin();
2904 i != obj_result.end(); ++i) {
2905 ObjectItem oi;
2906 oi.oid = i->oid;
2907 oi.nspace = i->nspace;
2908 oi.locator = i->locator;
2909 result->push_back(oi);
2910 }
2911
2912 return obj_result.size();
2913}
2914
2915void librados::IoCtx::object_list_slice(
2916 const ObjectCursor start,
2917 const ObjectCursor finish,
2918 const size_t n,
2919 const size_t m,
2920 ObjectCursor *split_start,
2921 ObjectCursor *split_finish)
2922{
2923 ceph_assert(split_start != nullptr);
2924 ceph_assert(split_finish != nullptr);
2925
2926 io_ctx_impl->object_list_slice(
2927 *((hobject_t*)(start.c_cursor)),
2928 *((hobject_t*)(finish.c_cursor)),
2929 n,
2930 m,
2931 (hobject_t*)(split_start->c_cursor),
2932 (hobject_t*)(split_finish->c_cursor));
2933}
2934
2935int librados::IoCtx::application_enable(const std::string& app_name,
2936 bool force)
2937{
2938 return io_ctx_impl->application_enable(app_name, force);
2939}
2940
2941int librados::IoCtx::application_enable_async(const std::string& app_name,
2942 bool force,
2943 PoolAsyncCompletion *c)
2944{
2945 io_ctx_impl->application_enable_async(app_name, force, c->pc);
2946 return 0;
2947}
2948
2949int librados::IoCtx::application_list(std::set<std::string> *app_names)
2950{
2951 return io_ctx_impl->application_list(app_names);
2952}
2953
2954int librados::IoCtx::application_metadata_get(const std::string& app_name,
2955 const std::string &key,
2956 std::string* value)
2957{
2958 return io_ctx_impl->application_metadata_get(app_name, key, value);
2959}
2960
2961int librados::IoCtx::application_metadata_set(const std::string& app_name,
2962 const std::string &key,
2963 const std::string& value)
2964{
2965 return io_ctx_impl->application_metadata_set(app_name, key, value);
2966}
2967
2968int librados::IoCtx::application_metadata_remove(const std::string& app_name,
2969 const std::string &key)
2970{
2971 return io_ctx_impl->application_metadata_remove(app_name, key);
2972}
2973
2974int librados::IoCtx::application_metadata_list(const std::string& app_name,
2975 std::map<std::string, std::string> *values)
2976{
2977 return io_ctx_impl->application_metadata_list(app_name, values);
2978}