]> git.proxmox.com Git - ceph.git/blame - ceph/src/librados/librados.cc
update source to 12.2.11
[ceph.git] / ceph / src / librados / librados.cc
CommitLineData
7c673cae
FG
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 <cls/lock/cls_lock_client.h>
36
37#include <string>
38#include <map>
39#include <set>
40#include <vector>
41#include <list>
42#include <stdexcept>
43
44#ifdef WITH_LTTNG
45#define TRACEPOINT_DEFINE
46#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
47#include "tracing/librados.h"
48#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
49#undef TRACEPOINT_DEFINE
50#else
51#define tracepoint(...)
52#endif
53
54using std::string;
55using std::map;
56using std::set;
57using std::vector;
58using std::list;
7c673cae
FG
59
60#define dout_subsys ceph_subsys_rados
61#undef dout_prefix
62#define dout_prefix *_dout << "librados: "
63
64#define RADOS_LIST_MAX_ENTRIES 1024
65
66namespace {
67
68TracepointProvider::Traits tracepoint_traits("librados_tp.so", "rados_tracing");
69
70uint8_t get_checksum_op_type(rados_checksum_type_t type) {
71 switch (type) {
72 case LIBRADOS_CHECKSUM_TYPE_XXHASH32:
73 return CEPH_OSD_CHECKSUM_OP_TYPE_XXHASH32;
74 case LIBRADOS_CHECKSUM_TYPE_XXHASH64:
75 return CEPH_OSD_CHECKSUM_OP_TYPE_XXHASH64;
76 case LIBRADOS_CHECKSUM_TYPE_CRC32C:
77 return CEPH_OSD_CHECKSUM_OP_TYPE_CRC32C;
78 default:
79 return -1;
80 }
81}
82
83} // anonymous namespace
84
85/*
86 * Structure of this file
87 *
88 * RadosClient and the related classes are the internal implementation of librados.
89 * Above that layer sits the C API, found in include/rados/librados.h, and
90 * the C++ API, found in include/rados/librados.hpp
91 *
92 * The C++ API sometimes implements things in terms of the C API.
93 * Both the C++ and C API rely on RadosClient.
94 *
95 * Visually:
96 * +--------------------------------------+
97 * | C++ API |
98 * +--------------------+ |
99 * | C API | |
100 * +--------------------+-----------------+
101 * | RadosClient |
102 * +--------------------------------------+
103 */
104
105namespace librados {
106
107struct ObjectOperationImpl {
108 ::ObjectOperation o;
109 real_time rt;
110 real_time *prt;
111
112 ObjectOperationImpl() : prt(NULL) {}
113};
114
115}
116
117size_t librados::ObjectOperation::size()
118{
119 ::ObjectOperation *o = &impl->o;
120 return o->size();
121}
122
123static void set_op_flags(::ObjectOperation *o, int flags)
124{
125 int rados_flags = 0;
126 if (flags & LIBRADOS_OP_FLAG_EXCL)
127 rados_flags |= CEPH_OSD_OP_FLAG_EXCL;
128 if (flags & LIBRADOS_OP_FLAG_FAILOK)
129 rados_flags |= CEPH_OSD_OP_FLAG_FAILOK;
130 if (flags & LIBRADOS_OP_FLAG_FADVISE_RANDOM)
131 rados_flags |= CEPH_OSD_OP_FLAG_FADVISE_RANDOM;
132 if (flags & LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL)
133 rados_flags |= CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL;
134 if (flags & LIBRADOS_OP_FLAG_FADVISE_WILLNEED)
135 rados_flags |= CEPH_OSD_OP_FLAG_FADVISE_WILLNEED;
136 if (flags & LIBRADOS_OP_FLAG_FADVISE_DONTNEED)
137 rados_flags |= CEPH_OSD_OP_FLAG_FADVISE_DONTNEED;
138 if (flags & LIBRADOS_OP_FLAG_FADVISE_NOCACHE)
139 rados_flags |= CEPH_OSD_OP_FLAG_FADVISE_NOCACHE;
140 o->set_last_op_flags(rados_flags);
141}
142
143//deprcated
144void librados::ObjectOperation::set_op_flags(ObjectOperationFlags flags)
145{
146 ::set_op_flags(&impl->o, (int)flags);
147}
148
149void librados::ObjectOperation::set_op_flags2(int flags)
150{
151 ::ObjectOperation *o = &impl->o;
152 ::set_op_flags(o, flags);
153}
154
155void librados::ObjectOperation::cmpext(uint64_t off,
156 bufferlist &cmp_bl,
157 int *prval)
158{
159 ::ObjectOperation *o = &impl->o;
160 o->cmpext(off, cmp_bl, prval);
161}
162
163void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, const bufferlist& v)
164{
165 ::ObjectOperation *o = &impl->o;
166 o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_STRING, v);
167}
168
169void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, uint64_t v)
170{
171 ::ObjectOperation *o = &impl->o;
172 bufferlist bl;
173 ::encode(v, bl);
174 o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_U64, bl);
175}
176
177void librados::ObjectOperation::assert_version(uint64_t ver)
178{
179 ::ObjectOperation *o = &impl->o;
180 o->assert_version(ver);
181}
182
183void librados::ObjectOperation::assert_exists()
184{
185 ::ObjectOperation *o = &impl->o;
186 o->stat(NULL, (ceph::real_time*) NULL, NULL);
187}
188
189void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl)
190{
191 ::ObjectOperation *o = &impl->o;
192 o->call(cls, method, inbl);
193}
194
195void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, bufferlist *outbl, int *prval)
196{
197 ::ObjectOperation *o = &impl->o;
198 o->call(cls, method, inbl, outbl, NULL, prval);
199}
200
201class ObjectOpCompletionCtx : public Context {
202 librados::ObjectOperationCompletion *completion;
203 bufferlist bl;
204public:
205 explicit ObjectOpCompletionCtx(librados::ObjectOperationCompletion *c) : completion(c) {}
206 void finish(int r) override {
207 completion->handle_completion(r, bl);
208 delete completion;
209 }
210
211 bufferlist *outbl() {
212 return &bl;
213 }
214};
215
216void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, librados::ObjectOperationCompletion *completion)
217{
218 ::ObjectOperation *o = &impl->o;
219
220 ObjectOpCompletionCtx *ctx = new ObjectOpCompletionCtx(completion);
221
222 o->call(cls, method, inbl, ctx->outbl(), ctx, NULL);
223}
224
225void librados::ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval)
226{
227 ::ObjectOperation *o = &impl->o;
228 o->stat(psize, pmtime, prval);
229}
230
231void librados::ObjectReadOperation::stat2(uint64_t *psize, struct timespec *pts, int *prval)
232{
233 ::ObjectOperation *o = &impl->o;
234 o->stat(psize, pts, prval);
235}
236
237void librados::ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl, int *prval)
238{
239 ::ObjectOperation *o = &impl->o;
240 o->read(off, len, pbl, prval, NULL);
241}
242
243void librados::ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
244 std::map<uint64_t,uint64_t> *m,
245 bufferlist *data_bl, int *prval)
246{
247 ::ObjectOperation *o = &impl->o;
248 o->sparse_read(off, len, m, data_bl, prval);
249}
250
251void librados::ObjectReadOperation::checksum(rados_checksum_type_t type,
252 const bufferlist &init_value_bl,
253 uint64_t off, size_t len,
254 size_t chunk_size, bufferlist *pbl,
255 int *prval)
256{
257 ::ObjectOperation *o = &impl->o;
258 o->checksum(get_checksum_op_type(type), init_value_bl, off, len, chunk_size,
259 pbl, prval, nullptr);
260}
261
262void librados::ObjectReadOperation::tmap_get(bufferlist *pbl, int *prval)
263{
264 ::ObjectOperation *o = &impl->o;
265 o->tmap_get(pbl, prval);
266}
267
268void librados::ObjectReadOperation::getxattr(const char *name, bufferlist *pbl, int *prval)
269{
270 ::ObjectOperation *o = &impl->o;
271 o->getxattr(name, pbl, prval);
272}
273
274void librados::ObjectReadOperation::omap_get_vals(
275 const std::string &start_after,
276 const std::string &filter_prefix,
277 uint64_t max_return,
278 std::map<std::string, bufferlist> *out_vals,
279 int *prval)
280{
281 ::ObjectOperation *o = &impl->o;
282 o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, nullptr,
283 prval);
284}
285
286void librados::ObjectReadOperation::omap_get_vals2(
287 const std::string &start_after,
288 const std::string &filter_prefix,
289 uint64_t max_return,
290 std::map<std::string, bufferlist> *out_vals,
291 bool *pmore,
292 int *prval)
293{
294 ::ObjectOperation *o = &impl->o;
295 o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, pmore,
296 prval);
297}
298
299void librados::ObjectReadOperation::omap_get_vals(
300 const std::string &start_after,
301 uint64_t max_return,
302 std::map<std::string, bufferlist> *out_vals,
303 int *prval)
304{
305 ::ObjectOperation *o = &impl->o;
306 o->omap_get_vals(start_after, "", max_return, out_vals, nullptr, prval);
307}
308
309void librados::ObjectReadOperation::omap_get_vals2(
310 const std::string &start_after,
311 uint64_t max_return,
312 std::map<std::string, bufferlist> *out_vals,
313 bool *pmore,
314 int *prval)
315{
316 ::ObjectOperation *o = &impl->o;
317 o->omap_get_vals(start_after, "", max_return, out_vals, pmore, prval);
318}
319
320void librados::ObjectReadOperation::omap_get_keys(
321 const std::string &start_after,
322 uint64_t max_return,
323 std::set<std::string> *out_keys,
324 int *prval)
325{
326 ::ObjectOperation *o = &impl->o;
327 o->omap_get_keys(start_after, max_return, out_keys, nullptr, prval);
328}
329
330void librados::ObjectReadOperation::omap_get_keys2(
331 const std::string &start_after,
332 uint64_t max_return,
333 std::set<std::string> *out_keys,
334 bool *pmore,
335 int *prval)
336{
337 ::ObjectOperation *o = &impl->o;
338 o->omap_get_keys(start_after, max_return, out_keys, pmore, prval);
339}
340
341void librados::ObjectReadOperation::omap_get_header(bufferlist *bl, int *prval)
342{
343 ::ObjectOperation *o = &impl->o;
344 o->omap_get_header(bl, prval);
345}
346
347void librados::ObjectReadOperation::omap_get_vals_by_keys(
348 const std::set<std::string> &keys,
349 std::map<std::string, bufferlist> *map,
350 int *prval)
351{
352 ::ObjectOperation *o = &impl->o;
353 o->omap_get_vals_by_keys(keys, map, prval);
354}
355
356void librados::ObjectOperation::omap_cmp(
357 const std::map<std::string, pair<bufferlist, int> > &assertions,
358 int *prval)
359{
360 ::ObjectOperation *o = &impl->o;
361 o->omap_cmp(assertions, prval);
362}
363
364void librados::ObjectReadOperation::list_watchers(
365 list<obj_watch_t> *out_watchers,
366 int *prval)
367{
368 ::ObjectOperation *o = &impl->o;
369 o->list_watchers(out_watchers, prval);
370}
371
372void librados::ObjectReadOperation::list_snaps(
373 snap_set_t *out_snaps,
374 int *prval)
375{
376 ::ObjectOperation *o = &impl->o;
377 o->list_snaps(out_snaps, prval);
378}
379
380void librados::ObjectReadOperation::is_dirty(bool *is_dirty, int *prval)
381{
382 ::ObjectOperation *o = &impl->o;
383 o->is_dirty(is_dirty, prval);
384}
385
386int librados::IoCtx::omap_get_vals(const std::string& oid,
387 const std::string& orig_start_after,
388 const std::string& filter_prefix,
389 uint64_t max_return,
390 std::map<std::string, bufferlist> *out_vals)
391{
392 bool first = true;
393 string start_after = orig_start_after;
394 bool more = true;
395 while (max_return > 0 && more) {
396 std::map<std::string,bufferlist> out;
397 ObjectReadOperation op;
398 op.omap_get_vals2(start_after, filter_prefix, max_return, &out, &more,
399 nullptr);
400 bufferlist bl;
401 int ret = operate(oid, &op, &bl);
402 if (ret < 0) {
403 return ret;
404 }
405 if (more) {
406 if (out.empty()) {
407 return -EINVAL; // wth
408 }
409 start_after = out.rbegin()->first;
410 }
411 if (out.size() <= max_return) {
412 max_return -= out.size();
413 } else {
414 max_return = 0;
415 }
416 if (first) {
417 out_vals->swap(out);
418 first = false;
419 } else {
420 out_vals->insert(out.begin(), out.end());
421 out.clear();
422 }
423 }
424 return 0;
425}
426
427int librados::IoCtx::omap_get_vals2(
428 const std::string& oid,
429 const std::string& start_after,
430 const std::string& filter_prefix,
431 uint64_t max_return,
432 std::map<std::string, bufferlist> *out_vals,
433 bool *pmore)
434{
435 ObjectReadOperation op;
436 int r;
437 op.omap_get_vals2(start_after, filter_prefix, max_return, out_vals, pmore, &r);
438 bufferlist bl;
439 int ret = operate(oid, &op, &bl);
440 if (ret < 0)
441 return ret;
442 return r;
443}
444
445void librados::ObjectReadOperation::getxattrs(map<string, bufferlist> *pattrs, int *prval)
446{
447 ::ObjectOperation *o = &impl->o;
448 o->getxattrs(pattrs, prval);
449}
450
451void librados::ObjectWriteOperation::mtime(time_t *pt)
452{
453 if (pt) {
454 impl->rt = ceph::real_clock::from_time_t(*pt);
455 impl->prt = &impl->rt;
456 }
457}
458
459void librados::ObjectWriteOperation::mtime2(struct timespec *pts)
460{
461 if (pts) {
462 impl->rt = ceph::real_clock::from_timespec(*pts);
463 impl->prt = &impl->rt;
464 }
465}
466
467void librados::ObjectWriteOperation::create(bool exclusive)
468{
469 ::ObjectOperation *o = &impl->o;
470 o->create(exclusive);
471}
472
473void librados::ObjectWriteOperation::create(bool exclusive,
474 const std::string& category) // unused
475{
476 ::ObjectOperation *o = &impl->o;
477 o->create(exclusive);
478}
479
480void librados::ObjectWriteOperation::write(uint64_t off, const bufferlist& bl)
481{
482 ::ObjectOperation *o = &impl->o;
483 bufferlist c = bl;
484 o->write(off, c);
485}
486
487void librados::ObjectWriteOperation::write_full(const bufferlist& bl)
488{
489 ::ObjectOperation *o = &impl->o;
490 bufferlist c = bl;
491 o->write_full(c);
492}
493
494void librados::ObjectWriteOperation::writesame(uint64_t off, uint64_t write_len,
495 const bufferlist& bl)
496{
497 ::ObjectOperation *o = &impl->o;
498 bufferlist c = bl;
499 o->writesame(off, write_len, c);
500}
501
502void librados::ObjectWriteOperation::append(const bufferlist& bl)
503{
504 ::ObjectOperation *o = &impl->o;
505 bufferlist c = bl;
506 o->append(c);
507}
508
509void librados::ObjectWriteOperation::remove()
510{
511 ::ObjectOperation *o = &impl->o;
512 o->remove();
513}
514
515void librados::ObjectWriteOperation::truncate(uint64_t off)
516{
517 ::ObjectOperation *o = &impl->o;
518 o->truncate(off);
519}
520
521void librados::ObjectWriteOperation::zero(uint64_t off, uint64_t len)
522{
523 ::ObjectOperation *o = &impl->o;
524 o->zero(off, len);
525}
526
527void librados::ObjectWriteOperation::rmxattr(const char *name)
528{
529 ::ObjectOperation *o = &impl->o;
530 o->rmxattr(name);
531}
532
533void librados::ObjectWriteOperation::setxattr(const char *name, const bufferlist& v)
534{
535 ::ObjectOperation *o = &impl->o;
536 o->setxattr(name, v);
537}
538
539void librados::ObjectWriteOperation::omap_set(
540 const map<string, bufferlist> &map)
541{
542 ::ObjectOperation *o = &impl->o;
543 o->omap_set(map);
544}
545
546void librados::ObjectWriteOperation::omap_set_header(const bufferlist &bl)
547{
548 bufferlist c = bl;
549 ::ObjectOperation *o = &impl->o;
550 o->omap_set_header(c);
551}
552
553void librados::ObjectWriteOperation::omap_clear()
554{
555 ::ObjectOperation *o = &impl->o;
556 o->omap_clear();
557}
558
559void librados::ObjectWriteOperation::omap_rm_keys(
560 const std::set<std::string> &to_rm)
561{
562 ::ObjectOperation *o = &impl->o;
563 o->omap_rm_keys(to_rm);
564}
565
566void librados::ObjectWriteOperation::copy_from(const std::string& src,
567 const IoCtx& src_ioctx,
568 uint64_t src_version)
569{
570 copy_from2(src, src_ioctx, src_version, 0);
571}
572
573void librados::ObjectWriteOperation::copy_from2(const std::string& src,
574 const IoCtx& src_ioctx,
575 uint64_t src_version,
576 uint32_t src_fadvise_flags)
577{
578 ::ObjectOperation *o = &impl->o;
579 o->copy_from(object_t(src), src_ioctx.io_ctx_impl->snap_seq,
580 src_ioctx.io_ctx_impl->oloc, src_version, 0, src_fadvise_flags);
581}
582
583void librados::ObjectWriteOperation::undirty()
584{
585 ::ObjectOperation *o = &impl->o;
586 o->undirty();
587}
588
589void librados::ObjectReadOperation::cache_flush()
590{
591 ::ObjectOperation *o = &impl->o;
592 o->cache_flush();
593}
594
595void librados::ObjectReadOperation::cache_try_flush()
596{
597 ::ObjectOperation *o = &impl->o;
598 o->cache_try_flush();
599}
600
601void librados::ObjectReadOperation::cache_evict()
602{
603 ::ObjectOperation *o = &impl->o;
604 o->cache_evict();
605}
606
31f18b77
FG
607void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj,
608 const IoCtx& tgt_ioctx,
609 uint64_t tgt_version)
610{
611 ::ObjectOperation *o = &impl->o;
612 o->set_redirect(object_t(tgt_obj), tgt_ioctx.io_ctx_impl->snap_seq,
613 tgt_ioctx.io_ctx_impl->oloc, tgt_version);
614}
615
7c673cae
FG
616void librados::ObjectWriteOperation::tmap_put(const bufferlist &bl)
617{
618 ::ObjectOperation *o = &impl->o;
619 bufferlist c = bl;
620 o->tmap_put(c);
621}
622
623void librados::ObjectWriteOperation::tmap_update(const bufferlist& cmdbl)
624{
625 ::ObjectOperation *o = &impl->o;
626 bufferlist c = cmdbl;
627 o->tmap_update(c);
628}
629
630void librados::ObjectWriteOperation::selfmanaged_snap_rollback(snap_t snapid)
631{
632 ::ObjectOperation *o = &impl->o;
633 o->rollback(snapid);
634}
635
636// You must specify the snapid not the name normally used with pool snapshots
637void librados::ObjectWriteOperation::snap_rollback(snap_t snapid)
638{
639 ::ObjectOperation *o = &impl->o;
640 o->rollback(snapid);
641}
642
643void librados::ObjectWriteOperation::set_alloc_hint(
644 uint64_t expected_object_size,
645 uint64_t expected_write_size)
646{
647 ::ObjectOperation *o = &impl->o;
648 o->set_alloc_hint(expected_object_size, expected_write_size, 0);
649}
650void librados::ObjectWriteOperation::set_alloc_hint2(
651 uint64_t expected_object_size,
652 uint64_t expected_write_size,
653 uint32_t flags)
654{
655 ::ObjectOperation *o = &impl->o;
656 o->set_alloc_hint(expected_object_size, expected_write_size, flags);
657}
658
659void librados::ObjectWriteOperation::cache_pin()
660{
661 ::ObjectOperation *o = &impl->o;
662 o->cache_pin();
663}
664
665void librados::ObjectWriteOperation::cache_unpin()
666{
667 ::ObjectOperation *o = &impl->o;
668 o->cache_unpin();
669}
670
671librados::WatchCtx::
672~WatchCtx()
673{
674}
675
676librados::WatchCtx2::
677~WatchCtx2()
678{
679}
680
681
682struct librados::ObjListCtx {
683 librados::IoCtxImpl dupctx;
684 librados::IoCtxImpl *ctx;
685 Objecter::NListContext *nlc;
686 bool legacy_list_api;
687
688 ObjListCtx(IoCtxImpl *c, Objecter::NListContext *nl, bool legacy=false)
689 : nlc(nl),
690 legacy_list_api(legacy) {
691 // Get our own private IoCtxImpl so that namespace setting isn't
692 // changed by caller between uses.
693 ctx = &dupctx;
694 dupctx.dup(*c);
695 }
696 ~ObjListCtx() {
697 ctx = NULL;
698 delete nlc;
699 }
700};
701
702///////////////////////////// NObjectIteratorImpl /////////////////////////////
703librados::NObjectIteratorImpl::NObjectIteratorImpl(ObjListCtx *ctx_)
704 : ctx(ctx_)
705{
706}
707
708librados::NObjectIteratorImpl::~NObjectIteratorImpl()
709{
710 ctx.reset();
711}
712
713librados::NObjectIteratorImpl::NObjectIteratorImpl(const NObjectIteratorImpl &rhs)
714{
715 *this = rhs;
716}
717
718librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator=(const librados::NObjectIteratorImpl &rhs)
719{
720 if (&rhs == this)
721 return *this;
722 if (rhs.ctx.get() == NULL) {
723 ctx.reset();
724 return *this;
725 }
726 Objecter::NListContext *list_ctx = new Objecter::NListContext(*rhs.ctx->nlc);
727 ctx.reset(new ObjListCtx(rhs.ctx->ctx, list_ctx));
728 cur_obj = rhs.cur_obj;
729 return *this;
730}
731
732bool librados::NObjectIteratorImpl::operator==(const librados::NObjectIteratorImpl& rhs) const {
733
734 if (ctx.get() == NULL) {
735 if (rhs.ctx.get() == NULL)
736 return true;
737 return rhs.ctx->nlc->at_end();
738 }
739 if (rhs.ctx.get() == NULL) {
740 // Redundant but same as ObjectIterator version
741 if (ctx.get() == NULL)
742 return true;
743 return ctx->nlc->at_end();
744 }
745 return ctx.get() == rhs.ctx.get();
746}
747
748bool librados::NObjectIteratorImpl::operator!=(const librados::NObjectIteratorImpl& rhs) const {
749 return !(*this == rhs);
750}
751
752const librados::ListObject& librados::NObjectIteratorImpl::operator*() const {
753 return cur_obj;
754}
755
756const librados::ListObject* librados::NObjectIteratorImpl::operator->() const {
757 return &cur_obj;
758}
759
760librados::NObjectIteratorImpl& librados::NObjectIteratorImpl::operator++()
761{
762 get_next();
763 return *this;
764}
765
766librados::NObjectIteratorImpl librados::NObjectIteratorImpl::operator++(int)
767{
768 librados::NObjectIteratorImpl ret(*this);
769 get_next();
770 return ret;
771}
772
773uint32_t librados::NObjectIteratorImpl::seek(uint32_t pos)
774{
775 uint32_t r = rados_nobjects_list_seek(ctx.get(), pos);
776 get_next();
777 return r;
778}
779
780uint32_t librados::NObjectIteratorImpl::seek(const ObjectCursor& cursor)
781{
782 uint32_t r = rados_nobjects_list_seek_cursor(ctx.get(), (rados_object_list_cursor)cursor.c_cursor);
783 get_next();
784 return r;
785}
786
787librados::ObjectCursor librados::NObjectIteratorImpl::get_cursor()
788{
789 librados::ObjListCtx *lh = (librados::ObjListCtx *)ctx.get();
790 librados::ObjectCursor oc;
791 oc.set(lh->ctx->nlist_get_cursor(lh->nlc));
792 return oc;
793}
794
795void librados::NObjectIteratorImpl::set_filter(const bufferlist &bl)
796{
797 assert(ctx);
798 ctx->nlc->filter = bl;
799}
800
801void librados::NObjectIteratorImpl::get_next()
802{
803 const char *entry, *key, *nspace;
804 if (ctx->nlc->at_end())
805 return;
806 int ret = rados_nobjects_list_next(ctx.get(), &entry, &key, &nspace);
807 if (ret == -ENOENT) {
808 return;
809 }
810 else if (ret) {
f64942e4
AA
811 throw std::system_error(-ret, std::system_category(),
812 "rados_nobjects_list_next");
7c673cae
FG
813 }
814
815 if (cur_obj.impl == NULL)
816 cur_obj.impl = new ListObjectImpl();
817 cur_obj.impl->nspace = nspace;
818 cur_obj.impl->oid = entry;
819 cur_obj.impl->locator = key ? key : string();
820}
821
822uint32_t librados::NObjectIteratorImpl::get_pg_hash_position() const
823{
824 return ctx->nlc->get_pg_hash_position();
825}
826
827///////////////////////////// NObjectIterator /////////////////////////////
828librados::NObjectIterator::NObjectIterator(ObjListCtx *ctx_)
829{
830 impl = new NObjectIteratorImpl(ctx_);
831}
832
833librados::NObjectIterator::~NObjectIterator()
834{
835 delete impl;
836}
837
838librados::NObjectIterator::NObjectIterator(const NObjectIterator &rhs)
839{
840 if (rhs.impl == NULL) {
841 impl = NULL;
842 return;
843 }
844 impl = new NObjectIteratorImpl();
845 *impl = *(rhs.impl);
846}
847
848librados::NObjectIterator& librados::NObjectIterator::operator=(const librados::NObjectIterator &rhs)
849{
850 if (rhs.impl == NULL) {
851 delete impl;
852 impl = NULL;
853 return *this;
854 }
855 if (impl == NULL)
856 impl = new NObjectIteratorImpl();
857 *impl = *(rhs.impl);
858 return *this;
859}
860
861bool librados::NObjectIterator::operator==(const librados::NObjectIterator& rhs) const
862{
863 if (impl && rhs.impl) {
864 return *impl == *(rhs.impl);
865 } else {
866 return impl == rhs.impl;
867 }
868}
869
870bool librados::NObjectIterator::operator!=(const librados::NObjectIterator& rhs) const
871{
872 return !(*this == rhs);
873}
874
875const librados::ListObject& librados::NObjectIterator::operator*() const {
876 assert(impl);
877 return *(impl->get_listobjectp());
878}
879
880const librados::ListObject* librados::NObjectIterator::operator->() const {
881 assert(impl);
882 return impl->get_listobjectp();
883}
884
885librados::NObjectIterator& librados::NObjectIterator::operator++()
886{
887 assert(impl);
888 impl->get_next();
889 return *this;
890}
891
892librados::NObjectIterator librados::NObjectIterator::operator++(int)
893{
894 librados::NObjectIterator ret(*this);
895 impl->get_next();
896 return ret;
897}
898
899uint32_t librados::NObjectIterator::seek(uint32_t pos)
900{
901 assert(impl);
902 return impl->seek(pos);
903}
904
905uint32_t librados::NObjectIterator::seek(const ObjectCursor& cursor)
906{
907 assert(impl);
908 return impl->seek(cursor);
909}
910
911librados::ObjectCursor librados::NObjectIterator::get_cursor()
912{
913 assert(impl);
914 return impl->get_cursor();
915}
916
917void librados::NObjectIterator::set_filter(const bufferlist &bl)
918{
919 impl->set_filter(bl);
920}
921
922void librados::NObjectIterator::get_next()
923{
924 assert(impl);
925 impl->get_next();
926}
927
928uint32_t librados::NObjectIterator::get_pg_hash_position() const
929{
930 assert(impl);
931 return impl->get_pg_hash_position();
932}
933
934const librados::NObjectIterator librados::NObjectIterator::__EndObjectIterator(NULL);
935
936///////////////////////////// PoolAsyncCompletion //////////////////////////////
937int librados::PoolAsyncCompletion::PoolAsyncCompletion::set_callback(void *cb_arg,
938 rados_callback_t cb)
939{
940 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
941 return c->set_callback(cb_arg, cb);
942}
943
944int librados::PoolAsyncCompletion::PoolAsyncCompletion::wait()
945{
946 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
947 return c->wait();
948}
949
950bool librados::PoolAsyncCompletion::PoolAsyncCompletion::is_complete()
951{
952 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
953 return c->is_complete();
954}
955
956int librados::PoolAsyncCompletion::PoolAsyncCompletion::get_return_value()
957{
958 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
959 return c->get_return_value();
960}
961
962void librados::PoolAsyncCompletion::PoolAsyncCompletion::release()
963{
964 PoolAsyncCompletionImpl *c = (PoolAsyncCompletionImpl *)pc;
965 c->release();
966 delete this;
967}
968
969///////////////////////////// AioCompletion //////////////////////////////
970int librados::AioCompletion::AioCompletion::set_complete_callback(void *cb_arg, rados_callback_t cb)
971{
972 AioCompletionImpl *c = (AioCompletionImpl *)pc;
973 return c->set_complete_callback(cb_arg, cb);
974}
975
976int librados::AioCompletion::AioCompletion::set_safe_callback(void *cb_arg, rados_callback_t cb)
977{
978 AioCompletionImpl *c = (AioCompletionImpl *)pc;
979 return c->set_safe_callback(cb_arg, cb);
980}
981
982int librados::AioCompletion::AioCompletion::wait_for_complete()
983{
984 AioCompletionImpl *c = (AioCompletionImpl *)pc;
985 return c->wait_for_complete();
986}
987
988int librados::AioCompletion::AioCompletion::wait_for_safe()
989{
990 AioCompletionImpl *c = (AioCompletionImpl *)pc;
991 return c->wait_for_safe();
992}
993
994bool librados::AioCompletion::AioCompletion::is_complete()
995{
996 AioCompletionImpl *c = (AioCompletionImpl *)pc;
997 return c->is_complete();
998}
999
1000bool librados::AioCompletion::AioCompletion::is_safe()
1001{
1002 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1003 return c->is_safe();
1004}
1005
1006int librados::AioCompletion::AioCompletion::wait_for_complete_and_cb()
1007{
1008 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1009 return c->wait_for_complete_and_cb();
1010}
1011
1012int librados::AioCompletion::AioCompletion::wait_for_safe_and_cb()
1013{
1014 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1015 return c->wait_for_safe_and_cb();
1016}
1017
1018bool librados::AioCompletion::AioCompletion::is_complete_and_cb()
1019{
1020 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1021 return c->is_complete_and_cb();
1022}
1023
1024bool librados::AioCompletion::AioCompletion::is_safe_and_cb()
1025{
1026 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1027 return c->is_safe_and_cb();
1028}
1029
1030int librados::AioCompletion::AioCompletion::get_return_value()
1031{
1032 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1033 return c->get_return_value();
1034}
1035
1036int librados::AioCompletion::AioCompletion::get_version()
1037{
1038 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1039 return c->get_version();
1040}
1041
1042uint64_t librados::AioCompletion::AioCompletion::get_version64()
1043{
1044 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1045 return c->get_version();
1046}
1047
1048void librados::AioCompletion::AioCompletion::release()
1049{
1050 AioCompletionImpl *c = (AioCompletionImpl *)pc;
1051 c->release();
1052 delete this;
1053}
1054
1055///////////////////////////// IoCtx //////////////////////////////
1056librados::IoCtx::IoCtx() : io_ctx_impl(NULL)
1057{
1058}
1059
1060void librados::IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io)
1061{
1062 IoCtxImpl *io_ctx_impl = (IoCtxImpl*)p;
1063
1064 io.io_ctx_impl = io_ctx_impl;
1065 if (io_ctx_impl) {
1066 io_ctx_impl->get();
1067 }
1068}
1069
1070librados::IoCtx::IoCtx(const IoCtx& rhs)
1071{
1072 io_ctx_impl = rhs.io_ctx_impl;
1073 if (io_ctx_impl) {
1074 io_ctx_impl->get();
1075 }
1076}
1077
1078librados::IoCtx& librados::IoCtx::operator=(const IoCtx& rhs)
1079{
1080 if (io_ctx_impl)
1081 io_ctx_impl->put();
1082 io_ctx_impl = rhs.io_ctx_impl;
1083 io_ctx_impl->get();
1084 return *this;
1085}
1086
1087librados::IoCtx::~IoCtx()
1088{
1089 close();
1090}
1091
1092void librados::IoCtx::close()
1093{
1094 if (io_ctx_impl)
1095 io_ctx_impl->put();
1096 io_ctx_impl = 0;
1097}
1098
1099void librados::IoCtx::dup(const IoCtx& rhs)
1100{
1101 if (io_ctx_impl)
1102 io_ctx_impl->put();
1103 io_ctx_impl = new IoCtxImpl();
1104 io_ctx_impl->get();
1105 io_ctx_impl->dup(*rhs.io_ctx_impl);
1106}
1107
1108int librados::IoCtx::set_auid(uint64_t auid_)
1109{
1110 return io_ctx_impl->pool_change_auid(auid_);
1111}
1112
1113int librados::IoCtx::set_auid_async(uint64_t auid_, PoolAsyncCompletion *c)
1114{
1115 return io_ctx_impl->pool_change_auid_async(auid_, c->pc);
1116}
1117
1118int librados::IoCtx::get_auid(uint64_t *auid_)
1119{
1120 return rados_ioctx_pool_get_auid(io_ctx_impl, auid_);
1121}
1122
1123bool librados::IoCtx::pool_requires_alignment()
1124{
1125 return io_ctx_impl->client->pool_requires_alignment(get_id());
1126}
1127
1128int librados::IoCtx::pool_requires_alignment2(bool *requires)
1129{
1130 return io_ctx_impl->client->pool_requires_alignment2(get_id(), requires);
1131}
1132
1133uint64_t librados::IoCtx::pool_required_alignment()
1134{
1135 return io_ctx_impl->client->pool_required_alignment(get_id());
1136}
1137
1138int librados::IoCtx::pool_required_alignment2(uint64_t *alignment)
1139{
1140 return io_ctx_impl->client->pool_required_alignment2(get_id(), alignment);
1141}
1142
1143std::string librados::IoCtx::get_pool_name()
1144{
1145 std::string s;
1146 io_ctx_impl->client->pool_get_name(get_id(), &s);
1147 return s;
1148}
1149
1150std::string librados::IoCtx::get_pool_name() const
1151{
1152 return io_ctx_impl->get_cached_pool_name();
1153}
1154
1155uint64_t librados::IoCtx::get_instance_id() const
1156{
1157 return io_ctx_impl->client->get_instance_id();
1158}
1159
1160int librados::IoCtx::create(const std::string& oid, bool exclusive)
1161{
1162 object_t obj(oid);
1163 return io_ctx_impl->create(obj, exclusive);
1164}
1165
1166int librados::IoCtx::create(const std::string& oid, bool exclusive,
1167 const std::string& category) // unused
1168{
1169 object_t obj(oid);
1170 return io_ctx_impl->create(obj, exclusive);
1171}
1172
1173int librados::IoCtx::write(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1174{
1175 object_t obj(oid);
1176 return io_ctx_impl->write(obj, bl, len, off);
1177}
1178
1179int librados::IoCtx::append(const std::string& oid, bufferlist& bl, size_t len)
1180{
1181 object_t obj(oid);
1182 return io_ctx_impl->append(obj, bl, len);
1183}
1184
1185int librados::IoCtx::write_full(const std::string& oid, bufferlist& bl)
1186{
1187 object_t obj(oid);
1188 return io_ctx_impl->write_full(obj, bl);
1189}
1190
1191int librados::IoCtx::writesame(const std::string& oid, bufferlist& bl,
1192 size_t write_len, uint64_t off)
1193{
1194 object_t obj(oid);
1195 return io_ctx_impl->writesame(obj, bl, write_len, off);
1196}
1197
1198
1199int librados::IoCtx::read(const std::string& oid, bufferlist& bl, size_t len, uint64_t off)
1200{
1201 object_t obj(oid);
1202 return io_ctx_impl->read(obj, bl, len, off);
1203}
1204
1205int librados::IoCtx::checksum(const std::string& oid,
1206 rados_checksum_type_t type,
1207 const bufferlist &init_value_bl, size_t len,
1208 uint64_t off, size_t chunk_size, bufferlist *pbl)
1209{
1210 object_t obj(oid);
1211 return io_ctx_impl->checksum(obj, get_checksum_op_type(type), init_value_bl,
1212 len, off, chunk_size, pbl);
1213}
1214
1215int librados::IoCtx::remove(const std::string& oid)
1216{
1217 object_t obj(oid);
1218 return io_ctx_impl->remove(obj);
1219}
1220
1221int librados::IoCtx::remove(const std::string& oid, int flags)
1222{
1223 object_t obj(oid);
1224 return io_ctx_impl->remove(obj, flags);
1225}
1226
1227int librados::IoCtx::trunc(const std::string& oid, uint64_t size)
1228{
1229 object_t obj(oid);
1230 return io_ctx_impl->trunc(obj, size);
1231}
1232
1233int librados::IoCtx::mapext(const std::string& oid, uint64_t off, size_t len,
1234 std::map<uint64_t,uint64_t>& m)
1235{
1236 object_t obj(oid);
1237 return io_ctx_impl->mapext(obj, off, len, m);
1238}
1239
1240int librados::IoCtx::cmpext(const std::string& oid, uint64_t off, bufferlist& cmp_bl)
1241{
1242 object_t obj(oid);
1243 return io_ctx_impl->cmpext(obj, off, cmp_bl);
1244}
1245
1246int librados::IoCtx::sparse_read(const std::string& oid, std::map<uint64_t,uint64_t>& m,
1247 bufferlist& bl, size_t len, uint64_t off)
1248{
1249 object_t obj(oid);
1250 return io_ctx_impl->sparse_read(obj, m, bl, len, off);
1251}
1252
1253int librados::IoCtx::getxattr(const std::string& oid, const char *name, bufferlist& bl)
1254{
1255 object_t obj(oid);
1256 return io_ctx_impl->getxattr(obj, name, bl);
1257}
1258
1259int librados::IoCtx::getxattrs(const std::string& oid, map<std::string, bufferlist>& attrset)
1260{
1261 object_t obj(oid);
1262 return io_ctx_impl->getxattrs(obj, attrset);
1263}
1264
1265int librados::IoCtx::setxattr(const std::string& oid, const char *name, bufferlist& bl)
1266{
1267 object_t obj(oid);
1268 return io_ctx_impl->setxattr(obj, name, bl);
1269}
1270
1271int librados::IoCtx::rmxattr(const std::string& oid, const char *name)
1272{
1273 object_t obj(oid);
1274 return io_ctx_impl->rmxattr(obj, name);
1275}
1276
1277int librados::IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtime)
1278{
1279 object_t obj(oid);
1280 return io_ctx_impl->stat(obj, psize, pmtime);
1281}
1282
1283int librados::IoCtx::stat2(const std::string& oid, uint64_t *psize, struct timespec *pts)
1284{
1285 object_t obj(oid);
1286 return io_ctx_impl->stat2(obj, psize, pts);
1287}
1288
1289int librados::IoCtx::exec(const std::string& oid, const char *cls, const char *method,
1290 bufferlist& inbl, bufferlist& outbl)
1291{
1292 object_t obj(oid);
1293 return io_ctx_impl->exec(obj, cls, method, inbl, outbl);
1294}
1295
1296int librados::IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl)
1297{
1298 object_t obj(oid);
1299 return io_ctx_impl->tmap_update(obj, cmdbl);
1300}
1301
1302int librados::IoCtx::tmap_put(const std::string& oid, bufferlist& bl)
1303{
1304 object_t obj(oid);
1305 return io_ctx_impl->tmap_put(obj, bl);
1306}
1307
1308int librados::IoCtx::tmap_get(const std::string& oid, bufferlist& bl)
1309{
1310 object_t obj(oid);
1311 return io_ctx_impl->tmap_get(obj, bl);
1312}
1313
1314int librados::IoCtx::tmap_to_omap(const std::string& oid, bool nullok)
1315{
1316 object_t obj(oid);
1317 return io_ctx_impl->tmap_to_omap(obj, nullok);
1318}
1319
1320int librados::IoCtx::omap_get_vals(const std::string& oid,
1321 const std::string& start_after,
1322 uint64_t max_return,
1323 std::map<std::string, bufferlist> *out_vals)
1324{
1325 return omap_get_vals(oid, start_after, string(), max_return, out_vals);
1326}
1327
1328int librados::IoCtx::omap_get_vals2(
1329 const std::string& oid,
1330 const std::string& start_after,
1331 uint64_t max_return,
1332 std::map<std::string, bufferlist> *out_vals,
1333 bool *pmore)
1334{
1335 ObjectReadOperation op;
1336 int r;
1337 op.omap_get_vals2(start_after, max_return, out_vals, pmore, &r);
1338 bufferlist bl;
1339 int ret = operate(oid, &op, &bl);
1340 if (ret < 0)
1341 return ret;
1342 return r;
1343}
1344
1345int librados::IoCtx::omap_get_keys(const std::string& oid,
1346 const std::string& orig_start_after,
1347 uint64_t max_return,
1348 std::set<std::string> *out_keys)
1349{
1350 bool first = true;
1351 string start_after = orig_start_after;
1352 bool more = true;
1353 while (max_return > 0 && more) {
1354 std::set<std::string> out;
1355 ObjectReadOperation op;
1356 op.omap_get_keys2(start_after, max_return, &out, &more, nullptr);
1357 bufferlist bl;
1358 int ret = operate(oid, &op, &bl);
1359 if (ret < 0) {
1360 return ret;
1361 }
1362 if (more) {
1363 if (out.empty()) {
1364 return -EINVAL; // wth
1365 }
1366 start_after = *out.rbegin();
1367 }
1368 if (out.size() <= max_return) {
1369 max_return -= out.size();
1370 } else {
1371 max_return = 0;
1372 }
1373 if (first) {
1374 out_keys->swap(out);
1375 first = false;
1376 } else {
1377 out_keys->insert(out.begin(), out.end());
1378 out.clear();
1379 }
1380 }
1381 return 0;
1382}
1383
1384int librados::IoCtx::omap_get_keys2(
1385 const std::string& oid,
1386 const std::string& start_after,
1387 uint64_t max_return,
1388 std::set<std::string> *out_keys,
1389 bool *pmore)
1390{
1391 ObjectReadOperation op;
1392 int r;
1393 op.omap_get_keys2(start_after, max_return, out_keys, pmore, &r);
1394 bufferlist bl;
1395 int ret = operate(oid, &op, &bl);
1396 if (ret < 0)
1397 return ret;
1398 return r;
1399}
1400
1401int librados::IoCtx::omap_get_header(const std::string& oid,
1402 bufferlist *bl)
1403{
1404 ObjectReadOperation op;
1405 int r;
1406 op.omap_get_header(bl, &r);
1407 bufferlist b;
1408 int ret = operate(oid, &op, &b);
1409 if (ret < 0)
1410 return ret;
1411
1412 return r;
1413}
1414
1415int librados::IoCtx::omap_get_vals_by_keys(const std::string& oid,
1416 const std::set<std::string>& keys,
1417 std::map<std::string, bufferlist> *vals)
1418{
1419 ObjectReadOperation op;
1420 int r;
1421 bufferlist bl;
1422 op.omap_get_vals_by_keys(keys, vals, &r);
1423 int ret = operate(oid, &op, &bl);
1424 if (ret < 0)
1425 return ret;
1426
1427 return r;
1428}
1429
1430int librados::IoCtx::omap_set(const std::string& oid,
1431 const map<string, bufferlist>& m)
1432{
1433 ObjectWriteOperation op;
1434 op.omap_set(m);
1435 return operate(oid, &op);
1436}
1437
1438int librados::IoCtx::omap_set_header(const std::string& oid,
1439 const bufferlist& bl)
1440{
1441 ObjectWriteOperation op;
1442 op.omap_set_header(bl);
1443 return operate(oid, &op);
1444}
1445
1446int librados::IoCtx::omap_clear(const std::string& oid)
1447{
1448 ObjectWriteOperation op;
1449 op.omap_clear();
1450 return operate(oid, &op);
1451}
1452
1453int librados::IoCtx::omap_rm_keys(const std::string& oid,
1454 const std::set<std::string>& keys)
1455{
1456 ObjectWriteOperation op;
1457 op.omap_rm_keys(keys);
1458 return operate(oid, &op);
1459}
1460
1461
1462
1463static int translate_flags(int flags)
1464{
1465 int op_flags = 0;
1466 if (flags & librados::OPERATION_BALANCE_READS)
1467 op_flags |= CEPH_OSD_FLAG_BALANCE_READS;
1468 if (flags & librados::OPERATION_LOCALIZE_READS)
1469 op_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
1470 if (flags & librados::OPERATION_ORDER_READS_WRITES)
1471 op_flags |= CEPH_OSD_FLAG_RWORDERED;
1472 if (flags & librados::OPERATION_IGNORE_CACHE)
1473 op_flags |= CEPH_OSD_FLAG_IGNORE_CACHE;
1474 if (flags & librados::OPERATION_SKIPRWLOCKS)
1475 op_flags |= CEPH_OSD_FLAG_SKIPRWLOCKS;
1476 if (flags & librados::OPERATION_IGNORE_OVERLAY)
1477 op_flags |= CEPH_OSD_FLAG_IGNORE_OVERLAY;
1478 if (flags & librados::OPERATION_FULL_TRY)
1479 op_flags |= CEPH_OSD_FLAG_FULL_TRY;
1480 if (flags & librados::OPERATION_FULL_FORCE)
1481 op_flags |= CEPH_OSD_FLAG_FULL_FORCE;
31f18b77
FG
1482 if (flags & librados::OPERATION_IGNORE_REDIRECT)
1483 op_flags |= CEPH_OSD_FLAG_IGNORE_REDIRECT;
7c673cae
FG
1484
1485 return op_flags;
1486}
1487
1488int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o)
1489{
1490 object_t obj(oid);
1491 return io_ctx_impl->operate(obj, &o->impl->o, (ceph::real_time *)o->impl->prt);
1492}
1493
1494int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl)
1495{
1496 object_t obj(oid);
1497 return io_ctx_impl->operate_read(obj, &o->impl->o, pbl);
1498}
1499
1500int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1501 librados::ObjectWriteOperation *o)
1502{
1503 object_t obj(oid);
1504 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1505 io_ctx_impl->snapc, 0);
1506}
1507int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1508 ObjectWriteOperation *o, int flags)
1509{
1510 object_t obj(oid);
1511 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1512 io_ctx_impl->snapc,
1513 translate_flags(flags));
1514}
1515
1516int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1517 librados::ObjectWriteOperation *o,
1518 snap_t snap_seq, std::vector<snap_t>& snaps)
1519{
1520 object_t obj(oid);
1521 vector<snapid_t> snv;
1522 snv.resize(snaps.size());
1523 for (size_t i = 0; i < snaps.size(); ++i)
1524 snv[i] = snaps[i];
1525 SnapContext snapc(snap_seq, snv);
1526 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1527 snapc, 0);
1528}
1529
1530int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1531 librados::ObjectWriteOperation *o,
1532 snap_t snap_seq, std::vector<snap_t>& snaps,
1533 const blkin_trace_info *trace_info)
1534{
1535 object_t obj(oid);
1536 vector<snapid_t> snv;
1537 snv.resize(snaps.size());
1538 for (size_t i = 0; i < snaps.size(); ++i)
1539 snv[i] = snaps[i];
1540 SnapContext snapc(snap_seq, snv);
1541 return io_ctx_impl->aio_operate(obj, &o->impl->o, c->pc,
1542 snapc, 0, trace_info);
1543}
1544
1545int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1546 librados::ObjectReadOperation *o,
1547 bufferlist *pbl)
1548{
1549 object_t obj(oid);
1550 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1551 0, pbl);
1552}
1553
1554// deprecated
1555int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1556 librados::ObjectReadOperation *o,
1557 snap_t snapid_unused_deprecated,
1558 int flags, bufferlist *pbl)
1559{
1560 object_t obj(oid);
1561 int op_flags = 0;
1562 if (flags & OPERATION_BALANCE_READS)
1563 op_flags |= CEPH_OSD_FLAG_BALANCE_READS;
1564 if (flags & OPERATION_LOCALIZE_READS)
1565 op_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
1566 if (flags & OPERATION_ORDER_READS_WRITES)
1567 op_flags |= CEPH_OSD_FLAG_RWORDERED;
1568
1569 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1570 op_flags, pbl);
1571}
1572
1573int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1574 librados::ObjectReadOperation *o,
1575 int flags, bufferlist *pbl)
1576{
1577 object_t obj(oid);
1578 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1579 translate_flags(flags), pbl);
1580}
1581
1582int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
1583 librados::ObjectReadOperation *o,
1584 int flags, bufferlist *pbl, const blkin_trace_info *trace_info)
1585{
1586 object_t obj(oid);
1587 return io_ctx_impl->aio_operate_read(obj, &o->impl->o, c->pc,
1588 translate_flags(flags), pbl, trace_info);
1589}
1590
1591void librados::IoCtx::snap_set_read(snap_t seq)
1592{
1593 io_ctx_impl->set_snap_read(seq);
1594}
1595
1596int librados::IoCtx::selfmanaged_snap_set_write_ctx(snap_t seq, vector<snap_t>& snaps)
1597{
1598 vector<snapid_t> snv;
1599 snv.resize(snaps.size());
1600 for (unsigned i=0; i<snaps.size(); i++)
1601 snv[i] = snaps[i];
1602 return io_ctx_impl->set_snap_write_context(seq, snv);
1603}
1604
1605int librados::IoCtx::snap_create(const char *snapname)
1606{
1607 return io_ctx_impl->snap_create(snapname);
1608}
1609
1610int librados::IoCtx::snap_lookup(const char *name, snap_t *snapid)
1611{
1612 return io_ctx_impl->snap_lookup(name, snapid);
1613}
1614
1615int librados::IoCtx::snap_get_stamp(snap_t snapid, time_t *t)
1616{
1617 return io_ctx_impl->snap_get_stamp(snapid, t);
1618}
1619
1620int librados::IoCtx::snap_get_name(snap_t snapid, std::string *s)
1621{
1622 return io_ctx_impl->snap_get_name(snapid, s);
1623}
1624
1625int librados::IoCtx::snap_remove(const char *snapname)
1626{
1627 return io_ctx_impl->snap_remove(snapname);
1628}
1629
1630int librados::IoCtx::snap_list(std::vector<snap_t> *snaps)
1631{
1632 return io_ctx_impl->snap_list(snaps);
1633}
1634
1635int librados::IoCtx::snap_rollback(const std::string& oid, const char *snapname)
1636{
1637 return io_ctx_impl->rollback(oid, snapname);
1638}
1639
1640// Deprecated name kept for backward compatibility
1641int librados::IoCtx::rollback(const std::string& oid, const char *snapname)
1642{
1643 return snap_rollback(oid, snapname);
1644}
1645
1646int librados::IoCtx::selfmanaged_snap_create(uint64_t *snapid)
1647{
1648 return io_ctx_impl->selfmanaged_snap_create(snapid);
1649}
1650
1651void librados::IoCtx::aio_selfmanaged_snap_create(uint64_t *snapid,
1652 AioCompletion *c)
1653{
1654 io_ctx_impl->aio_selfmanaged_snap_create(snapid, c->pc);
1655}
1656
1657int librados::IoCtx::selfmanaged_snap_remove(uint64_t snapid)
1658{
1659 return io_ctx_impl->selfmanaged_snap_remove(snapid);
1660}
1661
1662void librados::IoCtx::aio_selfmanaged_snap_remove(uint64_t snapid,
1663 AioCompletion *c)
1664{
1665 io_ctx_impl->aio_selfmanaged_snap_remove(snapid, c->pc);
1666}
1667
1668int librados::IoCtx::selfmanaged_snap_rollback(const std::string& oid, uint64_t snapid)
1669{
1670 return io_ctx_impl->selfmanaged_snap_rollback_object(oid,
1671 io_ctx_impl->snapc,
1672 snapid);
1673}
1674
1675int librados::IoCtx::lock_exclusive(const std::string &oid, const std::string &name,
1676 const std::string &cookie,
1677 const std::string &description,
1678 struct timeval * duration, uint8_t flags)
1679{
1680 utime_t dur = utime_t();
1681 if (duration)
1682 dur.set_from_timeval(duration);
1683
1684 return rados::cls::lock::lock(this, oid, name, LOCK_EXCLUSIVE, cookie, "",
1685 description, dur, flags);
1686}
1687
1688int librados::IoCtx::lock_shared(const std::string &oid, const std::string &name,
1689 const std::string &cookie, const std::string &tag,
1690 const std::string &description,
1691 struct timeval * duration, uint8_t flags)
1692{
1693 utime_t dur = utime_t();
1694 if (duration)
1695 dur.set_from_timeval(duration);
1696
1697 return rados::cls::lock::lock(this, oid, name, LOCK_SHARED, cookie, tag,
1698 description, dur, flags);
1699}
1700
1701int librados::IoCtx::unlock(const std::string &oid, const std::string &name,
1702 const std::string &cookie)
1703{
1704 return rados::cls::lock::unlock(this, oid, name, cookie);
1705}
1706
1707struct AioUnlockCompletion : public librados::ObjectOperationCompletion {
1708 librados::AioCompletionImpl *completion;
1709 AioUnlockCompletion(librados::AioCompletion *c) : completion(c->pc) {
1710 completion->get();
1711 };
1712 void handle_completion(int r, bufferlist& outbl) override {
1713 rados_callback_t cb = completion->callback_complete;
1714 void *cb_arg = completion->callback_complete_arg;
1715 cb(completion, cb_arg);
1716 completion->lock.Lock();
1717 completion->callback_complete = NULL;
1718 completion->cond.Signal();
1719 completion->put_unlock();
1720 }
1721};
1722
1723int librados::IoCtx::aio_unlock(const std::string &oid, const std::string &name,
1724 const std::string &cookie, AioCompletion *c)
1725{
1726 return rados::cls::lock::aio_unlock(this, oid, name, cookie, c);
1727}
1728
1729int librados::IoCtx::break_lock(const std::string &oid, const std::string &name,
1730 const std::string &client, const std::string &cookie)
1731{
1732 entity_name_t locker;
1733 if (!locker.parse(client))
1734 return -EINVAL;
1735 return rados::cls::lock::break_lock(this, oid, name, cookie, locker);
1736}
1737
1738int librados::IoCtx::list_lockers(const std::string &oid, const std::string &name,
1739 int *exclusive,
1740 std::string *tag,
1741 std::list<librados::locker_t> *lockers)
1742{
1743 std::list<librados::locker_t> tmp_lockers;
1744 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t> rados_lockers;
1745 std::string tmp_tag;
1746 ClsLockType tmp_type;
1747 int r = rados::cls::lock::get_lock_info(this, oid, name, &rados_lockers, &tmp_type, &tmp_tag);
1748 if (r < 0)
1749 return r;
1750
1751 map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t>::iterator map_it;
1752 for (map_it = rados_lockers.begin(); map_it != rados_lockers.end(); ++map_it) {
1753 librados::locker_t locker;
1754 locker.client = stringify(map_it->first.locker);
1755 locker.cookie = map_it->first.cookie;
1756 locker.address = stringify(map_it->second.addr);
1757 tmp_lockers.push_back(locker);
1758 }
1759
1760 if (lockers)
1761 *lockers = tmp_lockers;
1762 if (tag)
1763 *tag = tmp_tag;
1764 if (exclusive) {
1765 if (tmp_type == LOCK_EXCLUSIVE)
1766 *exclusive = 1;
1767 else
1768 *exclusive = 0;
1769 }
1770
1771 return tmp_lockers.size();
1772}
1773
1774librados::NObjectIterator librados::IoCtx::nobjects_begin()
1775{
1776 bufferlist bl;
1777 return nobjects_begin(bl);
1778}
1779
1780librados::NObjectIterator librados::IoCtx::nobjects_begin(
1781 const bufferlist &filter)
1782{
1783 rados_list_ctx_t listh;
1784 rados_nobjects_list_open(io_ctx_impl, &listh);
1785 NObjectIterator iter((ObjListCtx*)listh);
1786 if (filter.length() > 0) {
1787 iter.set_filter(filter);
1788 }
1789 iter.get_next();
1790 return iter;
1791}
1792
1793librados::NObjectIterator librados::IoCtx::nobjects_begin(uint32_t pos)
1794{
1795 bufferlist bl;
1796 return nobjects_begin(pos, bl);
1797}
1798
1799librados::NObjectIterator librados::IoCtx::nobjects_begin(
1800 uint32_t pos, const bufferlist &filter)
1801{
1802 rados_list_ctx_t listh;
1803 rados_nobjects_list_open(io_ctx_impl, &listh);
1804 NObjectIterator iter((ObjListCtx*)listh);
1805 if (filter.length() > 0) {
1806 iter.set_filter(filter);
1807 }
1808 iter.seek(pos);
1809 return iter;
1810}
1811
1812librados::NObjectIterator librados::IoCtx::nobjects_begin(const ObjectCursor& cursor)
1813{
1814 bufferlist bl;
1815 return nobjects_begin(cursor, bl);
1816}
1817
1818librados::NObjectIterator librados::IoCtx::nobjects_begin(
1819 const ObjectCursor& cursor, const bufferlist &filter)
1820{
1821 rados_list_ctx_t listh;
1822 rados_nobjects_list_open(io_ctx_impl, &listh);
1823 NObjectIterator iter((ObjListCtx*)listh);
1824 if (filter.length() > 0) {
1825 iter.set_filter(filter);
1826 }
1827 iter.seek(cursor);
1828 return iter;
1829}
1830
1831const librados::NObjectIterator& librados::IoCtx::nobjects_end() const
1832{
1833 return NObjectIterator::__EndObjectIterator;
1834}
1835
1836int librados::IoCtx::hit_set_list(uint32_t hash, AioCompletion *c,
1837 std::list< std::pair<time_t, time_t> > *pls)
1838{
1839 return io_ctx_impl->hit_set_list(hash, c->pc, pls);
1840}
1841
1842int librados::IoCtx::hit_set_get(uint32_t hash, AioCompletion *c, time_t stamp,
1843 bufferlist *pbl)
1844{
1845 return io_ctx_impl->hit_set_get(hash, c->pc, stamp, pbl);
1846}
1847
1848
1849
1850uint64_t librados::IoCtx::get_last_version()
1851{
1852 return io_ctx_impl->last_version();
1853}
1854
1855int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1856 bufferlist *pbl, size_t len, uint64_t off)
1857{
1858 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off,
1859 io_ctx_impl->snap_seq);
1860}
1861
1862int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
1863 bufferlist *pbl, size_t len, uint64_t off,
1864 uint64_t snapid)
1865{
1866 return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off, snapid);
1867}
1868
1869int librados::IoCtx::aio_exec(const std::string& oid,
1870 librados::AioCompletion *c, const char *cls,
1871 const char *method, bufferlist& inbl,
1872 bufferlist *outbl)
1873{
1874 object_t obj(oid);
1875 return io_ctx_impl->aio_exec(obj, c->pc, cls, method, inbl, outbl);
1876}
1877
1878int librados::IoCtx::aio_cmpext(const std::string& oid,
1879 librados::AioCompletion *c,
1880 uint64_t off,
1881 bufferlist& cmp_bl)
1882{
1883 return io_ctx_impl->aio_cmpext(oid, c->pc, off, cmp_bl);
1884}
1885
1886int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1887 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1888 size_t len, uint64_t off)
1889{
1890 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1891 m, data_bl, len, off,
1892 io_ctx_impl->snap_seq);
1893}
1894
1895int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
1896 std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
1897 size_t len, uint64_t off, uint64_t snapid)
1898{
1899 return io_ctx_impl->aio_sparse_read(oid, c->pc,
1900 m, data_bl, len, off, snapid);
1901}
1902
1903int librados::IoCtx::aio_write(const std::string& oid, librados::AioCompletion *c,
1904 const bufferlist& bl, size_t len, uint64_t off)
1905{
1906 return io_ctx_impl->aio_write(oid, c->pc, bl, len, off);
1907}
1908
1909int librados::IoCtx::aio_append(const std::string& oid, librados::AioCompletion *c,
1910 const bufferlist& bl, size_t len)
1911{
1912 return io_ctx_impl->aio_append(oid, c->pc, bl, len);
1913}
1914
1915int librados::IoCtx::aio_write_full(const std::string& oid, librados::AioCompletion *c,
1916 const bufferlist& bl)
1917{
1918 object_t obj(oid);
1919 return io_ctx_impl->aio_write_full(obj, c->pc, bl);
1920}
1921
1922int librados::IoCtx::aio_writesame(const std::string& oid, librados::AioCompletion *c,
1923 const bufferlist& bl, size_t write_len,
1924 uint64_t off)
1925{
1926 return io_ctx_impl->aio_writesame(oid, c->pc, bl, write_len, off);
1927}
1928
1929
1930int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c)
1931{
1932 return io_ctx_impl->aio_remove(oid, c->pc);
1933}
1934
1935int librados::IoCtx::aio_remove(const std::string& oid, librados::AioCompletion *c, int flags)
1936{
1937 return io_ctx_impl->aio_remove(oid, c->pc, flags);
1938}
1939
1940int librados::IoCtx::aio_flush_async(librados::AioCompletion *c)
1941{
1942 io_ctx_impl->flush_aio_writes_async(c->pc);
1943 return 0;
1944}
1945
1946int librados::IoCtx::aio_flush()
1947{
1948 io_ctx_impl->flush_aio_writes();
1949 return 0;
1950}
1951
1952struct AioGetxattrDataPP {
1953 AioGetxattrDataPP(librados::AioCompletionImpl *c, bufferlist *_bl) :
1954 bl(_bl), completion(c) {}
1955 bufferlist *bl;
1956 struct librados::C_AioCompleteAndSafe completion;
1957};
1958
1959static void rados_aio_getxattr_completepp(rados_completion_t c, void *arg) {
1960 AioGetxattrDataPP *cdata = reinterpret_cast<AioGetxattrDataPP*>(arg);
1961 int rc = rados_aio_get_return_value(c);
1962 if (rc >= 0) {
1963 rc = cdata->bl->length();
1964 }
1965 cdata->completion.finish(rc);
1966 delete cdata;
1967}
1968
1969int librados::IoCtx::aio_getxattr(const std::string& oid, librados::AioCompletion *c,
1970 const char *name, bufferlist& bl)
1971{
1972 // create data object to be passed to async callback
1973 AioGetxattrDataPP *cdata = new AioGetxattrDataPP(c->pc, &bl);
1974 if (!cdata) {
1975 return -ENOMEM;
1976 }
1977 // create completion callback
1978 librados::AioCompletionImpl *comp = new librados::AioCompletionImpl;
1979 comp->set_complete_callback(cdata, rados_aio_getxattr_completepp);
1980 // call actual getxattr from IoCtxImpl
1981 object_t obj(oid);
1982 return io_ctx_impl->aio_getxattr(obj, comp, name, bl);
1983}
1984
1985int librados::IoCtx::aio_getxattrs(const std::string& oid, AioCompletion *c,
1986 map<std::string, bufferlist>& attrset)
1987{
1988 object_t obj(oid);
1989 return io_ctx_impl->aio_getxattrs(obj, c->pc, attrset);
1990}
1991
1992int librados::IoCtx::aio_setxattr(const std::string& oid, AioCompletion *c,
1993 const char *name, bufferlist& bl)
1994{
1995 object_t obj(oid);
1996 return io_ctx_impl->aio_setxattr(obj, c->pc, name, bl);
1997}
1998
1999int librados::IoCtx::aio_rmxattr(const std::string& oid, AioCompletion *c,
2000 const char *name)
2001{
2002 object_t obj(oid);
2003 return io_ctx_impl->aio_rmxattr(obj, c->pc, name);
2004}
2005
2006int librados::IoCtx::aio_stat(const std::string& oid, librados::AioCompletion *c,
2007 uint64_t *psize, time_t *pmtime)
2008{
2009 object_t obj(oid);
2010 return io_ctx_impl->aio_stat(obj, c->pc, psize, pmtime);
2011}
2012
2013int librados::IoCtx::aio_cancel(librados::AioCompletion *c)
2014{
2015 return io_ctx_impl->aio_cancel(c->pc);
2016}
2017
2018int librados::IoCtx::watch(const string& oid, uint64_t ver, uint64_t *cookie,
2019 librados::WatchCtx *ctx)
2020{
2021 object_t obj(oid);
2022 return io_ctx_impl->watch(obj, cookie, ctx, NULL);
2023}
2024
2025int librados::IoCtx::watch2(const string& oid, uint64_t *cookie,
2026 librados::WatchCtx2 *ctx2)
2027{
2028 object_t obj(oid);
2029 return io_ctx_impl->watch(obj, cookie, NULL, ctx2);
2030}
2031
2032int librados::IoCtx::watch3(const string& oid, uint64_t *cookie,
2033 librados::WatchCtx2 *ctx2, uint32_t timeout)
2034{
2035 object_t obj(oid);
2036 return io_ctx_impl->watch(obj, cookie, NULL, ctx2, timeout);
2037}
2038
2039int librados::IoCtx::aio_watch(const string& oid, AioCompletion *c,
2040 uint64_t *cookie,
2041 librados::WatchCtx2 *ctx2)
2042{
2043 object_t obj(oid);
2044 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2);
2045}
2046
2047int librados::IoCtx::aio_watch2(const string& oid, AioCompletion *c,
2048 uint64_t *cookie,
2049 librados::WatchCtx2 *ctx2,
2050 uint32_t timeout)
2051{
2052 object_t obj(oid);
2053 return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2, timeout);
2054}
2055
2056int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
2057{
2058 return io_ctx_impl->unwatch(handle);
2059}
2060
2061int librados::IoCtx::unwatch2(uint64_t handle)
2062{
2063 return io_ctx_impl->unwatch(handle);
2064}
2065
2066int librados::IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c)
2067{
2068 return io_ctx_impl->aio_unwatch(handle, c->pc);
2069}
2070
2071int librados::IoCtx::watch_check(uint64_t handle)
2072{
2073 return io_ctx_impl->watch_check(handle);
2074}
2075
2076int librados::IoCtx::notify(const string& oid, uint64_t ver, bufferlist& bl)
2077{
2078 object_t obj(oid);
2079 return io_ctx_impl->notify(obj, bl, 0, NULL, NULL, NULL);
2080}
2081
2082int librados::IoCtx::notify2(const string& oid, bufferlist& bl,
2083 uint64_t timeout_ms, bufferlist *preplybl)
2084{
2085 object_t obj(oid);
2086 return io_ctx_impl->notify(obj, bl, timeout_ms, preplybl, NULL, NULL);
2087}
2088
2089int librados::IoCtx::aio_notify(const string& oid, AioCompletion *c,
2090 bufferlist& bl, uint64_t timeout_ms,
2091 bufferlist *preplybl)
2092{
2093 object_t obj(oid);
2094 return io_ctx_impl->aio_notify(obj, c->pc, bl, timeout_ms, preplybl, NULL,
2095 NULL);
2096}
2097
2098void librados::IoCtx::notify_ack(const std::string& o,
2099 uint64_t notify_id, uint64_t handle,
2100 bufferlist& bl)
2101{
2102 io_ctx_impl->notify_ack(o, notify_id, handle, bl);
2103}
2104
2105int librados::IoCtx::list_watchers(const std::string& oid,
2106 std::list<obj_watch_t> *out_watchers)
2107{
2108 ObjectReadOperation op;
2109 int r;
2110 op.list_watchers(out_watchers, &r);
2111 bufferlist bl;
2112 int ret = operate(oid, &op, &bl);
2113 if (ret < 0)
2114 return ret;
2115
2116 return r;
2117}
2118
2119int librados::IoCtx::list_snaps(const std::string& oid,
2120 snap_set_t *out_snaps)
2121{
2122 ObjectReadOperation op;
2123 int r;
2124 if (io_ctx_impl->snap_seq != CEPH_SNAPDIR)
2125 return -EINVAL;
2126 op.list_snaps(out_snaps, &r);
2127 bufferlist bl;
2128 int ret = operate(oid, &op, &bl);
2129 if (ret < 0)
2130 return ret;
2131
2132 return r;
2133}
2134
2135void librados::IoCtx::set_notify_timeout(uint32_t timeout)
2136{
2137 io_ctx_impl->set_notify_timeout(timeout);
2138}
2139
2140int librados::IoCtx::set_alloc_hint(const std::string& o,
2141 uint64_t expected_object_size,
2142 uint64_t expected_write_size)
2143{
2144 object_t oid(o);
2145 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2146 expected_write_size, 0);
2147}
2148
2149int librados::IoCtx::set_alloc_hint2(const std::string& o,
2150 uint64_t expected_object_size,
2151 uint64_t expected_write_size,
2152 uint32_t flags)
2153{
2154 object_t oid(o);
2155 return io_ctx_impl->set_alloc_hint(oid, expected_object_size,
2156 expected_write_size, flags);
2157}
2158
2159void librados::IoCtx::set_assert_version(uint64_t ver)
2160{
2161 io_ctx_impl->set_assert_version(ver);
2162}
2163
2164void librados::IoCtx::locator_set_key(const string& key)
2165{
2166 io_ctx_impl->oloc.key = key;
2167}
2168
2169void librados::IoCtx::set_namespace(const string& nspace)
2170{
2171 io_ctx_impl->oloc.nspace = nspace;
2172}
2173
2174int64_t librados::IoCtx::get_id()
2175{
2176 return io_ctx_impl->get_id();
2177}
2178
2179uint32_t librados::IoCtx::get_object_hash_position(const std::string& oid)
2180{
2181 uint32_t hash;
2182 int r = io_ctx_impl->get_object_hash_position(oid, &hash);
2183 if (r < 0)
2184 hash = 0;
2185 return hash;
2186}
2187
2188uint32_t librados::IoCtx::get_object_pg_hash_position(const std::string& oid)
2189{
2190 uint32_t hash;
2191 int r = io_ctx_impl->get_object_pg_hash_position(oid, &hash);
2192 if (r < 0)
2193 hash = 0;
2194 return hash;
2195}
2196
2197int librados::IoCtx::get_object_hash_position2(
2198 const std::string& oid, uint32_t *hash_position)
2199{
2200 return io_ctx_impl->get_object_hash_position(oid, hash_position);
2201}
2202
2203int librados::IoCtx::get_object_pg_hash_position2(
2204 const std::string& oid, uint32_t *pg_hash_position)
2205{
2206 return io_ctx_impl->get_object_pg_hash_position(oid, pg_hash_position);
2207}
2208
2209librados::config_t librados::IoCtx::cct()
2210{
2211 return (config_t)io_ctx_impl->client->cct;
2212}
2213
2214librados::IoCtx::IoCtx(IoCtxImpl *io_ctx_impl_)
2215 : io_ctx_impl(io_ctx_impl_)
2216{
2217}
2218
2219void librados::IoCtx::set_osdmap_full_try()
2220{
2221 io_ctx_impl->objecter->set_osdmap_full_try();
2222}
2223
2224void librados::IoCtx::unset_osdmap_full_try()
2225{
2226 io_ctx_impl->objecter->unset_osdmap_full_try();
2227}
2228
2229///////////////////////////// Rados //////////////////////////////
2230void librados::Rados::version(int *major, int *minor, int *extra)
2231{
2232 rados_version(major, minor, extra);
2233}
2234
2235librados::Rados::Rados() : client(NULL)
2236{
2237}
2238
2239librados::Rados::Rados(IoCtx &ioctx)
2240{
2241 client = ioctx.io_ctx_impl->client;
2242 assert(client != NULL);
2243 client->get();
2244}
2245
2246librados::Rados::~Rados()
2247{
2248 shutdown();
2249}
2250
2251int librados::Rados::init(const char * const id)
2252{
2253 return rados_create((rados_t *)&client, id);
2254}
2255
2256int librados::Rados::init2(const char * const name,
2257 const char * const clustername, uint64_t flags)
2258{
2259 return rados_create2((rados_t *)&client, clustername, name, flags);
2260}
2261
2262int librados::Rados::init_with_context(config_t cct_)
2263{
2264 return rados_create_with_context((rados_t *)&client, (rados_config_t)cct_);
2265}
2266
2267int librados::Rados::connect()
2268{
2269 return client->connect();
2270}
2271
2272librados::config_t librados::Rados::cct()
2273{
2274 return (config_t)client->cct;
2275}
2276
2277int librados::Rados::watch_flush()
2278{
2279 if (!client)
2280 return -EINVAL;
2281 return client->watch_flush();
2282}
2283
2284int librados::Rados::aio_watch_flush(AioCompletion *c)
2285{
2286 if (!client)
2287 return -EINVAL;
2288 return client->async_watch_flush(c->pc);
2289}
2290
2291void librados::Rados::shutdown()
2292{
2293 if (!client)
2294 return;
2295 if (client->put()) {
2296 client->shutdown();
2297 delete client;
2298 client = NULL;
2299 }
2300}
2301
2302uint64_t librados::Rados::get_instance_id()
2303{
2304 return client->get_instance_id();
2305}
2306
2307int librados::Rados::conf_read_file(const char * const path) const
2308{
2309 return rados_conf_read_file((rados_t)client, path);
2310}
2311
2312int librados::Rados::conf_parse_argv(int argc, const char ** argv) const
2313{
2314 return rados_conf_parse_argv((rados_t)client, argc, argv);
2315}
2316
2317int librados::Rados::conf_parse_argv_remainder(int argc, const char ** argv,
2318 const char ** remargv) const
2319{
2320 return rados_conf_parse_argv_remainder((rados_t)client, argc, argv, remargv);
2321}
2322
2323int librados::Rados::conf_parse_env(const char *name) const
2324{
2325 return rados_conf_parse_env((rados_t)client, name);
2326}
2327
2328int librados::Rados::conf_set(const char *option, const char *value)
2329{
2330 return rados_conf_set((rados_t)client, option, value);
2331}
2332
2333int librados::Rados::conf_get(const char *option, std::string &val)
2334{
2335 char *str = NULL;
2336 md_config_t *conf = client->cct->_conf;
2337 int ret = conf->get_val(option, &str, -1);
2338 if (ret) {
2339 free(str);
2340 return ret;
2341 }
2342 val = str;
2343 free(str);
2344 return 0;
2345}
2346
224ce89b
WB
2347int librados::Rados::service_daemon_register(
2348 const std::string& service, ///< service name (e.g., 'rgw')
2349 const std::string& name, ///< daemon name (e.g., 'gwfoo')
2350 const std::map<std::string,std::string>& metadata) ///< static metadata about daemon
2351{
2352 return client->service_daemon_register(service, name, metadata);
2353}
2354
2355int librados::Rados::service_daemon_update_status(
2356 const std::map<std::string,std::string>& status)
2357{
2358 return client->service_daemon_update_status(status);
2359}
2360
7c673cae
FG
2361int librados::Rados::pool_create(const char *name)
2362{
2363 string str(name);
2364 return client->pool_create(str);
2365}
2366
2367int librados::Rados::pool_create(const char *name, uint64_t auid)
2368{
2369 string str(name);
2370 return client->pool_create(str, auid);
2371}
2372
2373int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule)
2374{
2375 string str(name);
2376 return client->pool_create(str, auid, crush_rule);
2377}
2378
2379int librados::Rados::pool_create_async(const char *name, PoolAsyncCompletion *c)
2380{
2381 string str(name);
2382 return client->pool_create_async(str, c->pc);
2383}
2384
2385int librados::Rados::pool_create_async(const char *name, uint64_t auid, PoolAsyncCompletion *c)
2386{
2387 string str(name);
2388 return client->pool_create_async(str, c->pc, auid);
2389}
2390
2391int librados::Rados::pool_create_async(const char *name, uint64_t auid, __u8 crush_rule,
2392 PoolAsyncCompletion *c)
2393{
2394 string str(name);
2395 return client->pool_create_async(str, c->pc, auid, crush_rule);
2396}
2397
2398int librados::Rados::pool_get_base_tier(int64_t pool_id, int64_t* base_tier)
2399{
2400 tracepoint(librados, rados_pool_get_base_tier_enter, (rados_t)client, pool_id);
2401 int retval = client->pool_get_base_tier(pool_id, base_tier);
2402 tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
2403 return retval;
2404}
2405
2406int librados::Rados::pool_delete(const char *name)
2407{
2408 return client->pool_delete(name);
2409}
2410
2411int librados::Rados::pool_delete_async(const char *name, PoolAsyncCompletion *c)
2412{
2413 return client->pool_delete_async(name, c->pc);
2414}
2415
2416int librados::Rados::pool_list(std::list<std::string>& v)
2417{
2418 std::list<std::pair<int64_t, std::string> > pools;
2419 int r = client->pool_list(pools);
2420 if (r < 0) {
2421 return r;
2422 }
2423
2424 v.clear();
2425 for (std::list<std::pair<int64_t, std::string> >::iterator it = pools.begin();
2426 it != pools.end(); ++it) {
2427 v.push_back(it->second);
2428 }
2429 return 0;
2430}
2431
2432int librados::Rados::pool_list2(std::list<std::pair<int64_t, std::string> >& v)
2433{
2434 return client->pool_list(v);
2435}
2436
2437int64_t librados::Rados::pool_lookup(const char *name)
2438{
2439 return client->lookup_pool(name);
2440}
2441
2442int librados::Rados::pool_reverse_lookup(int64_t id, std::string *name)
2443{
2444 return client->pool_get_name(id, name);
2445}
2446
2447int librados::Rados::mon_command(string cmd, const bufferlist& inbl,
2448 bufferlist *outbl, string *outs)
2449{
2450 vector<string> cmdvec;
2451 cmdvec.push_back(cmd);
2452 return client->mon_command(cmdvec, inbl, outbl, outs);
2453}
2454
2455int librados::Rados::osd_command(int osdid, std::string cmd, const bufferlist& inbl,
2456 bufferlist *outbl, std::string *outs)
2457{
2458 vector<string> cmdvec;
2459 cmdvec.push_back(cmd);
2460 return client->osd_command(osdid, cmdvec, inbl, outbl, outs);
2461}
2462
2463int librados::Rados::mgr_command(std::string cmd, const bufferlist& inbl,
2464 bufferlist *outbl, std::string *outs)
2465{
2466 vector<string> cmdvec;
2467 cmdvec.push_back(cmd);
2468 return client->mgr_command(cmdvec, inbl, outbl, outs);
2469}
2470
2471
2472
2473int librados::Rados::pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
2474 bufferlist *outbl, std::string *outs)
2475{
2476 vector<string> cmdvec;
2477 cmdvec.push_back(cmd);
2478
2479 pg_t pgid;
2480 if (!pgid.parse(pgstr))
2481 return -EINVAL;
2482
2483 return client->pg_command(pgid, cmdvec, inbl, outbl, outs);
2484}
2485
2486int librados::Rados::ioctx_create(const char *name, IoCtx &io)
2487{
2488 rados_ioctx_t p;
2489 int ret = rados_ioctx_create((rados_t)client, name, &p);
2490 if (ret)
2491 return ret;
2492 io.close();
2493 io.io_ctx_impl = (IoCtxImpl*)p;
2494 return 0;
2495}
2496
2497int librados::Rados::ioctx_create2(int64_t pool_id, IoCtx &io)
2498{
2499 rados_ioctx_t p;
2500 int ret = rados_ioctx_create2((rados_t)client, pool_id, &p);
2501 if (ret)
2502 return ret;
2503 io.close();
2504 io.io_ctx_impl = (IoCtxImpl*)p;
2505 return 0;
2506}
2507
2508void librados::Rados::test_blacklist_self(bool set)
2509{
2510 client->blacklist_self(set);
2511}
2512
2513int librados::Rados::get_pool_stats(std::list<string>& v,
2514 stats_map& result)
2515{
2516 map<string,::pool_stat_t> rawresult;
2517 int r = client->get_pool_stats(v, rawresult);
2518 for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
2519 p != rawresult.end();
2520 ++p) {
2521 pool_stat_t& pv = result[p->first];
2522 object_stat_sum_t *sum = &p->second.stats.sum;
2523 pv.num_kb = SHIFT_ROUND_UP(sum->num_bytes, 10);
2524 pv.num_bytes = sum->num_bytes;
2525 pv.num_objects = sum->num_objects;
2526 pv.num_object_clones = sum->num_object_clones;
2527 pv.num_object_copies = sum->num_object_copies;
2528 pv.num_objects_missing_on_primary = sum->num_objects_missing_on_primary;
2529 pv.num_objects_unfound = sum->num_objects_unfound;
2530 pv.num_objects_degraded = sum->num_objects_degraded;
2531 pv.num_rd = sum->num_rd;
2532 pv.num_rd_kb = sum->num_rd_kb;
2533 pv.num_wr = sum->num_wr;
2534 pv.num_wr_kb = sum->num_wr_kb;
2535 }
2536 return r;
2537}
2538
2539int librados::Rados::get_pool_stats(std::list<string>& v,
2540 std::map<string, stats_map>& result)
2541{
2542 stats_map m;
2543 int r = get_pool_stats(v, m);
2544 if (r < 0)
2545 return r;
2546 for (map<string,pool_stat_t>::iterator p = m.begin();
2547 p != m.end();
2548 ++p) {
2549 result[p->first][string()] = p->second;
2550 }
2551 return r;
2552}
2553
2554int librados::Rados::get_pool_stats(std::list<string>& v,
2555 string& category, // unused
2556 std::map<string, stats_map>& result)
2557{
2558 return -EOPNOTSUPP;
2559}
2560
2561bool librados::Rados::get_pool_is_selfmanaged_snaps_mode(const std::string& pool)
2562{
2563 return client->get_pool_is_selfmanaged_snaps_mode(pool);
2564}
2565
2566int librados::Rados::cluster_stat(cluster_stat_t& result)
2567{
2568 ceph_statfs stats;
2569 int r = client->get_fs_stats(stats);
2570 result.kb = stats.kb;
2571 result.kb_used = stats.kb_used;
2572 result.kb_avail = stats.kb_avail;
2573 result.num_objects = stats.num_objects;
2574 return r;
2575}
2576
2577int librados::Rados::cluster_fsid(string *fsid)
2578{
2579 return client->get_fsid(fsid);
2580}
2581
2582namespace librados {
2583 struct PlacementGroupImpl {
2584 pg_t pgid;
2585 };
2586
2587 PlacementGroup::PlacementGroup()
2588 : impl{new PlacementGroupImpl}
2589 {}
2590
2591 PlacementGroup::PlacementGroup(const PlacementGroup& pg)
2592 : impl{new PlacementGroupImpl}
2593 {
2594 impl->pgid = pg.impl->pgid;
2595 }
2596
2597 PlacementGroup::~PlacementGroup()
2598 {}
2599
2600 bool PlacementGroup::parse(const char* s)
2601 {
2602 return impl->pgid.parse(s);
2603 }
2604}
2605
2606std::ostream& librados::operator<<(std::ostream& out,
2607 const librados::PlacementGroup& pg)
2608{
2609 return out << pg.impl->pgid;
2610}
2611
2612namespace {
2613 int decode_json(JSONObj *obj, pg_t& pg)
2614 {
2615 string pg_str;
2616 JSONDecoder::decode_json("pgid", pg_str, obj);
2617 if (pg.parse(pg_str.c_str())) {
2618 return 0;
2619 } else {
2620 return -EINVAL;
2621 }
2622 }
2623
2624 int get_inconsistent_pgs(librados::RadosClient& client,
2625 int64_t pool_id,
2626 std::vector<librados::PlacementGroup>* pgs)
2627 {
2628 vector<string> cmd = {
2629 "{\"prefix\": \"pg ls\","
2630 "\"pool\": " + std::to_string(pool_id) + ","
2631 "\"states\": [\"inconsistent\"],"
2632 "\"format\": \"json\"}"
2633 };
2634 bufferlist inbl, outbl;
2635 string outstring;
c07f9fc5 2636 int ret = client.mgr_command(cmd, inbl, &outbl, &outstring);
7c673cae
FG
2637 if (ret) {
2638 return ret;
2639 }
2640 if (!outbl.length()) {
2641 // no pg returned
2642 return ret;
2643 }
2644 JSONParser parser;
2645 if (!parser.parse(outbl.c_str(), outbl.length())) {
2646 return -EINVAL;
2647 }
2648 if (!parser.is_array()) {
2649 return -EINVAL;
2650 }
2651 vector<string> v = parser.get_array_elements();
2652 for (auto i : v) {
2653 JSONParser pg_json;
2654 if (!pg_json.parse(i.c_str(), i.length())) {
2655 return -EINVAL;
2656 }
2657 librados::PlacementGroup pg;
2658 if (decode_json(&pg_json, pg.impl->pgid)) {
2659 return -EINVAL;
2660 }
2661 pgs->emplace_back(pg);
2662 }
2663 return 0;
2664 }
2665}
2666
2667int librados::Rados::get_inconsistent_pgs(int64_t pool_id,
2668 std::vector<PlacementGroup>* pgs)
2669{
2670 return ::get_inconsistent_pgs(*client, pool_id, pgs);
2671}
2672
2673int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
2674 const object_id_t &start_after,
2675 unsigned max_return,
2676 AioCompletion *c,
2677 std::vector<inconsistent_obj_t>* objects,
2678 uint32_t* interval)
2679{
2680 IoCtx ioctx;
2681 const pg_t pgid = pg.impl->pgid;
2682 int r = ioctx_create2(pgid.pool(), ioctx);
2683 if (r < 0) {
2684 return r;
2685 }
2686
2687 return ioctx.io_ctx_impl->get_inconsistent_objects(pgid,
2688 start_after,
2689 max_return,
2690 c->pc,
2691 objects,
2692 interval);
2693}
2694
2695int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
2696 const object_id_t &start_after,
2697 unsigned max_return,
2698 AioCompletion *c,
2699 std::vector<inconsistent_snapset_t>* snapsets,
2700 uint32_t* interval)
2701{
2702 IoCtx ioctx;
2703 const pg_t pgid = pg.impl->pgid;
2704 int r = ioctx_create2(pgid.pool(), ioctx);
2705 if (r < 0) {
2706 return r;
2707 }
2708
2709 return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
2710 start_after,
2711 max_return,
2712 c->pc,
2713 snapsets,
2714 interval);
2715}
2716
2717int librados::Rados::wait_for_latest_osdmap()
2718{
2719 return client->wait_for_latest_osdmap();
2720}
2721
2722int librados::Rados::blacklist_add(const std::string& client_address,
2723 uint32_t expire_seconds)
2724{
2725 return client->blacklist_add(client_address, expire_seconds);
2726}
2727
2728librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
2729{
2730 PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
2731 return new PoolAsyncCompletion(c);
2732}
2733
2734librados::AioCompletion *librados::Rados::aio_create_completion()
2735{
2736 AioCompletionImpl *c = new AioCompletionImpl;
2737 return new AioCompletion(c);
2738}
2739
2740librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
2741 callback_t cb_complete,
2742 callback_t cb_safe)
2743{
2744 AioCompletionImpl *c;
2745 int r = rados_aio_create_completion(cb_arg, cb_complete, cb_safe, (void**)&c);
2746 assert(r == 0);
2747 return new AioCompletion(c);
2748}
2749
2750librados::ObjectOperation::ObjectOperation()
2751{
2752 impl = new ObjectOperationImpl;
2753}
2754
2755librados::ObjectOperation::~ObjectOperation()
2756{
2757 delete impl;
2758}
2759
2760///////////////////////////// C API //////////////////////////////
2761
2762static CephContext *rados_create_cct(const char * const clustername,
2763 CephInitParameters *iparams)
2764{
2765 // missing things compared to global_init:
2766 // g_ceph_context, g_conf, g_lockdep, signal handlers
2767 CephContext *cct = common_preinit(*iparams, CODE_ENVIRONMENT_LIBRARY, 0);
2768 if (clustername)
2769 cct->_conf->cluster = clustername;
2770 cct->_conf->parse_env(); // environment variables override
2771 cct->_conf->apply_changes(NULL);
2772
2773 TracepointProvider::initialize<tracepoint_traits>(cct);
2774 return cct;
2775}
2776
2777extern "C" int rados_create(rados_t *pcluster, const char * const id)
2778{
2779 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
2780 if (id) {
2781 iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
2782 }
2783 CephContext *cct = rados_create_cct("", &iparams);
2784
2785 tracepoint(librados, rados_create_enter, id);
2786 *pcluster = reinterpret_cast<rados_t>(new librados::RadosClient(cct));
2787 tracepoint(librados, rados_create_exit, 0, *pcluster);
2788
2789 cct->put();
2790 return 0;
2791}
2792
2793// as above, but
2794// 1) don't assume 'client.'; name is a full type.id namestr
2795// 2) allow setting clustername
2796// 3) flags is for future expansion (maybe some of the global_init()
2797// behavior is appropriate for some consumers of librados, for instance)
2798
2799extern "C" int rados_create2(rados_t *pcluster, const char *const clustername,
2800 const char * const name, uint64_t flags)
2801{
2802 // client is assumed, but from_str will override
2803 int retval = 0;
2804 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
2805 if (!name || !iparams.name.from_str(name)) {
2806 retval = -EINVAL;
2807 }
2808
2809 CephContext *cct = rados_create_cct(clustername, &iparams);
2810 tracepoint(librados, rados_create2_enter, clustername, name, flags);
2811 if (retval == 0) {
2812 *pcluster = reinterpret_cast<rados_t>(new librados::RadosClient(cct));
2813 }
2814 tracepoint(librados, rados_create2_exit, retval, *pcluster);
2815
2816 cct->put();
2817 return retval;
2818}
2819
2820/* This function is intended for use by Ceph daemons. These daemons have
2821 * already called global_init and want to use that particular configuration for
2822 * their cluster.
2823 */
2824extern "C" int rados_create_with_context(rados_t *pcluster, rados_config_t cct_)
2825{
2826 CephContext *cct = (CephContext *)cct_;
2827 TracepointProvider::initialize<tracepoint_traits>(cct);
2828
2829 tracepoint(librados, rados_create_with_context_enter, cct_);
2830 librados::RadosClient *radosp = new librados::RadosClient(cct);
2831 *pcluster = (void *)radosp;
2832 tracepoint(librados, rados_create_with_context_exit, 0, *pcluster);
2833 return 0;
2834}
2835
2836extern "C" rados_config_t rados_cct(rados_t cluster)
2837{
2838 tracepoint(librados, rados_cct_enter, cluster);
2839 librados::RadosClient *client = (librados::RadosClient *)cluster;
2840 rados_config_t retval = (rados_config_t)client->cct;
2841 tracepoint(librados, rados_cct_exit, retval);
2842 return retval;
2843}
2844
2845extern "C" int rados_connect(rados_t cluster)
2846{
2847 tracepoint(librados, rados_connect_enter, cluster);
2848 librados::RadosClient *client = (librados::RadosClient *)cluster;
2849 int retval = client->connect();
2850 tracepoint(librados, rados_connect_exit, retval);
2851 return retval;
2852}
2853
2854extern "C" void rados_shutdown(rados_t cluster)
2855{
2856 tracepoint(librados, rados_shutdown_enter, cluster);
2857 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
2858 radosp->shutdown();
2859 delete radosp;
2860 tracepoint(librados, rados_shutdown_exit);
2861}
2862
2863extern "C" uint64_t rados_get_instance_id(rados_t cluster)
2864{
2865 tracepoint(librados, rados_get_instance_id_enter, cluster);
2866 librados::RadosClient *client = (librados::RadosClient *)cluster;
2867 uint64_t retval = client->get_instance_id();
2868 tracepoint(librados, rados_get_instance_id_exit, retval);
2869 return retval;
2870}
2871
2872extern "C" void rados_version(int *major, int *minor, int *extra)
2873{
2874 tracepoint(librados, rados_version_enter, major, minor, extra);
2875 if (major)
2876 *major = LIBRADOS_VER_MAJOR;
2877 if (minor)
2878 *minor = LIBRADOS_VER_MINOR;
2879 if (extra)
2880 *extra = LIBRADOS_VER_EXTRA;
2881 tracepoint(librados, rados_version_exit, LIBRADOS_VER_MAJOR, LIBRADOS_VER_MINOR, LIBRADOS_VER_EXTRA);
2882}
2883
2884
2885// -- config --
2886extern "C" int rados_conf_read_file(rados_t cluster, const char *path_list)
2887{
2888 tracepoint(librados, rados_conf_read_file_enter, cluster, path_list);
2889 librados::RadosClient *client = (librados::RadosClient *)cluster;
2890 md_config_t *conf = client->cct->_conf;
2891 ostringstream warnings;
2892 int ret = conf->parse_config_files(path_list, &warnings, 0);
2893 if (ret) {
2894 if (warnings.tellp() > 0)
2895 lderr(client->cct) << warnings.str() << dendl;
2896 client->cct->_conf->complain_about_parse_errors(client->cct);
2897 tracepoint(librados, rados_conf_read_file_exit, ret);
2898 return ret;
2899 }
2900 conf->parse_env(); // environment variables override
2901
2902 conf->apply_changes(NULL);
2903 client->cct->_conf->complain_about_parse_errors(client->cct);
2904 tracepoint(librados, rados_conf_read_file_exit, 0);
2905 return 0;
2906}
2907
2908extern "C" int rados_conf_parse_argv(rados_t cluster, int argc, const char **argv)
2909{
2910 tracepoint(librados, rados_conf_parse_argv_enter, cluster, argc);
2911 int i;
2912 for(i = 0; i < argc; i++) {
2913 tracepoint(librados, rados_conf_parse_argv_arg, argv[i]);
2914 }
2915 librados::RadosClient *client = (librados::RadosClient *)cluster;
2916 md_config_t *conf = client->cct->_conf;
2917 vector<const char*> args;
2918 argv_to_vec(argc, argv, args);
2919 int ret = conf->parse_argv(args);
2920 if (ret) {
2921 tracepoint(librados, rados_conf_parse_argv_exit, ret);
2922 return ret;
2923 }
2924 conf->apply_changes(NULL);
2925 tracepoint(librados, rados_conf_parse_argv_exit, 0);
2926 return 0;
2927}
2928
2929// like above, but return the remainder of argv to contain remaining
2930// unparsed args. Must be allocated to at least argc by caller.
2931// remargv will contain n <= argc pointers to original argv[], the end
2932// of which may be NULL
2933
2934extern "C" int rados_conf_parse_argv_remainder(rados_t cluster, int argc,
2935 const char **argv,
2936 const char **remargv)
2937{
2938 tracepoint(librados, rados_conf_parse_argv_remainder_enter, cluster, argc);
2939 unsigned int i;
2940 for(i = 0; i < (unsigned int) argc; i++) {
2941 tracepoint(librados, rados_conf_parse_argv_remainder_arg, argv[i]);
2942 }
2943 librados::RadosClient *client = (librados::RadosClient *)cluster;
2944 md_config_t *conf = client->cct->_conf;
2945 vector<const char*> args;
2946 for (int i=0; i<argc; i++)
2947 args.push_back(argv[i]);
2948 int ret = conf->parse_argv(args);
2949 if (ret) {
2950 tracepoint(librados, rados_conf_parse_argv_remainder_exit, ret);
2951 return ret;
2952 }
2953 conf->apply_changes(NULL);
2954 assert(args.size() <= (unsigned int)argc);
2955 for (i = 0; i < (unsigned int)argc; ++i) {
2956 if (i < args.size())
2957 remargv[i] = args[i];
2958 else
2959 remargv[i] = (const char *)NULL;
2960 tracepoint(librados, rados_conf_parse_argv_remainder_remarg, remargv[i]);
2961 }
2962 tracepoint(librados, rados_conf_parse_argv_remainder_exit, 0);
2963 return 0;
2964}
2965
2966extern "C" int rados_conf_parse_env(rados_t cluster, const char *env)
2967{
2968 tracepoint(librados, rados_conf_parse_env_enter, cluster, env);
2969 librados::RadosClient *client = (librados::RadosClient *)cluster;
2970 md_config_t *conf = client->cct->_conf;
2971 vector<const char*> args;
2972 env_to_vec(args, env);
2973 int ret = conf->parse_argv(args);
2974 if (ret) {
2975 tracepoint(librados, rados_conf_parse_env_exit, ret);
2976 return ret;
2977 }
2978 conf->apply_changes(NULL);
2979 tracepoint(librados, rados_conf_parse_env_exit, 0);
2980 return 0;
2981}
2982
2983extern "C" int rados_conf_set(rados_t cluster, const char *option, const char *value)
2984{
2985 tracepoint(librados, rados_conf_set_enter, cluster, option, value);
2986 librados::RadosClient *client = (librados::RadosClient *)cluster;
2987 md_config_t *conf = client->cct->_conf;
2988 int ret = conf->set_val(option, value);
2989 if (ret) {
2990 tracepoint(librados, rados_conf_set_exit, ret);
2991 return ret;
2992 }
2993 conf->apply_changes(NULL);
2994 tracepoint(librados, rados_conf_set_exit, 0);
2995 return 0;
2996}
2997
2998/* cluster info */
2999extern "C" int rados_cluster_stat(rados_t cluster, rados_cluster_stat_t *result)
3000{
3001 tracepoint(librados, rados_cluster_stat_enter, cluster);
3002 librados::RadosClient *client = (librados::RadosClient *)cluster;
3003
3004 ceph_statfs stats;
3005 int r = client->get_fs_stats(stats);
3006 result->kb = stats.kb;
3007 result->kb_used = stats.kb_used;
3008 result->kb_avail = stats.kb_avail;
3009 result->num_objects = stats.num_objects;
3010 tracepoint(librados, rados_cluster_stat_exit, r, result->kb, result->kb_used, result->kb_avail, result->num_objects);
3011 return r;
3012}
3013
3014extern "C" int rados_conf_get(rados_t cluster, const char *option, char *buf, size_t len)
3015{
3016 tracepoint(librados, rados_conf_get_enter, cluster, option, len);
3017 char *tmp = buf;
3018 librados::RadosClient *client = (librados::RadosClient *)cluster;
3019 md_config_t *conf = client->cct->_conf;
3020 int retval = conf->get_val(option, &tmp, len);
3021 tracepoint(librados, rados_conf_get_exit, retval, retval ? "" : option);
3022 return retval;
3023}
3024
3025extern "C" int64_t rados_pool_lookup(rados_t cluster, const char *name)
3026{
3027 tracepoint(librados, rados_pool_lookup_enter, cluster, name);
3028 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3029 int64_t retval = radosp->lookup_pool(name);
3030 tracepoint(librados, rados_pool_lookup_exit, retval);
3031 return retval;
3032}
3033
3034extern "C" int rados_pool_reverse_lookup(rados_t cluster, int64_t id,
3035 char *buf, size_t maxlen)
3036{
3037 tracepoint(librados, rados_pool_reverse_lookup_enter, cluster, id, maxlen);
3038 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3039 std::string name;
3040 int r = radosp->pool_get_name(id, &name);
3041 if (r < 0) {
3042 tracepoint(librados, rados_pool_reverse_lookup_exit, r, "");
3043 return r;
3044 }
3045 if (name.length() >= maxlen) {
3046 tracepoint(librados, rados_pool_reverse_lookup_exit, -ERANGE, "");
3047 return -ERANGE;
3048 }
3049 strcpy(buf, name.c_str());
3050 int retval = name.length();
3051 tracepoint(librados, rados_pool_reverse_lookup_exit, retval, buf);
3052 return retval;
3053}
3054
3055extern "C" int rados_cluster_fsid(rados_t cluster, char *buf,
3056 size_t maxlen)
3057{
3058 tracepoint(librados, rados_cluster_fsid_enter, cluster, maxlen);
3059 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3060 std::string fsid;
3061 radosp->get_fsid(&fsid);
3062 if (fsid.length() >= maxlen) {
3063 tracepoint(librados, rados_cluster_fsid_exit, -ERANGE, "");
3064 return -ERANGE;
3065 }
3066 strcpy(buf, fsid.c_str());
3067 int retval = fsid.length();
3068 tracepoint(librados, rados_cluster_fsid_exit, retval, buf);
3069 return retval;
3070}
3071
3072extern "C" int rados_wait_for_latest_osdmap(rados_t cluster)
3073{
3074 tracepoint(librados, rados_wait_for_latest_osdmap_enter, cluster);
3075 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3076 int retval = radosp->wait_for_latest_osdmap();
3077 tracepoint(librados, rados_wait_for_latest_osdmap_exit, retval);
3078 return retval;
3079}
3080
3081extern "C" int rados_blacklist_add(rados_t cluster, char *client_address,
3082 uint32_t expire_seconds)
3083{
3084 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3085 return radosp->blacklist_add(client_address, expire_seconds);
3086}
3087
c07f9fc5
FG
3088extern "C" int rados_application_enable(rados_ioctx_t io, const char *app_name,
3089 int force)
3090{
3091 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3092 return ctx->application_enable(app_name, force != 0);
3093}
3094
3095extern "C" int rados_application_list(rados_ioctx_t io, char *values,
3096 size_t *values_len)
3097{
3098 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3099 std::set<std::string> app_names;
3100 int r = ctx->application_list(&app_names);
3101 if (r < 0) {
3102 return r;
3103 }
3104
3105 size_t total_len = 0;
3106 for (auto app_name : app_names) {
3107 total_len += app_name.size() + 1;
3108 }
3109
3110 if (*values_len < total_len) {
3111 *values_len = total_len;
3112 return -ERANGE;
3113 }
3114
3115 char *values_p = values;
3116 for (auto app_name : app_names) {
3117 size_t len = app_name.size() + 1;
3118 strncpy(values_p, app_name.c_str(), len);
3119 values_p += len;
3120 }
3121 *values_p = '\0';
3122 *values_len = total_len;
3123 return 0;
3124}
3125
3126extern "C" int rados_application_metadata_get(rados_ioctx_t io,
3127 const char *app_name,
3128 const char *key, char *value,
3129 size_t *value_len)
3130{
3131 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3132 std::string value_str;
3133 int r = ctx->application_metadata_get(app_name, key, &value_str);
3134 if (r < 0) {
3135 return r;
3136 }
3137
3138 size_t len = value_str.size() + 1;
3139 if (*value_len < len) {
3140 *value_len = len;
3141 return -ERANGE;
3142 }
3143
3144 strncpy(value, value_str.c_str(), len);
3145 *value_len = len;
3146 return 0;
3147}
3148
3149extern "C" int rados_application_metadata_set(rados_ioctx_t io,
3150 const char *app_name,
3151 const char *key,
3152 const char *value)
3153{
3154 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3155 return ctx->application_metadata_set(app_name, key, value);
3156}
3157
3158extern "C" int rados_application_metadata_remove(rados_ioctx_t io,
3159 const char *app_name,
3160 const char *key)
3161{
3162 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3163 return ctx->application_metadata_remove(app_name, key);
3164}
3165
3166extern "C" int rados_application_metadata_list(rados_ioctx_t io,
3167 const char *app_name,
3168 char *keys, size_t *keys_len,
3169 char *values, size_t *vals_len)
3170{
3171 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3172 std::map<std::string, std::string> metadata;
3173 int r = ctx->application_metadata_list(app_name, &metadata);
3174 if (r < 0) {
3175 return r;
3176 }
3177
3178 size_t total_key_len = 0;
3179 size_t total_val_len = 0;
3180 for (auto pair : metadata) {
3181 total_key_len += pair.first.size() + 1;
3182 total_val_len += pair.second.size() + 1;
3183 }
3184
3185 if (*keys_len < total_key_len || *vals_len < total_val_len) {
3186 *keys_len = total_key_len;
3187 *vals_len = total_val_len;
3188 return -ERANGE;
3189 }
3190
3191 char *keys_p = keys;
3192 char *vals_p = values;
3193 for (auto pair : metadata) {
3194 size_t key_len = pair.first.size() + 1;
3195 strncpy(keys_p, pair.first.c_str(), key_len);
3196 keys_p += key_len;
3197
3198 size_t val_len = pair.second.size() + 1;
3199 strncpy(vals_p, pair.second.c_str(), val_len);
3200 vals_p += val_len;
3201 }
3202 *keys_p = '\0';
3203 *keys_len = total_key_len;
3204
3205 *vals_p = '\0';
3206 *vals_len = total_val_len;
3207 return 0;
3208}
3209
7c673cae
FG
3210extern "C" int rados_pool_list(rados_t cluster, char *buf, size_t len)
3211{
3212 tracepoint(librados, rados_pool_list_enter, cluster, len);
3213 librados::RadosClient *client = (librados::RadosClient *)cluster;
3214 std::list<std::pair<int64_t, std::string> > pools;
3215 int r = client->pool_list(pools);
3216 if (r < 0) {
3217 tracepoint(librados, rados_pool_list_exit, r);
3218 return r;
3219 }
3220
3221 if (len > 0 && !buf) {
3222 tracepoint(librados, rados_pool_list_exit, -EINVAL);
3223 return -EINVAL;
3224 }
3225
3226 char *b = buf;
3227 if (b)
3228 memset(b, 0, len);
3229 int needed = 0;
3230 std::list<std::pair<int64_t, std::string> >::const_iterator i = pools.begin();
3231 std::list<std::pair<int64_t, std::string> >::const_iterator p_end =
3232 pools.end();
3233 for (; i != p_end; ++i) {
3234 int rl = i->second.length() + 1;
3235 if (len < (unsigned)rl)
3236 break;
3237 const char* pool = i->second.c_str();
3238 tracepoint(librados, rados_pool_list_pool, pool);
3239 if (b) {
3240 strncat(b, pool, rl);
3241 b += rl;
3242 }
3243 needed += rl;
3244 len -= rl;
3245 }
3246 for (; i != p_end; ++i) {
3247 int rl = i->second.length() + 1;
3248 needed += rl;
3249 }
3250 int retval = needed + 1;
3251 tracepoint(librados, rados_pool_list_exit, retval);
3252 return retval;
3253}
3254
3255CEPH_RADOS_API int rados_inconsistent_pg_list(rados_t cluster, int64_t pool_id,
3256 char *buf, size_t len)
3257{
3258 tracepoint(librados, rados_inconsistent_pg_list_enter, cluster, pool_id, len);
3259 librados::RadosClient *client = (librados::RadosClient *)cluster;
3260 std::vector<librados::PlacementGroup> pgs;
3261 int r = ::get_inconsistent_pgs(*client, pool_id, &pgs);
3262 if (r < 0) {
3263 tracepoint(librados, rados_inconsistent_pg_list_exit, r);
3264 return r;
3265 }
3266
3267 if (len > 0 && !buf) {
3268 tracepoint(librados, rados_inconsistent_pg_list_exit, -EINVAL);
3269 return -EINVAL;
3270 }
3271
3272 char *b = buf;
3273 if (b)
3274 memset(b, 0, len);
3275 int needed = 0;
3276 for (const auto pg : pgs) {
3277 std::ostringstream ss;
3278 ss << pg;
3279 auto s = ss.str();
3280 unsigned rl = s.length() + 1;
3281 if (b && len >= rl) {
3282 tracepoint(librados, rados_inconsistent_pg_list_pg, s.c_str());
3283 strncat(b, s.c_str(), rl);
3284 b += rl;
3285 len -= rl;
3286 }
3287 needed += rl;
3288 }
3289 int retval = needed + 1;
3290 tracepoint(librados, rados_inconsistent_pg_list_exit, retval);
3291 return retval;
3292}
3293
c07f9fc5
FG
3294
3295static void dict_to_map(const char *dict,
3296 std::map<std::string, std::string>* dict_map)
3297{
3298 while (*dict != '\0') {
3299 const char* key = dict;
3300 dict += strlen(key) + 1;
3301 const char* value = dict;
3302 dict += strlen(value) + 1;
3303 (*dict_map)[key] = value;
3304 }
3305}
3306
3307CEPH_RADOS_API int rados_service_register(rados_t cluster, const char *service,
3308 const char *daemon,
3309 const char *metadata_dict)
3310{
3311 librados::RadosClient *client = (librados::RadosClient *)cluster;
3312
3313 std::map<std::string, std::string> metadata;
3314 dict_to_map(metadata_dict, &metadata);
3315
3316 return client->service_daemon_register(service, daemon, metadata);
3317}
3318
3319CEPH_RADOS_API int rados_service_update_status(rados_t cluster,
3320 const char *status_dict)
3321{
3322 librados::RadosClient *client = (librados::RadosClient *)cluster;
3323
3324 std::map<std::string, std::string> status;
3325 dict_to_map(status_dict, &status);
3326
3327 return client->service_daemon_update_status(status);
3328}
3329
7c673cae
FG
3330static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
3331{
3332 if (outbuf) {
3333 if (outbl.length() > 0) {
3334 *outbuf = (char *)malloc(outbl.length());
3335 memcpy(*outbuf, outbl.c_str(), outbl.length());
3336 } else {
3337 *outbuf = NULL;
3338 }
3339 }
3340 if (outbuflen)
3341 *outbuflen = outbl.length();
3342}
3343
3344static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
3345{
3346 if (outbuf) {
3347 if (outbl.length() > 0) {
3348 *outbuf = (char *)malloc(outbl.length());
3349 memcpy(*outbuf, outbl.c_str(), outbl.length());
3350 } else {
3351 *outbuf = NULL;
3352 }
3353 }
3354 if (outbuflen)
3355 *outbuflen = outbl.length();
3356}
3357
3358extern "C" int rados_ping_monitor(rados_t cluster, const char *mon_id,
3359 char **outstr, size_t *outstrlen)
3360{
3361 tracepoint(librados, rados_ping_monitor_enter, cluster, mon_id);
3362 librados::RadosClient *client = (librados::RadosClient *)cluster;
3363 string str;
3364
3365 if (!mon_id) {
3366 tracepoint(librados, rados_ping_monitor_exit, -EINVAL, NULL, NULL);
3367 return -EINVAL;
3368 }
3369
3370 int ret = client->ping_monitor(mon_id, &str);
3371 if (ret == 0) {
3372 do_out_buffer(str, outstr, outstrlen);
3373 }
3374 tracepoint(librados, rados_ping_monitor_exit, ret, ret < 0 ? NULL : outstr, ret < 0 ? NULL : outstrlen);
3375 return ret;
3376}
3377
3378extern "C" int rados_mon_command(rados_t cluster, const char **cmd,
3379 size_t cmdlen,
3380 const char *inbuf, size_t inbuflen,
3381 char **outbuf, size_t *outbuflen,
3382 char **outs, size_t *outslen)
3383{
3384 tracepoint(librados, rados_mon_command_enter, cluster, cmdlen, inbuf, inbuflen);
3385 librados::RadosClient *client = (librados::RadosClient *)cluster;
3386 bufferlist inbl;
3387 bufferlist outbl;
3388 string outstring;
3389 vector<string> cmdvec;
3390
3391 for (size_t i = 0; i < cmdlen; i++) {
3392 tracepoint(librados, rados_mon_command_cmd, cmd[i]);
3393 cmdvec.push_back(cmd[i]);
3394 }
3395
3396 inbl.append(inbuf, inbuflen);
3397 int ret = client->mon_command(cmdvec, inbl, &outbl, &outstring);
3398
3399 do_out_buffer(outbl, outbuf, outbuflen);
3400 do_out_buffer(outstring, outs, outslen);
3401 tracepoint(librados, rados_mon_command_exit, ret, outbuf, outbuflen, outs, outslen);
3402 return ret;
3403}
3404
3405extern "C" int rados_mon_command_target(rados_t cluster, const char *name,
3406 const char **cmd,
3407 size_t cmdlen,
3408 const char *inbuf, size_t inbuflen,
3409 char **outbuf, size_t *outbuflen,
3410 char **outs, size_t *outslen)
3411{
3412 tracepoint(librados, rados_mon_command_target_enter, cluster, name, cmdlen, inbuf, inbuflen);
3413 librados::RadosClient *client = (librados::RadosClient *)cluster;
3414 bufferlist inbl;
3415 bufferlist outbl;
3416 string outstring;
3417 vector<string> cmdvec;
3418
3419 // is this a numeric id?
3420 char *endptr;
3421 errno = 0;
3422 long rank = strtol(name, &endptr, 10);
3423 if ((errno == ERANGE && (rank == LONG_MAX || rank == LONG_MIN)) ||
3424 (errno != 0 && rank == 0) ||
3425 endptr == name || // no digits
3426 *endptr != '\0') { // extra characters
3427 rank = -1;
3428 }
3429
3430 for (size_t i = 0; i < cmdlen; i++) {
3431 tracepoint(librados, rados_mon_command_target_cmd, cmd[i]);
3432 cmdvec.push_back(cmd[i]);
3433 }
3434
3435 inbl.append(inbuf, inbuflen);
3436 int ret;
3437 if (rank >= 0)
3438 ret = client->mon_command(rank, cmdvec, inbl, &outbl, &outstring);
3439 else
3440 ret = client->mon_command(name, cmdvec, inbl, &outbl, &outstring);
3441
3442 do_out_buffer(outbl, outbuf, outbuflen);
3443 do_out_buffer(outstring, outs, outslen);
3444 tracepoint(librados, rados_mon_command_target_exit, ret, outbuf, outbuflen, outs, outslen);
3445 return ret;
3446}
3447
3448extern "C" int rados_osd_command(rados_t cluster, int osdid, const char **cmd,
3449 size_t cmdlen,
3450 const char *inbuf, size_t inbuflen,
3451 char **outbuf, size_t *outbuflen,
3452 char **outs, size_t *outslen)
3453{
3454 tracepoint(librados, rados_osd_command_enter, cluster, osdid, cmdlen, inbuf, inbuflen);
3455 librados::RadosClient *client = (librados::RadosClient *)cluster;
3456 bufferlist inbl;
3457 bufferlist outbl;
3458 string outstring;
3459 vector<string> cmdvec;
3460
3461 for (size_t i = 0; i < cmdlen; i++) {
3462 tracepoint(librados, rados_osd_command_cmd, cmd[i]);
3463 cmdvec.push_back(cmd[i]);
3464 }
3465
3466 inbl.append(inbuf, inbuflen);
3467 int ret = client->osd_command(osdid, cmdvec, inbl, &outbl, &outstring);
3468
3469 do_out_buffer(outbl, outbuf, outbuflen);
3470 do_out_buffer(outstring, outs, outslen);
3471 tracepoint(librados, rados_osd_command_exit, ret, outbuf, outbuflen, outs, outslen);
3472 return ret;
3473}
3474
3475extern "C" int rados_mgr_command(rados_t cluster, const char **cmd,
3476 size_t cmdlen,
3477 const char *inbuf, size_t inbuflen,
3478 char **outbuf, size_t *outbuflen,
3479 char **outs, size_t *outslen)
3480{
3481 tracepoint(librados, rados_mgr_command_enter, cluster, cmdlen, inbuf,
3482 inbuflen);
3483
3484 librados::RadosClient *client = (librados::RadosClient *)cluster;
3485 bufferlist inbl;
3486 bufferlist outbl;
3487 string outstring;
3488 vector<string> cmdvec;
3489
3490 for (size_t i = 0; i < cmdlen; i++) {
3491 tracepoint(librados, rados_mgr_command_cmd, cmd[i]);
3492 cmdvec.push_back(cmd[i]);
3493 }
3494
3495 inbl.append(inbuf, inbuflen);
3496 int ret = client->mgr_command(cmdvec, inbl, &outbl, &outstring);
3497
3498 do_out_buffer(outbl, outbuf, outbuflen);
3499 do_out_buffer(outstring, outs, outslen);
3500 tracepoint(librados, rados_mgr_command_exit, ret, outbuf, outbuflen, outs,
3501 outslen);
3502 return ret;
3503}
3504
3505extern "C" int rados_pg_command(rados_t cluster, const char *pgstr,
3506 const char **cmd, size_t cmdlen,
3507 const char *inbuf, size_t inbuflen,
3508 char **outbuf, size_t *outbuflen,
3509 char **outs, size_t *outslen)
3510{
3511 tracepoint(librados, rados_pg_command_enter, cluster, pgstr, cmdlen, inbuf, inbuflen);
3512 librados::RadosClient *client = (librados::RadosClient *)cluster;
3513 bufferlist inbl;
3514 bufferlist outbl;
3515 string outstring;
3516 pg_t pgid;
3517 vector<string> cmdvec;
3518
3519 for (size_t i = 0; i < cmdlen; i++) {
3520 tracepoint(librados, rados_pg_command_cmd, cmd[i]);
3521 cmdvec.push_back(cmd[i]);
3522 }
3523
3524 inbl.append(inbuf, inbuflen);
3525 if (!pgid.parse(pgstr))
3526 return -EINVAL;
3527
3528 int ret = client->pg_command(pgid, cmdvec, inbl, &outbl, &outstring);
3529
3530 do_out_buffer(outbl, outbuf, outbuflen);
3531 do_out_buffer(outstring, outs, outslen);
3532 tracepoint(librados, rados_pg_command_exit, ret, outbuf, outbuflen, outs, outslen);
3533 return ret;
3534}
3535
3536extern "C" void rados_buffer_free(char *buf)
3537{
3538 tracepoint(librados, rados_buffer_free_enter, buf);
3539 if (buf)
3540 free(buf);
3541 tracepoint(librados, rados_buffer_free_exit);
3542}
3543
3544extern "C" int rados_monitor_log(rados_t cluster, const char *level, rados_log_callback_t cb, void *arg)
3545{
3546 tracepoint(librados, rados_monitor_log_enter, cluster, level, cb, arg);
3547 librados::RadosClient *client = (librados::RadosClient *)cluster;
31f18b77 3548 int retval = client->monitor_log(level, cb, nullptr, arg);
7c673cae
FG
3549 tracepoint(librados, rados_monitor_log_exit, retval);
3550 return retval;
3551}
3552
31f18b77
FG
3553extern "C" int rados_monitor_log2(rados_t cluster, const char *level,
3554 rados_log_callback2_t cb, void *arg)
3555{
3556 tracepoint(librados, rados_monitor_log2_enter, cluster, level, cb, arg);
3557 librados::RadosClient *client = (librados::RadosClient *)cluster;
3558 int retval = client->monitor_log(level, nullptr, cb, arg);
3559 tracepoint(librados, rados_monitor_log2_exit, retval);
3560 return retval;
3561}
3562
7c673cae
FG
3563extern "C" int rados_ioctx_create(rados_t cluster, const char *name, rados_ioctx_t *io)
3564{
3565 tracepoint(librados, rados_ioctx_create_enter, cluster, name);
3566 librados::RadosClient *client = (librados::RadosClient *)cluster;
3567 librados::IoCtxImpl *ctx;
3568
3569 int r = client->create_ioctx(name, &ctx);
3570 if (r < 0) {
3571 tracepoint(librados, rados_ioctx_create_exit, r, NULL);
3572 return r;
3573 }
3574
3575 *io = ctx;
3576 ctx->get();
3577 tracepoint(librados, rados_ioctx_create_exit, 0, ctx);
3578 return 0;
3579}
3580
3581extern "C" int rados_ioctx_create2(rados_t cluster, int64_t pool_id,
3582 rados_ioctx_t *io)
3583{
3584 tracepoint(librados, rados_ioctx_create2_enter, cluster, pool_id);
3585 librados::RadosClient *client = (librados::RadosClient *)cluster;
3586 librados::IoCtxImpl *ctx;
3587
3588 int r = client->create_ioctx(pool_id, &ctx);
3589 if (r < 0) {
3590 tracepoint(librados, rados_ioctx_create2_exit, r, NULL);
3591 return r;
3592 }
3593
3594 *io = ctx;
3595 ctx->get();
3596 tracepoint(librados, rados_ioctx_create2_exit, 0, ctx);
3597 return 0;
3598}
3599
3600extern "C" void rados_ioctx_destroy(rados_ioctx_t io)
3601{
3602 tracepoint(librados, rados_ioctx_destroy_enter, io);
3603 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3604 ctx->put();
3605 tracepoint(librados, rados_ioctx_destroy_exit);
3606}
3607
3608extern "C" int rados_ioctx_pool_stat(rados_ioctx_t io, struct rados_pool_stat_t *stats)
3609{
3610 tracepoint(librados, rados_ioctx_pool_stat_enter, io);
3611 librados::IoCtxImpl *io_ctx_impl = (librados::IoCtxImpl *)io;
3612 list<string> ls;
3613 std::string pool_name;
3614
3615 int err = io_ctx_impl->client->pool_get_name(io_ctx_impl->get_id(), &pool_name);
3616 if (err) {
3617 tracepoint(librados, rados_ioctx_pool_stat_exit, err, stats);
3618 return err;
3619 }
3620 ls.push_back(pool_name);
3621
3622 map<string, ::pool_stat_t> rawresult;
3623 err = io_ctx_impl->client->get_pool_stats(ls, rawresult);
3624 if (err) {
3625 tracepoint(librados, rados_ioctx_pool_stat_exit, err, stats);
3626 return err;
3627 }
3628
3629 ::pool_stat_t& r = rawresult[pool_name];
3630 stats->num_kb = SHIFT_ROUND_UP(r.stats.sum.num_bytes, 10);
3631 stats->num_bytes = r.stats.sum.num_bytes;
3632 stats->num_objects = r.stats.sum.num_objects;
3633 stats->num_object_clones = r.stats.sum.num_object_clones;
3634 stats->num_object_copies = r.stats.sum.num_object_copies;
3635 stats->num_objects_missing_on_primary = r.stats.sum.num_objects_missing_on_primary;
3636 stats->num_objects_unfound = r.stats.sum.num_objects_unfound;
3637 stats->num_objects_degraded =
3638 r.stats.sum.num_objects_degraded +
3639 r.stats.sum.num_objects_misplaced; // FIXME: this is imprecise
3640 stats->num_rd = r.stats.sum.num_rd;
3641 stats->num_rd_kb = r.stats.sum.num_rd_kb;
3642 stats->num_wr = r.stats.sum.num_wr;
3643 stats->num_wr_kb = r.stats.sum.num_wr_kb;
3644 tracepoint(librados, rados_ioctx_pool_stat_exit, 0, stats);
3645 return 0;
3646}
3647
3648extern "C" rados_config_t rados_ioctx_cct(rados_ioctx_t io)
3649{
3650 tracepoint(librados, rados_ioctx_cct_enter, io);
3651 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3652 rados_config_t retval = (rados_config_t)ctx->client->cct;
3653 tracepoint(librados, rados_ioctx_cct_exit, retval);
3654 return retval;
3655}
3656
3657extern "C" void rados_ioctx_snap_set_read(rados_ioctx_t io, rados_snap_t seq)
3658{
3659 tracepoint(librados, rados_ioctx_snap_set_read_enter, io, seq);
3660 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3661 ctx->set_snap_read((snapid_t)seq);
3662 tracepoint(librados, rados_ioctx_snap_set_read_exit);
3663}
3664
3665extern "C" int rados_ioctx_selfmanaged_snap_set_write_ctx(rados_ioctx_t io,
3666 rados_snap_t seq, rados_snap_t *snaps, int num_snaps)
3667{
3668 tracepoint(librados, rados_ioctx_selfmanaged_snap_set_write_ctx_enter, io, seq, snaps, num_snaps);
3669 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3670 vector<snapid_t> snv;
3671 snv.resize(num_snaps);
3672 for (int i=0; i<num_snaps; i++) {
3673 snv[i] = (snapid_t)snaps[i];
3674 }
3675 int retval = ctx->set_snap_write_context((snapid_t)seq, snv);
3676 tracepoint(librados, rados_ioctx_selfmanaged_snap_set_write_ctx_exit, retval);
3677 return retval;
3678}
3679
3680extern "C" int rados_write(rados_ioctx_t io, const char *o, const char *buf, size_t len, uint64_t off)
3681{
3682 tracepoint(librados, rados_write_enter, io, o, buf, len, off);
3683 if (len > UINT_MAX/2)
3684 return -E2BIG;
3685 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3686 object_t oid(o);
3687 bufferlist bl;
3688 bl.append(buf, len);
3689 int retval = ctx->write(oid, bl, len, off);
3690 tracepoint(librados, rados_write_exit, retval);
3691 return retval;
3692}
3693
3694extern "C" int rados_append(rados_ioctx_t io, const char *o, const char *buf, size_t len)
3695{
3696 tracepoint(librados, rados_append_enter, io, o, buf, len);
3697 if (len > UINT_MAX/2)
3698 return -E2BIG;
3699 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3700 object_t oid(o);
3701 bufferlist bl;
3702 bl.append(buf, len);
3703 int retval = ctx->append(oid, bl, len);
3704 tracepoint(librados, rados_append_exit, retval);
3705 return retval;
3706}
3707
3708extern "C" int rados_write_full(rados_ioctx_t io, const char *o, const char *buf, size_t len)
3709{
3710 tracepoint(librados, rados_write_full_enter, io, o, buf, len);
3711 if (len > UINT_MAX/2)
3712 return -E2BIG;
3713 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3714 object_t oid(o);
3715 bufferlist bl;
3716 bl.append(buf, len);
3717 int retval = ctx->write_full(oid, bl);
3718 tracepoint(librados, rados_write_full_exit, retval);
3719 return retval;
3720}
3721
3722extern "C" int rados_writesame(rados_ioctx_t io,
3723 const char *o,
3724 const char *buf,
3725 size_t data_len,
3726 size_t write_len,
3727 uint64_t off)
3728{
3729 tracepoint(librados, rados_writesame_enter, io, o, buf, data_len, write_len, off);
3730 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3731 object_t oid(o);
3732 bufferlist bl;
3733 bl.append(buf, data_len);
3734 int retval = ctx->writesame(oid, bl, write_len, off);
3735 tracepoint(librados, rados_writesame_exit, retval);
3736 return retval;
3737}
3738
3739extern "C" int rados_trunc(rados_ioctx_t io, const char *o, uint64_t size)
3740{
3741 tracepoint(librados, rados_trunc_enter, io, o, size);
3742 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3743 object_t oid(o);
3744 int retval = ctx->trunc(oid, size);
3745 tracepoint(librados, rados_trunc_exit, retval);
3746 return retval;
3747}
3748
3749extern "C" int rados_remove(rados_ioctx_t io, const char *o)
3750{
3751 tracepoint(librados, rados_remove_enter, io, o);
3752 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3753 object_t oid(o);
3754 int retval = ctx->remove(oid);
3755 tracepoint(librados, rados_remove_exit, retval);
3756 return retval;
3757}
3758
3759extern "C" int rados_read(rados_ioctx_t io, const char *o, char *buf, size_t len, uint64_t off)
3760{
3761 tracepoint(librados, rados_read_enter, io, o, buf, len, off);
3762 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3763 int ret;
3764 object_t oid(o);
3765
3766 bufferlist bl;
3767 bufferptr bp = buffer::create_static(len, buf);
3768 bl.push_back(bp);
3769
3770 ret = ctx->read(oid, bl, len, off);
3771 if (ret >= 0) {
3772 if (bl.length() > len) {
3773 tracepoint(librados, rados_read_exit, -ERANGE, NULL);
3774 return -ERANGE;
3775 }
3776 if (!bl.is_provided_buffer(buf))
3777 bl.copy(0, bl.length(), buf);
3778 ret = bl.length(); // hrm :/
3779 }
3780
3781 tracepoint(librados, rados_read_exit, ret, buf);
3782 return ret;
3783}
3784
3785extern "C" int rados_checksum(rados_ioctx_t io, const char *o,
3786 rados_checksum_type_t type,
3787 const char *init_value, size_t init_value_len,
3788 size_t len, uint64_t off, size_t chunk_size,
3789 char *pchecksum, size_t checksum_len)
3790{
3791 tracepoint(librados, rados_checksum_enter, io, o, type, init_value,
3792 init_value_len, len, off, chunk_size);
3793 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3794 object_t oid(o);
3795
3796 bufferlist init_value_bl;
3797 init_value_bl.append(init_value, init_value_len);
3798
3799 bufferlist checksum_bl;
3800
3801 int retval = ctx->checksum(oid, get_checksum_op_type(type), init_value_bl,
3802 len, off, chunk_size, &checksum_bl);
3803 if (retval >= 0) {
3804 if (checksum_bl.length() > checksum_len) {
3805 tracepoint(librados, rados_checksum_exit, -ERANGE, NULL, 0);
3806 return -ERANGE;
3807 }
3808
3809 checksum_bl.copy(0, checksum_bl.length(), pchecksum);
3810 }
3811 tracepoint(librados, rados_checksum_exit, retval, pchecksum, checksum_len);
3812 return retval;
3813}
3814
3815extern "C" uint64_t rados_get_last_version(rados_ioctx_t io)
3816{
3817 tracepoint(librados, rados_get_last_version_enter, io);
3818 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3819 uint64_t retval = ctx->last_version();
3820 tracepoint(librados, rados_get_last_version_exit, retval);
3821 return retval;
3822}
3823
3824extern "C" int rados_pool_create(rados_t cluster, const char *name)
3825{
3826 tracepoint(librados, rados_pool_create_enter, cluster, name);
3827 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3828 string sname(name);
3829 int retval = radosp->pool_create(sname);
3830 tracepoint(librados, rados_pool_create_exit, retval);
3831 return retval;
3832}
3833
3834extern "C" int rados_pool_create_with_auid(rados_t cluster, const char *name,
3835 uint64_t auid)
3836{
3837 tracepoint(librados, rados_pool_create_with_auid_enter, cluster, name, auid);
3838 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3839 string sname(name);
3840 int retval = radosp->pool_create(sname, auid);
3841 tracepoint(librados, rados_pool_create_with_auid_exit, retval);
3842 return retval;
3843}
3844
3845extern "C" int rados_pool_create_with_crush_rule(rados_t cluster, const char *name,
3846 __u8 crush_rule_num)
3847{
3848 tracepoint(librados, rados_pool_create_with_crush_rule_enter, cluster, name, crush_rule_num);
3849 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3850 string sname(name);
3851 int retval = radosp->pool_create(sname, 0, crush_rule_num);
3852 tracepoint(librados, rados_pool_create_with_crush_rule_exit, retval);
3853 return retval;
3854}
3855
3856extern "C" int rados_pool_create_with_all(rados_t cluster, const char *name,
3857 uint64_t auid, __u8 crush_rule_num)
3858{
3859 tracepoint(librados, rados_pool_create_with_all_enter, cluster, name, auid, crush_rule_num);
3860 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
3861 string sname(name);
3862 int retval = radosp->pool_create(sname, auid, crush_rule_num);
3863 tracepoint(librados, rados_pool_create_with_all_exit, retval);
3864 return retval;
3865}
3866
3867extern "C" int rados_pool_get_base_tier(rados_t cluster, int64_t pool_id, int64_t* base_tier)
3868{
3869 tracepoint(librados, rados_pool_get_base_tier_enter, cluster, pool_id);
3870 librados::RadosClient *client = (librados::RadosClient *)cluster;
3871 int retval = client->pool_get_base_tier(pool_id, base_tier);
3872 tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
3873 return retval;
3874}
3875
3876extern "C" int rados_pool_delete(rados_t cluster, const char *pool_name)
3877{
3878 tracepoint(librados, rados_pool_delete_enter, cluster, pool_name);
3879 librados::RadosClient *client = (librados::RadosClient *)cluster;
3880 int retval = client->pool_delete(pool_name);
3881 tracepoint(librados, rados_pool_delete_exit, retval);
3882 return retval;
3883}
3884
3885extern "C" int rados_ioctx_pool_set_auid(rados_ioctx_t io, uint64_t auid)
3886{
3887 tracepoint(librados, rados_ioctx_pool_set_auid_enter, io, auid);
3888 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3889 int retval = ctx->pool_change_auid(auid);
3890 tracepoint(librados, rados_ioctx_pool_set_auid_exit, retval);
3891 return retval;
3892}
3893
3894extern "C" int rados_ioctx_pool_get_auid(rados_ioctx_t io, uint64_t *auid)
3895{
3896 tracepoint(librados, rados_ioctx_pool_get_auid_enter, io);
3897 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3898 int retval = ctx->client->pool_get_auid(ctx->get_id(), (unsigned long long *)auid);
3899 tracepoint(librados, rados_ioctx_pool_get_auid_exit, retval, *auid);
3900 return retval;
3901}
3902
3903extern "C" int rados_ioctx_pool_requires_alignment(rados_ioctx_t io)
3904{
3905 tracepoint(librados, rados_ioctx_pool_requires_alignment_enter, io);
3906 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3907 int retval = ctx->client->pool_requires_alignment(ctx->get_id());
3908 tracepoint(librados, rados_ioctx_pool_requires_alignment_exit, retval);
3909 return retval;
3910}
3911
3912extern "C" int rados_ioctx_pool_requires_alignment2(rados_ioctx_t io,
3913 int *requires)
3914{
3915 tracepoint(librados, rados_ioctx_pool_requires_alignment_enter2, io);
3916 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3917 bool requires_alignment;
3918 int retval = ctx->client->pool_requires_alignment2(ctx->get_id(),
3919 &requires_alignment);
3920 tracepoint(librados, rados_ioctx_pool_requires_alignment_exit2, retval,
3921 requires_alignment);
3922 if (requires)
3923 *requires = requires_alignment;
3924 return retval;
3925}
3926
3927extern "C" uint64_t rados_ioctx_pool_required_alignment(rados_ioctx_t io)
3928{
3929 tracepoint(librados, rados_ioctx_pool_required_alignment_enter, io);
3930 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3931 uint64_t retval = ctx->client->pool_required_alignment(ctx->get_id());
3932 tracepoint(librados, rados_ioctx_pool_required_alignment_exit, retval);
3933 return retval;
3934}
3935
3936extern "C" int rados_ioctx_pool_required_alignment2(rados_ioctx_t io,
3937 uint64_t *alignment)
3938{
3939 tracepoint(librados, rados_ioctx_pool_required_alignment_enter2, io);
3940 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3941 int retval = ctx->client->pool_required_alignment2(ctx->get_id(),
3942 alignment);
3943 tracepoint(librados, rados_ioctx_pool_required_alignment_exit2, retval,
3944 *alignment);
3945 return retval;
3946}
3947
3948extern "C" void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key)
3949{
3950 tracepoint(librados, rados_ioctx_locator_set_key_enter, io, key);
3951 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3952 if (key)
3953 ctx->oloc.key = key;
3954 else
3955 ctx->oloc.key = "";
3956 tracepoint(librados, rados_ioctx_locator_set_key_exit);
3957}
3958
3959extern "C" void rados_ioctx_set_namespace(rados_ioctx_t io, const char *nspace)
3960{
3961 tracepoint(librados, rados_ioctx_set_namespace_enter, io, nspace);
3962 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3963 if (nspace)
3964 ctx->oloc.nspace = nspace;
3965 else
3966 ctx->oloc.nspace = "";
3967 tracepoint(librados, rados_ioctx_set_namespace_exit);
3968}
3969
3970extern "C" rados_t rados_ioctx_get_cluster(rados_ioctx_t io)
3971{
3972 tracepoint(librados, rados_ioctx_get_cluster_enter, io);
3973 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3974 rados_t retval = (rados_t)ctx->client;
3975 tracepoint(librados, rados_ioctx_get_cluster_exit, retval);
3976 return retval;
3977}
3978
3979extern "C" int64_t rados_ioctx_get_id(rados_ioctx_t io)
3980{
3981 tracepoint(librados, rados_ioctx_get_id_enter, io);
3982 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3983 int64_t retval = ctx->get_id();
3984 tracepoint(librados, rados_ioctx_get_id_exit, retval);
3985 return retval;
3986}
3987
3988extern "C" int rados_ioctx_get_pool_name(rados_ioctx_t io, char *s, unsigned maxlen)
3989{
3990 tracepoint(librados, rados_ioctx_get_pool_name_enter, io, maxlen);
3991 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3992 std::string pool_name;
3993
3994 int err = ctx->client->pool_get_name(ctx->get_id(), &pool_name);
3995 if (err) {
3996 tracepoint(librados, rados_ioctx_get_pool_name_exit, err, "");
3997 return err;
3998 }
3999 if (pool_name.length() >= maxlen) {
4000 tracepoint(librados, rados_ioctx_get_pool_name_exit, -ERANGE, "");
4001 return -ERANGE;
4002 }
4003 strcpy(s, pool_name.c_str());
4004 int retval = pool_name.length();
4005 tracepoint(librados, rados_ioctx_get_pool_name_exit, retval, s);
4006 return retval;
4007}
4008
4009// snaps
4010
4011extern "C" int rados_ioctx_snap_create(rados_ioctx_t io, const char *snapname)
4012{
4013 tracepoint(librados, rados_ioctx_snap_create_enter, io, snapname);
4014 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4015 int retval = ctx->snap_create(snapname);
4016 tracepoint(librados, rados_ioctx_snap_create_exit, retval);
4017 return retval;
4018}
4019
4020extern "C" int rados_ioctx_snap_remove(rados_ioctx_t io, const char *snapname)
4021{
4022 tracepoint(librados, rados_ioctx_snap_remove_enter, io, snapname);
4023 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4024 int retval = ctx->snap_remove(snapname);
4025 tracepoint(librados, rados_ioctx_snap_remove_exit, retval);
4026 return retval;
4027}
4028
4029extern "C" int rados_ioctx_snap_rollback(rados_ioctx_t io, const char *oid,
4030 const char *snapname)
4031{
4032 tracepoint(librados, rados_ioctx_snap_rollback_enter, io, oid, snapname);
4033 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4034 int retval = ctx->rollback(oid, snapname);
4035 tracepoint(librados, rados_ioctx_snap_rollback_exit, retval);
4036 return retval;
4037}
4038
4039// Deprecated name kept for backward compatibility
4040extern "C" int rados_rollback(rados_ioctx_t io, const char *oid,
4041 const char *snapname)
4042{
4043 return rados_ioctx_snap_rollback(io, oid, snapname);
4044}
4045
4046extern "C" int rados_ioctx_selfmanaged_snap_create(rados_ioctx_t io,
4047 uint64_t *snapid)
4048{
4049 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_enter, io);
4050 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4051 int retval = ctx->selfmanaged_snap_create(snapid);
4052 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_exit, retval, *snapid);
4053 return retval;
4054}
4055
4056extern "C" void
4057rados_aio_ioctx_selfmanaged_snap_create(rados_ioctx_t io,
4058 rados_snap_t *snapid,
4059 rados_completion_t completion)
4060{
4061 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_enter, io);
4062 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4063 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
4064 ctx->aio_selfmanaged_snap_create(snapid, c);
4065 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_exit, 0, 0);
4066}
4067
4068extern "C" int rados_ioctx_selfmanaged_snap_remove(rados_ioctx_t io,
4069 uint64_t snapid)
4070{
4071 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_enter, io, snapid);
4072 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4073 int retval = ctx->selfmanaged_snap_remove(snapid);
4074 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_exit, retval);
4075 return retval;
4076}
4077
4078extern "C" void
4079rados_aio_ioctx_selfmanaged_snap_remove(rados_ioctx_t io,
4080 rados_snap_t snapid,
4081 rados_completion_t completion)
4082{
4083 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_enter, io, snapid);
4084 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4085 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
4086 ctx->aio_selfmanaged_snap_remove(snapid, c);
4087 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_exit, 0);
4088}
4089
4090extern "C" int rados_ioctx_selfmanaged_snap_rollback(rados_ioctx_t io,
4091 const char *oid,
4092 uint64_t snapid)
4093{
4094 tracepoint(librados, rados_ioctx_selfmanaged_snap_rollback_enter, io, oid, snapid);
4095 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4096 int retval = ctx->selfmanaged_snap_rollback_object(oid, ctx->snapc, snapid);
4097 tracepoint(librados, rados_ioctx_selfmanaged_snap_rollback_exit, retval);
4098 return retval;
4099}
4100
4101extern "C" int rados_ioctx_snap_list(rados_ioctx_t io, rados_snap_t *snaps,
4102 int maxlen)
4103{
4104 tracepoint(librados, rados_ioctx_snap_list_enter, io, maxlen);
4105 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4106 vector<uint64_t> snapvec;
4107 int r = ctx->snap_list(&snapvec);
4108 if (r < 0) {
4109 tracepoint(librados, rados_ioctx_snap_list_exit, r, snaps, 0);
4110 return r;
4111 }
4112 if ((int)snapvec.size() <= maxlen) {
4113 for (unsigned i=0; i<snapvec.size(); i++) {
4114 snaps[i] = snapvec[i];
4115 }
4116 int retval = snapvec.size();
4117 tracepoint(librados, rados_ioctx_snap_list_exit, retval, snaps, retval);
4118 return retval;
4119 }
4120 int retval = -ERANGE;
4121 tracepoint(librados, rados_ioctx_snap_list_exit, retval, snaps, 0);
4122 return retval;
4123}
4124
4125extern "C" int rados_ioctx_snap_lookup(rados_ioctx_t io, const char *name,
4126 rados_snap_t *id)
4127{
4128 tracepoint(librados, rados_ioctx_snap_lookup_enter, io, name);
4129 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4130 int retval = ctx->snap_lookup(name, (uint64_t *)id);
4131 tracepoint(librados, rados_ioctx_snap_lookup_exit, retval, *id);
4132 return retval;
4133}
4134
4135extern "C" int rados_ioctx_snap_get_name(rados_ioctx_t io, rados_snap_t id,
4136 char *name, int maxlen)
4137{
4138 tracepoint(librados, rados_ioctx_snap_get_name_enter, io, id, maxlen);
4139 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4140 std::string sname;
4141 int r = ctx->snap_get_name(id, &sname);
4142 if (r < 0) {
4143 tracepoint(librados, rados_ioctx_snap_get_name_exit, r, "");
4144 return r;
4145 }
4146 if ((int)sname.length() >= maxlen) {
4147 int retval = -ERANGE;
4148 tracepoint(librados, rados_ioctx_snap_get_name_exit, retval, "");
4149 return retval;
4150 }
4151 strncpy(name, sname.c_str(), maxlen);
4152 tracepoint(librados, rados_ioctx_snap_get_name_exit, 0, name);
4153 return 0;
4154}
4155
4156extern "C" int rados_ioctx_snap_get_stamp(rados_ioctx_t io, rados_snap_t id, time_t *t)
4157{
4158 tracepoint(librados, rados_ioctx_snap_get_stamp_enter, io, id);
4159 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4160 int retval = ctx->snap_get_stamp(id, t);
4161 tracepoint(librados, rados_ioctx_snap_get_stamp_exit, retval, *t);
4162 return retval;
4163}
4164
4165extern "C" int rados_cmpext(rados_ioctx_t io, const char *o,
4166 const char *cmp_buf, size_t cmp_len, uint64_t off)
4167{
4168 tracepoint(librados, rados_cmpext_enter, io, o, cmp_buf, cmp_len, off);
4169 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4170 int ret;
4171 object_t oid(o);
4172
4173 bufferlist cmp_bl;
4174 cmp_bl.append(cmp_buf, cmp_len);
4175
4176 ret = ctx->cmpext(oid, off, cmp_bl);
4177 tracepoint(librados, rados_cmpext_exit, ret);
4178
4179 return ret;
4180}
4181
4182extern "C" int rados_getxattr(rados_ioctx_t io, const char *o, const char *name,
4183 char *buf, size_t len)
4184{
4185 tracepoint(librados, rados_getxattr_enter, io, o, name, len);
4186 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4187 int ret;
4188 object_t oid(o);
4189 bufferlist bl;
4190 bl.push_back(buffer::create_static(len, buf));
4191 ret = ctx->getxattr(oid, name, bl);
4192 if (ret >= 0) {
4193 if (bl.length() > len) {
4194 tracepoint(librados, rados_getxattr_exit, -ERANGE, buf, 0);
4195 return -ERANGE;
4196 }
4197 if (!bl.is_provided_buffer(buf))
4198 bl.copy(0, bl.length(), buf);
4199 ret = bl.length();
4200 }
4201
4202 tracepoint(librados, rados_getxattr_exit, ret, buf, ret);
4203 return ret;
4204}
4205
4206extern "C" int rados_getxattrs(rados_ioctx_t io, const char *oid,
4207 rados_xattrs_iter_t *iter)
4208{
4209 tracepoint(librados, rados_getxattrs_enter, io, oid);
4210 librados::RadosXattrsIter *it = new librados::RadosXattrsIter();
4211 if (!it) {
4212 tracepoint(librados, rados_getxattrs_exit, -ENOMEM, NULL);
4213 return -ENOMEM;
4214 }
4215 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4216 object_t obj(oid);
4217 int ret = ctx->getxattrs(obj, it->attrset);
4218 if (ret) {
4219 delete it;
4220 tracepoint(librados, rados_getxattrs_exit, ret, NULL);
4221 return ret;
4222 }
4223 it->i = it->attrset.begin();
4224
4225 librados::RadosXattrsIter **iret = (librados::RadosXattrsIter**)iter;
4226 *iret = it;
4227 *iter = it;
4228 tracepoint(librados, rados_getxattrs_exit, 0, *iter);
4229 return 0;
4230}
4231
4232extern "C" int rados_getxattrs_next(rados_xattrs_iter_t iter,
4233 const char **name, const char **val, size_t *len)
4234{
4235 tracepoint(librados, rados_getxattrs_next_enter, iter);
4236 librados::RadosXattrsIter *it = static_cast<librados::RadosXattrsIter*>(iter);
94b18763
FG
4237 if (it->val) {
4238 free(it->val);
4239 it->val = NULL;
4240 }
7c673cae
FG
4241 if (it->i == it->attrset.end()) {
4242 *name = NULL;
4243 *val = NULL;
4244 *len = 0;
4245 tracepoint(librados, rados_getxattrs_next_exit, 0, NULL, NULL, 0);
4246 return 0;
4247 }
7c673cae
FG
4248 const std::string &s(it->i->first);
4249 *name = s.c_str();
4250 bufferlist &bl(it->i->second);
4251 size_t bl_len = bl.length();
4252 if (!bl_len) {
4253 // malloc(0) is not guaranteed to return a valid pointer
4254 *val = (char *)NULL;
4255 } else {
4256 it->val = (char*)malloc(bl_len);
4257 if (!it->val) {
4258 tracepoint(librados, rados_getxattrs_next_exit, -ENOMEM, *name, NULL, 0);
4259 return -ENOMEM;
4260 }
4261 memcpy(it->val, bl.c_str(), bl_len);
4262 *val = it->val;
4263 }
4264 *len = bl_len;
4265 ++it->i;
4266 tracepoint(librados, rados_getxattrs_next_exit, 0, *name, *val, *len);
4267 return 0;
4268}
4269
4270extern "C" void rados_getxattrs_end(rados_xattrs_iter_t iter)
4271{
4272 tracepoint(librados, rados_getxattrs_end_enter, iter);
4273 librados::RadosXattrsIter *it = static_cast<librados::RadosXattrsIter*>(iter);
4274 delete it;
4275 tracepoint(librados, rados_getxattrs_end_exit);
4276}
4277
4278extern "C" int rados_setxattr(rados_ioctx_t io, const char *o, const char *name, const char *buf, size_t len)
4279{
4280 tracepoint(librados, rados_setxattr_enter, io, o, name, buf, len);
4281 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4282 object_t oid(o);
4283 bufferlist bl;
4284 bl.append(buf, len);
4285 int retval = ctx->setxattr(oid, name, bl);
4286 tracepoint(librados, rados_setxattr_exit, retval);
4287 return retval;
4288}
4289
4290extern "C" int rados_rmxattr(rados_ioctx_t io, const char *o, const char *name)
4291{
4292 tracepoint(librados, rados_rmxattr_enter, io, o, name);
4293 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4294 object_t oid(o);
4295 int retval = ctx->rmxattr(oid, name);
4296 tracepoint(librados, rados_rmxattr_exit, retval);
4297 return retval;
4298}
4299
4300extern "C" int rados_stat(rados_ioctx_t io, const char *o, uint64_t *psize, time_t *pmtime)
4301{
4302 tracepoint(librados, rados_stat_enter, io, o);
4303 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4304 object_t oid(o);
4305 int retval = ctx->stat(oid, psize, pmtime);
4306 tracepoint(librados, rados_stat_exit, retval, psize, pmtime);
4307 return retval;
4308}
4309
4310extern "C" int rados_tmap_update(rados_ioctx_t io, const char *o, const char *cmdbuf, size_t cmdbuflen)
4311{
4312 tracepoint(librados, rados_tmap_update_enter, io, o, cmdbuf, cmdbuflen);
4313 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4314 object_t oid(o);
4315 bufferlist cmdbl;
4316 cmdbl.append(cmdbuf, cmdbuflen);
4317 int retval = ctx->tmap_update(oid, cmdbl);
4318 tracepoint(librados, rados_tmap_update_exit, retval);
4319 return retval;
4320}
4321
4322extern "C" int rados_tmap_put(rados_ioctx_t io, const char *o, const char *buf, size_t buflen)
4323{
4324 tracepoint(librados, rados_tmap_put_enter, io, o, buf, buflen);
4325 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4326 object_t oid(o);
4327 bufferlist bl;
4328 bl.append(buf, buflen);
4329 int retval = ctx->tmap_put(oid, bl);
4330 tracepoint(librados, rados_tmap_put_exit, retval);
4331 return retval;
4332}
4333
4334extern "C" int rados_tmap_get(rados_ioctx_t io, const char *o, char *buf, size_t buflen)
4335{
4336 tracepoint(librados, rados_tmap_get_enter, io, o, buflen);
4337 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4338 object_t oid(o);
4339 bufferlist bl;
4340 int r = ctx->tmap_get(oid, bl);
4341 if (r < 0) {
4342 tracepoint(librados, rados_tmap_get_exit, r, buf, 0);
4343 return r;
4344 }
4345 if (bl.length() > buflen) {
4346 tracepoint(librados, rados_tmap_get_exit, -ERANGE, buf, 0);
4347 return -ERANGE;
4348 }
4349 bl.copy(0, bl.length(), buf);
4350 int retval = bl.length();
4351 tracepoint(librados, rados_tmap_get_exit, retval, buf, retval);
4352 return retval;
4353}
4354
4355extern "C" int rados_tmap_to_omap(rados_ioctx_t io, const char *o, bool nullok)
4356{
4357 tracepoint(librados, rados_tmap_to_omap_enter, io, o, nullok);
4358 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4359 object_t oid(o);
4360 int retval = ctx->tmap_to_omap(oid, nullok);
4361 tracepoint(librados, rados_tmap_to_omap_exit, retval);
4362 return retval;
4363}
4364
4365extern "C" int rados_exec(rados_ioctx_t io, const char *o, const char *cls, const char *method,
4366 const char *inbuf, size_t in_len, char *buf, size_t out_len)
4367{
4368 tracepoint(librados, rados_exec_enter, io, o, cls, method, inbuf, in_len, out_len);
4369 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4370 object_t oid(o);
4371 bufferlist inbl, outbl;
4372 int ret;
4373 inbl.append(inbuf, in_len);
4374 ret = ctx->exec(oid, cls, method, inbl, outbl);
4375 if (ret >= 0) {
4376 if (outbl.length()) {
4377 if (outbl.length() > out_len) {
4378 tracepoint(librados, rados_exec_exit, -ERANGE, buf, 0);
4379 return -ERANGE;
4380 }
4381 outbl.copy(0, outbl.length(), buf);
4382 ret = outbl.length(); // hrm :/
4383 }
4384 }
4385 tracepoint(librados, rados_exec_exit, ret, buf, ret);
4386 return ret;
4387}
4388
4389extern "C" rados_object_list_cursor rados_object_list_begin(rados_ioctx_t io)
4390{
4391 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4392
4393 hobject_t *result = new hobject_t(ctx->objecter->enumerate_objects_begin());
4394 return (rados_object_list_cursor)result;
4395}
4396
4397extern "C" rados_object_list_cursor rados_object_list_end(rados_ioctx_t io)
4398{
4399 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4400
4401 hobject_t *result = new hobject_t(ctx->objecter->enumerate_objects_end());
4402 return (rados_object_list_cursor)result;
4403}
4404
4405extern "C" int rados_object_list_is_end(
4406 rados_ioctx_t io, rados_object_list_cursor cur)
4407{
4408 hobject_t *hobj = (hobject_t*)cur;
4409 return hobj->is_max();
4410}
4411
4412extern "C" void rados_object_list_cursor_free(
4413 rados_ioctx_t io, rados_object_list_cursor cur)
4414{
4415 hobject_t *hobj = (hobject_t*)cur;
4416 delete hobj;
4417}
4418
4419extern "C" int rados_object_list_cursor_cmp(
4420 rados_ioctx_t io,
4421 rados_object_list_cursor lhs_cur,
4422 rados_object_list_cursor rhs_cur)
4423{
4424 hobject_t *lhs = (hobject_t*)lhs_cur;
4425 hobject_t *rhs = (hobject_t*)rhs_cur;
4426 return cmp(*lhs, *rhs);
4427}
4428
4429extern "C" int rados_object_list(rados_ioctx_t io,
4430 const rados_object_list_cursor start,
4431 const rados_object_list_cursor finish,
4432 const size_t result_item_count,
4433 const char *filter_buf,
4434 const size_t filter_buf_len,
4435 rados_object_list_item *result_items,
4436 rados_object_list_cursor *next)
4437{
4438 assert(next);
4439
4440 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4441
4442 // Zero out items so that they will be safe to free later
4443 memset(result_items, 0, sizeof(rados_object_list_item) * result_item_count);
4444
4445 std::list<librados::ListObjectImpl> result;
4446 hobject_t next_hash;
4447
4448 bufferlist filter_bl;
4449 if (filter_buf != nullptr) {
4450 filter_bl.append(filter_buf, filter_buf_len);
4451 }
4452
4453 C_SaferCond cond;
4454 ctx->objecter->enumerate_objects(
4455 ctx->poolid,
4456 ctx->oloc.nspace,
4457 *((hobject_t*)start),
4458 *((hobject_t*)finish),
4459 result_item_count,
4460 filter_bl,
4461 &result,
4462 &next_hash,
4463 &cond);
4464
4465 hobject_t *next_hobj = (hobject_t*)(*next);
4466 assert(next_hobj);
4467
4468 int r = cond.wait();
4469 if (r < 0) {
4470 *next_hobj = hobject_t::get_max();
4471 return r;
4472 }
4473
4474 assert(result.size() <= result_item_count); // Don't overflow!
4475
4476 int k = 0;
4477 for (std::list<librados::ListObjectImpl>::iterator i = result.begin();
4478 i != result.end(); ++i) {
4479 rados_object_list_item &item = result_items[k++];
4480 do_out_buffer(i->oid, &item.oid, &item.oid_length);
4481 do_out_buffer(i->nspace, &item.nspace, &item.nspace_length);
4482 do_out_buffer(i->locator, &item.locator, &item.locator_length);
4483 }
4484
4485 *next_hobj = next_hash;
4486
4487 return result.size();
4488}
4489
4490extern "C" void rados_object_list_free(
4491 const size_t result_size,
4492 rados_object_list_item *results)
4493{
4494 assert(results);
4495
4496 for (unsigned int i = 0; i < result_size; ++i) {
4497 rados_buffer_free(results[i].oid);
4498 rados_buffer_free(results[i].locator);
4499 rados_buffer_free(results[i].nspace);
4500 }
4501}
4502
4503/* list objects */
4504
4505extern "C" int rados_nobjects_list_open(rados_ioctx_t io, rados_list_ctx_t *listh)
4506{
4507 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4508
4509 tracepoint(librados, rados_nobjects_list_open_enter, io);
4510
4511 Objecter::NListContext *h = new Objecter::NListContext;
4512 h->pool_id = ctx->poolid;
4513 h->pool_snap_seq = ctx->snap_seq;
4514 h->nspace = ctx->oloc.nspace; // After dropping compatibility need nspace
4515 *listh = (void *)new librados::ObjListCtx(ctx, h);
4516 tracepoint(librados, rados_nobjects_list_open_exit, 0, *listh);
4517 return 0;
4518}
4519
4520extern "C" void rados_nobjects_list_close(rados_list_ctx_t h)
4521{
4522 tracepoint(librados, rados_nobjects_list_close_enter, h);
4523 librados::ObjListCtx *lh = (librados::ObjListCtx *)h;
4524 delete lh;
4525 tracepoint(librados, rados_nobjects_list_close_exit);
4526}
4527
4528extern "C" uint32_t rados_nobjects_list_seek(rados_list_ctx_t listctx,
4529 uint32_t pos)
4530{
4531 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
4532 tracepoint(librados, rados_nobjects_list_seek_enter, listctx, pos);
4533 uint32_t r = lh->ctx->nlist_seek(lh->nlc, pos);
4534 tracepoint(librados, rados_nobjects_list_seek_exit, r);
4535 return r;
4536}
4537
4538extern "C" uint32_t rados_nobjects_list_seek_cursor(rados_list_ctx_t listctx,
4539 rados_object_list_cursor cursor)
4540{
4541 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
4542
4543 tracepoint(librados, rados_nobjects_list_seek_cursor_enter, listctx);
4544 uint32_t r = lh->ctx->nlist_seek(lh->nlc, cursor);
4545 tracepoint(librados, rados_nobjects_list_seek_cursor_exit, r);
4546 return r;
4547}
4548
4549extern "C" int rados_nobjects_list_get_cursor(rados_list_ctx_t listctx,
4550 rados_object_list_cursor *cursor)
4551{
4552 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
4553
4554 tracepoint(librados, rados_nobjects_list_get_cursor_enter, listctx);
4555 *cursor = lh->ctx->nlist_get_cursor(lh->nlc);
4556 tracepoint(librados, rados_nobjects_list_get_cursor_exit, 0);
4557 return 0;
4558}
4559
4560extern "C" uint32_t rados_nobjects_list_get_pg_hash_position(
4561 rados_list_ctx_t listctx)
4562{
4563 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
4564 tracepoint(librados, rados_nobjects_list_get_pg_hash_position_enter, listctx);
4565 uint32_t retval = lh->nlc->get_pg_hash_position();
4566 tracepoint(librados, rados_nobjects_list_get_pg_hash_position_exit, retval);
4567 return retval;
4568}
4569
4570extern "C" int rados_nobjects_list_next(rados_list_ctx_t listctx, const char **entry, const char **key, const char **nspace)
4571{
4572 tracepoint(librados, rados_nobjects_list_next_enter, listctx);
4573 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
4574 Objecter::NListContext *h = lh->nlc;
4575
4576 // if the list is non-empty, this method has been called before
4577 if (!h->list.empty())
4578 // so let's kill the previously-returned object
4579 h->list.pop_front();
4580
4581 if (h->list.empty()) {
4582 int ret = lh->ctx->nlist(lh->nlc, RADOS_LIST_MAX_ENTRIES);
4583 if (ret < 0) {
4584 tracepoint(librados, rados_nobjects_list_next_exit, ret, NULL, NULL, NULL);
4585 return ret;
4586 }
4587 if (h->list.empty()) {
4588 tracepoint(librados, rados_nobjects_list_next_exit, -ENOENT, NULL, NULL, NULL);
4589 return -ENOENT;
4590 }
4591 }
4592
4593 *entry = h->list.front().oid.c_str();
4594
4595 if (key) {
4596 if (h->list.front().locator.size())
4597 *key = h->list.front().locator.c_str();
4598 else
4599 *key = NULL;
4600 }
4601 if (nspace)
4602 *nspace = h->list.front().nspace.c_str();
4603 tracepoint(librados, rados_nobjects_list_next_exit, 0, *entry, key, nspace);
4604 return 0;
4605}
4606
4607
4608/*
4609 * removed legacy v2 list objects stubs
4610 *
4611 * thse return -ENOTSUP where possible.
4612 */
4613extern "C" int rados_objects_list_open(
4614 rados_ioctx_t io,
4615 rados_list_ctx_t *ctx)
4616{
4617 return -ENOTSUP;
4618}
4619
4620extern "C" uint32_t rados_objects_list_get_pg_hash_position(
4621 rados_list_ctx_t ctx)
4622{
4623 return 0;
4624}
4625
4626extern "C" uint32_t rados_objects_list_seek(
4627 rados_list_ctx_t ctx,
4628 uint32_t pos)
4629{
4630 return 0;
4631}
4632
4633extern "C" int rados_objects_list_next(
4634 rados_list_ctx_t ctx,
4635 const char **entry,
4636 const char **key)
4637{
4638 return -ENOTSUP;
4639}
4640
4641extern "C" void rados_objects_list_close(
4642 rados_list_ctx_t ctx)
4643{
4644}
4645
4646
4647// -------------------------
4648// aio
4649
4650extern "C" int rados_aio_create_completion(void *cb_arg,
4651 rados_callback_t cb_complete,
4652 rados_callback_t cb_safe,
4653 rados_completion_t *pc)
4654{
4655 tracepoint(librados, rados_aio_create_completion_enter, cb_arg, cb_complete, cb_safe);
4656 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
4657 if (cb_complete)
4658 c->set_complete_callback(cb_arg, cb_complete);
4659 if (cb_safe)
4660 c->set_safe_callback(cb_arg, cb_safe);
4661 *pc = c;
4662 tracepoint(librados, rados_aio_create_completion_exit, 0, *pc);
4663 return 0;
4664}
4665
4666extern "C" int rados_aio_wait_for_complete(rados_completion_t c)
4667{
4668 tracepoint(librados, rados_aio_wait_for_complete_enter, c);
4669 int retval = ((librados::AioCompletionImpl*)c)->wait_for_complete();
4670 tracepoint(librados, rados_aio_wait_for_complete_exit, retval);
4671 return retval;
4672}
4673
4674extern "C" int rados_aio_wait_for_safe(rados_completion_t c)
4675{
4676 tracepoint(librados, rados_aio_wait_for_safe_enter, c);
4677 int retval = ((librados::AioCompletionImpl*)c)->wait_for_safe();
4678 tracepoint(librados, rados_aio_wait_for_safe_exit, retval);
4679 return retval;
4680}
4681
4682extern "C" int rados_aio_is_complete(rados_completion_t c)
4683{
4684 tracepoint(librados, rados_aio_is_complete_enter, c);
4685 int retval = ((librados::AioCompletionImpl*)c)->is_complete();
4686 tracepoint(librados, rados_aio_is_complete_exit, retval);
4687 return retval;
4688}
4689
4690extern "C" int rados_aio_is_safe(rados_completion_t c)
4691{
4692 tracepoint(librados, rados_aio_is_safe_enter, c);
4693 int retval = ((librados::AioCompletionImpl*)c)->is_safe();
4694 tracepoint(librados, rados_aio_is_safe_exit, retval);
4695 return retval;
4696}
4697
4698extern "C" int rados_aio_wait_for_complete_and_cb(rados_completion_t c)
4699{
4700 tracepoint(librados, rados_aio_wait_for_complete_and_cb_enter, c);
4701 int retval = ((librados::AioCompletionImpl*)c)->wait_for_complete_and_cb();
4702 tracepoint(librados, rados_aio_wait_for_complete_and_cb_exit, retval);
4703 return retval;
4704}
4705
4706extern "C" int rados_aio_wait_for_safe_and_cb(rados_completion_t c)
4707{
4708 tracepoint(librados, rados_aio_wait_for_safe_and_cb_enter, c);
4709 int retval = ((librados::AioCompletionImpl*)c)->wait_for_safe_and_cb();
4710 tracepoint(librados, rados_aio_wait_for_safe_and_cb_exit, retval);
4711 return retval;
4712}
4713
4714extern "C" int rados_aio_is_complete_and_cb(rados_completion_t c)
4715{
4716 tracepoint(librados, rados_aio_is_complete_and_cb_enter, c);
4717 int retval = ((librados::AioCompletionImpl*)c)->is_complete_and_cb();
4718 tracepoint(librados, rados_aio_is_complete_and_cb_exit, retval);
4719 return retval;
4720}
4721
4722extern "C" int rados_aio_is_safe_and_cb(rados_completion_t c)
4723{
4724 tracepoint(librados, rados_aio_is_safe_and_cb_enter, c);
4725 int retval = ((librados::AioCompletionImpl*)c)->is_safe_and_cb();
4726 tracepoint(librados, rados_aio_is_safe_and_cb_exit, retval);
4727 return retval;
4728}
4729
4730extern "C" int rados_aio_get_return_value(rados_completion_t c)
4731{
4732 tracepoint(librados, rados_aio_get_return_value_enter, c);
4733 int retval = ((librados::AioCompletionImpl*)c)->get_return_value();
4734 tracepoint(librados, rados_aio_get_return_value_exit, retval);
4735 return retval;
4736}
4737
4738extern "C" uint64_t rados_aio_get_version(rados_completion_t c)
4739{
4740 tracepoint(librados, rados_aio_get_version_enter, c);
4741 uint64_t retval = ((librados::AioCompletionImpl*)c)->get_version();
4742 tracepoint(librados, rados_aio_get_version_exit, retval);
4743 return retval;
4744}
4745
4746extern "C" void rados_aio_release(rados_completion_t c)
4747{
4748 tracepoint(librados, rados_aio_release_enter, c);
4749 ((librados::AioCompletionImpl*)c)->put();
4750 tracepoint(librados, rados_aio_release_exit);
4751}
4752
4753extern "C" int rados_aio_read(rados_ioctx_t io, const char *o,
4754 rados_completion_t completion,
4755 char *buf, size_t len, uint64_t off)
4756{
4757 tracepoint(librados, rados_aio_read_enter, io, o, completion, len, off);
4758 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4759 object_t oid(o);
4760 int retval = ctx->aio_read(oid, (librados::AioCompletionImpl*)completion,
4761 buf, len, off, ctx->snap_seq);
4762 tracepoint(librados, rados_aio_read_exit, retval);
4763 return retval;
4764}
4765
4766#ifdef WITH_BLKIN
4767extern "C" int rados_aio_read_traced(rados_ioctx_t io, const char *o,
4768 rados_completion_t completion,
4769 char *buf, size_t len, uint64_t off,
4770 struct blkin_trace_info *info)
4771{
4772 tracepoint(librados, rados_aio_read_enter, io, o, completion, len, off);
4773 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4774 object_t oid(o);
4775 int retval = ctx->aio_read(oid, (librados::AioCompletionImpl*)completion,
4776 buf, len, off, ctx->snap_seq, info);
4777 tracepoint(librados, rados_aio_read_exit, retval);
4778 return retval;
4779}
4780#endif
4781
4782extern "C" int rados_aio_write(rados_ioctx_t io, const char *o,
4783 rados_completion_t completion,
4784 const char *buf, size_t len, uint64_t off)
4785{
4786 tracepoint(librados, rados_aio_write_enter, io, o, completion, buf, len, off);
4787 if (len > UINT_MAX/2)
4788 return -E2BIG;
4789 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4790 object_t oid(o);
4791 bufferlist bl;
4792 bl.append(buf, len);
4793 int retval = ctx->aio_write(oid, (librados::AioCompletionImpl*)completion,
4794 bl, len, off);
4795 tracepoint(librados, rados_aio_write_exit, retval);
4796 return retval;
4797}
4798
4799#ifdef WITH_BLKIN
4800extern "C" int rados_aio_write_traced(rados_ioctx_t io, const char *o,
4801 rados_completion_t completion,
4802 const char *buf, size_t len, uint64_t off,
4803 struct blkin_trace_info *info)
4804{
4805 tracepoint(librados, rados_aio_write_enter, io, o, completion, buf, len, off);
4806 if (len > UINT_MAX/2)
4807 return -E2BIG;
4808 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4809 object_t oid(o);
4810 bufferlist bl;
4811 bl.append(buf, len);
4812 int retval = ctx->aio_write(oid, (librados::AioCompletionImpl*)completion,
4813 bl, len, off, info);
4814 tracepoint(librados, rados_aio_write_exit, retval);
4815 return retval;
4816}
4817#endif
4818
4819extern "C" int rados_aio_append(rados_ioctx_t io, const char *o,
4820 rados_completion_t completion,
4821 const char *buf, size_t len)
4822{
4823 tracepoint(librados, rados_aio_append_enter, io, o, completion, buf, len);
4824 if (len > UINT_MAX/2)
4825 return -E2BIG;
4826 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4827 object_t oid(o);
4828 bufferlist bl;
4829 bl.append(buf, len);
4830 int retval = ctx->aio_append(oid, (librados::AioCompletionImpl*)completion,
4831 bl, len);
4832 tracepoint(librados, rados_aio_append_exit, retval);
4833 return retval;
4834}
4835
4836extern "C" int rados_aio_write_full(rados_ioctx_t io, const char *o,
4837 rados_completion_t completion,
4838 const char *buf, size_t len)
4839{
4840 tracepoint(librados, rados_aio_write_full_enter, io, o, completion, buf, len);
4841 if (len > UINT_MAX/2)
4842 return -E2BIG;
4843 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4844 object_t oid(o);
4845 bufferlist bl;
4846 bl.append(buf, len);
4847 int retval = ctx->aio_write_full(oid, (librados::AioCompletionImpl*)completion, bl);
4848 tracepoint(librados, rados_aio_write_full_exit, retval);
4849 return retval;
4850}
4851
4852extern "C" int rados_aio_writesame(rados_ioctx_t io, const char *o,
4853 rados_completion_t completion,
4854 const char *buf, size_t data_len,
4855 size_t write_len, uint64_t off)
4856{
4857 tracepoint(librados, rados_aio_writesame_enter, io, o, completion, buf,
4858 data_len, write_len, off);
4859 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4860 object_t oid(o);
4861 bufferlist bl;
4862 bl.append(buf, data_len);
4863 int retval = ctx->aio_writesame(o, (librados::AioCompletionImpl*)completion,
4864 bl, write_len, off);
4865 tracepoint(librados, rados_aio_writesame_exit, retval);
4866 return retval;
4867}
4868
4869extern "C" int rados_aio_remove(rados_ioctx_t io, const char *o,
4870 rados_completion_t completion)
4871{
4872 tracepoint(librados, rados_aio_remove_enter, io, o, completion);
4873 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4874 object_t oid(o);
4875 int retval = ctx->aio_remove(oid, (librados::AioCompletionImpl*)completion);
4876 tracepoint(librados, rados_aio_remove_exit, retval);
4877 return retval;
4878}
4879
4880extern "C" int rados_aio_flush_async(rados_ioctx_t io,
4881 rados_completion_t completion)
4882{
4883 tracepoint(librados, rados_aio_flush_async_enter, io, completion);
4884 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4885 ctx->flush_aio_writes_async((librados::AioCompletionImpl*)completion);
4886 tracepoint(librados, rados_aio_flush_async_exit, 0);
4887 return 0;
4888}
4889
4890extern "C" int rados_aio_flush(rados_ioctx_t io)
4891{
4892 tracepoint(librados, rados_aio_flush_enter, io);
4893 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4894 ctx->flush_aio_writes();
4895 tracepoint(librados, rados_aio_flush_exit, 0);
4896 return 0;
4897}
4898
4899struct AioGetxattrData {
4900 AioGetxattrData(char* buf, rados_completion_t c, size_t l) :
4901 user_buf(buf), len(l), user_completion((librados::AioCompletionImpl*)c) {}
4902 bufferlist bl;
4903 char* user_buf;
4904 size_t len;
4905 struct librados::C_AioCompleteAndSafe user_completion;
4906};
4907
4908static void rados_aio_getxattr_complete(rados_completion_t c, void *arg) {
4909 AioGetxattrData *cdata = reinterpret_cast<AioGetxattrData*>(arg);
4910 int rc = rados_aio_get_return_value(c);
4911 if (rc >= 0) {
4912 if (cdata->bl.length() > cdata->len) {
4913 rc = -ERANGE;
4914 } else {
4915 if (!cdata->bl.is_provided_buffer(cdata->user_buf))
4916 cdata->bl.copy(0, cdata->bl.length(), cdata->user_buf);
4917 rc = cdata->bl.length();
4918 }
4919 }
4920 cdata->user_completion.finish(rc);
4921 delete cdata;
4922}
4923
4924extern "C" int rados_aio_getxattr(rados_ioctx_t io, const char *o,
4925 rados_completion_t completion,
4926 const char *name, char *buf, size_t len)
4927{
4928 tracepoint(librados, rados_aio_getxattr_enter, io, o, completion, name, len);
4929 // create data object to be passed to async callback
4930 AioGetxattrData *cdata = new AioGetxattrData(buf, completion, len);
4931 if (!cdata) {
4932 tracepoint(librados, rados_aio_getxattr_exit, -ENOMEM, NULL, 0);
4933 return -ENOMEM;
4934 }
4935 cdata->bl.push_back(buffer::create_static(len, buf));
4936 // create completion callback
4937 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
4938 c->set_complete_callback(cdata, rados_aio_getxattr_complete);
4939 // call async getxattr of IoCtx
4940 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4941 object_t oid(o);
4942 int ret = ctx->aio_getxattr(oid, c, name, cdata->bl);
4943 tracepoint(librados, rados_aio_getxattr_exit, ret, buf, ret);
4944 return ret;
4945}
4946
4947namespace {
4948struct AioGetxattrsData {
4949 AioGetxattrsData(rados_completion_t c, rados_xattrs_iter_t *_iter) :
4950 iter(_iter), user_completion((librados::AioCompletionImpl*)c) {
4951 it = new librados::RadosXattrsIter();
4952 }
4953 ~AioGetxattrsData() {
4954 if (it) delete it;
4955 }
4956 librados::RadosXattrsIter *it;
4957 rados_xattrs_iter_t *iter;
4958 struct librados::C_AioCompleteAndSafe user_completion;
4959};
4960}
4961
4962static void rados_aio_getxattrs_complete(rados_completion_t c, void *arg) {
4963 AioGetxattrsData *cdata = reinterpret_cast<AioGetxattrsData*>(arg);
4964 int rc = rados_aio_get_return_value(c);
4965 if (rc) {
4966 cdata->user_completion.finish(rc);
4967 } else {
4968 cdata->it->i = cdata->it->attrset.begin();
4969 *cdata->iter = cdata->it;
4970 cdata->it = 0;
4971 cdata->user_completion.finish(0);
4972 }
4973 delete cdata;
4974}
4975
4976extern "C" int rados_aio_getxattrs(rados_ioctx_t io, const char *oid,
4977 rados_completion_t completion,
4978 rados_xattrs_iter_t *iter)
4979{
4980 tracepoint(librados, rados_aio_getxattrs_enter, io, oid, completion);
4981 // create data object to be passed to async callback
4982 AioGetxattrsData *cdata = new AioGetxattrsData(completion, iter);
4983 if (!cdata) {
4984 tracepoint(librados, rados_getxattrs_exit, -ENOMEM, NULL);
4985 return -ENOMEM;
4986 }
4987 // create completion callback
4988 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
4989 c->set_complete_callback(cdata, rados_aio_getxattrs_complete);
4990 // call async getxattrs of IoCtx
4991 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4992 object_t obj(oid);
4993 int ret = ctx->aio_getxattrs(obj, c, cdata->it->attrset);
4994 tracepoint(librados, rados_aio_getxattrs_exit, ret, cdata->it);
4995 return ret;
4996}
4997
4998extern "C" int rados_aio_setxattr(rados_ioctx_t io, const char *o,
4999 rados_completion_t completion,
5000 const char *name, const char *buf, size_t len)
5001{
5002 tracepoint(librados, rados_aio_setxattr_enter, io, o, completion, name, buf, len);
5003 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5004 object_t oid(o);
5005 bufferlist bl;
5006 bl.append(buf, len);
5007 int retval = ctx->aio_setxattr(oid, (librados::AioCompletionImpl*)completion, name, bl);
5008 tracepoint(librados, rados_aio_setxattr_exit, retval);
5009 return retval;
5010}
5011
5012extern "C" int rados_aio_rmxattr(rados_ioctx_t io, const char *o,
5013 rados_completion_t completion,
5014 const char *name)
5015{
5016 tracepoint(librados, rados_aio_rmxattr_enter, io, o, completion, name);
5017 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5018 object_t oid(o);
5019 int retval = ctx->aio_rmxattr(oid, (librados::AioCompletionImpl*)completion, name);
5020 tracepoint(librados, rados_aio_rmxattr_exit, retval);
5021 return retval;
5022}
5023
5024extern "C" int rados_aio_stat(rados_ioctx_t io, const char *o,
5025 rados_completion_t completion,
5026 uint64_t *psize, time_t *pmtime)
5027{
5028 tracepoint(librados, rados_aio_stat_enter, io, o, completion);
5029 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5030 object_t oid(o);
5031 int retval = ctx->aio_stat(oid, (librados::AioCompletionImpl*)completion,
5032 psize, pmtime);
5033 tracepoint(librados, rados_aio_stat_exit, retval);
5034 return retval;
5035}
5036
5037extern "C" int rados_aio_cmpext(rados_ioctx_t io, const char *o,
5038 rados_completion_t completion, const char *cmp_buf,
5039 size_t cmp_len, uint64_t off)
5040{
5041 tracepoint(librados, rados_aio_cmpext_enter, io, o, completion, cmp_buf,
5042 cmp_len, off);
5043 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5044 object_t oid(o);
5045 int retval = ctx->aio_cmpext(oid, (librados::AioCompletionImpl*)completion,
5046 cmp_buf, cmp_len, off);
5047 tracepoint(librados, rados_aio_cmpext_exit, retval);
5048 return retval;
5049}
5050
5051extern "C" int rados_aio_cancel(rados_ioctx_t io, rados_completion_t completion)
5052{
5053 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5054 return ctx->aio_cancel((librados::AioCompletionImpl*)completion);
5055}
5056
5057extern "C" int rados_aio_exec(rados_ioctx_t io, const char *o,
5058 rados_completion_t completion,
5059 const char *cls, const char *method,
5060 const char *inbuf, size_t in_len,
5061 char *buf, size_t out_len)
5062{
5063 tracepoint(librados, rados_aio_exec_enter, io, o, completion);
5064 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5065 object_t oid(o);
5066 bufferlist inbl;
5067 inbl.append(inbuf, in_len);
5068 int retval = ctx->aio_exec(oid, (librados::AioCompletionImpl*)completion,
5069 cls, method, inbl, buf, out_len);
5070 tracepoint(librados, rados_aio_exec_exit, retval);
5071 return retval;
5072}
5073
5074struct C_WatchCB : public librados::WatchCtx {
5075 rados_watchcb_t wcb;
5076 void *arg;
5077 C_WatchCB(rados_watchcb_t _wcb, void *_arg) : wcb(_wcb), arg(_arg) {}
5078 void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override {
5079 wcb(opcode, ver, arg);
5080 }
5081};
5082
5083extern "C" int rados_watch(rados_ioctx_t io, const char *o, uint64_t ver,
5084 uint64_t *handle,
5085 rados_watchcb_t watchcb, void *arg)
5086{
5087 tracepoint(librados, rados_watch_enter, io, o, ver, watchcb, arg);
5088 uint64_t *cookie = handle;
5089 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5090 object_t oid(o);
5091 C_WatchCB *wc = new C_WatchCB(watchcb, arg);
5092 int retval = ctx->watch(oid, cookie, wc, NULL, true);
5093 tracepoint(librados, rados_watch_exit, retval, *handle);
5094 return retval;
5095}
5096
5097struct C_WatchCB2 : public librados::WatchCtx2 {
5098 rados_watchcb2_t wcb;
5099 rados_watcherrcb_t errcb;
5100 void *arg;
5101 C_WatchCB2(rados_watchcb2_t _wcb,
5102 rados_watcherrcb_t _errcb,
5103 void *_arg) : wcb(_wcb), errcb(_errcb), arg(_arg) {}
5104 void handle_notify(uint64_t notify_id,
5105 uint64_t cookie,
5106 uint64_t notifier_gid,
5107 bufferlist& bl) override {
5108 wcb(arg, notify_id, cookie, notifier_gid, bl.c_str(), bl.length());
5109 }
5110 void handle_error(uint64_t cookie, int err) override {
5111 if (errcb)
5112 errcb(arg, cookie, err);
5113 }
5114};
5115
5116extern "C" int rados_watch2(rados_ioctx_t io, const char *o, uint64_t *handle,
5117 rados_watchcb2_t watchcb,
5118 rados_watcherrcb_t watcherrcb,
5119 void *arg) {
5120 return rados_watch3(io, o, handle, watchcb, watcherrcb, 0, arg);
5121}
5122
5123extern "C" int rados_watch3(rados_ioctx_t io, const char *o, uint64_t *handle,
5124 rados_watchcb2_t watchcb,
5125 rados_watcherrcb_t watcherrcb,
5126 uint32_t timeout,
5127 void *arg)
5128{
5129 tracepoint(librados, rados_watch3_enter, io, o, handle, watchcb, timeout, arg);
5130 int ret;
5131 if (!watchcb || !o || !handle) {
5132 ret = -EINVAL;
5133 } else {
5134 uint64_t *cookie = handle;
5135 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5136 object_t oid(o);
5137 C_WatchCB2 *wc = new C_WatchCB2(watchcb, watcherrcb, arg);
5138 ret = ctx->watch(oid, cookie, NULL, wc, timeout, true);
5139 }
5140 tracepoint(librados, rados_watch3_exit, ret, handle ? *handle : 0);
5141 return ret;
5142}
5143
5144extern "C" int rados_aio_watch(rados_ioctx_t io, const char *o,
5145 rados_completion_t completion,
5146 uint64_t *handle,
5147 rados_watchcb2_t watchcb,
5148 rados_watcherrcb_t watcherrcb, void *arg) {
5149 return rados_aio_watch2(io, o, completion, handle, watchcb, watcherrcb, 0, arg);
5150}
5151
5152extern "C" int rados_aio_watch2(rados_ioctx_t io, const char *o,
5153 rados_completion_t completion,
5154 uint64_t *handle,
5155 rados_watchcb2_t watchcb,
5156 rados_watcherrcb_t watcherrcb,
5157 uint32_t timeout, void *arg)
5158{
5159 tracepoint(librados, rados_aio_watch2_enter, io, o, completion, handle, watchcb, timeout, arg);
5160 int ret;
5161 if (!completion || !watchcb || !o || !handle) {
5162 ret = -EINVAL;
5163 } else {
5164 uint64_t *cookie = handle;
5165 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5166 object_t oid(o);
5167 librados::AioCompletionImpl *c =
5168 reinterpret_cast<librados::AioCompletionImpl*>(completion);
5169 C_WatchCB2 *wc = new C_WatchCB2(watchcb, watcherrcb, arg);
5170 ret = ctx->aio_watch(oid, c, cookie, NULL, wc, timeout, true);
5171 }
5172 tracepoint(librados, rados_aio_watch2_exit, ret, handle ? *handle : 0);
5173 return ret;
5174}
5175
5176
5177extern "C" int rados_unwatch(rados_ioctx_t io, const char *o, uint64_t handle)
5178{
5179 tracepoint(librados, rados_unwatch_enter, io, o, handle);
5180 uint64_t cookie = handle;
5181 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5182 int retval = ctx->unwatch(cookie);
5183 tracepoint(librados, rados_unwatch_exit, retval);
5184 return retval;
5185}
5186
5187extern "C" int rados_unwatch2(rados_ioctx_t io, uint64_t handle)
5188{
5189 tracepoint(librados, rados_unwatch2_enter, io, handle);
5190 uint64_t cookie = handle;
5191 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5192 int retval = ctx->unwatch(cookie);
5193 tracepoint(librados, rados_unwatch2_exit, retval);
5194 return retval;
5195}
5196
5197extern "C" int rados_aio_unwatch(rados_ioctx_t io, uint64_t handle,
5198 rados_completion_t completion)
5199{
5200 tracepoint(librados, rados_aio_unwatch_enter, io, handle, completion);
5201 uint64_t cookie = handle;
5202 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5203 librados::AioCompletionImpl *c =
5204 reinterpret_cast<librados::AioCompletionImpl*>(completion);
5205 int retval = ctx->aio_unwatch(cookie, c);
5206 tracepoint(librados, rados_aio_unwatch_exit, retval);
5207 return retval;
5208}
5209
5210extern "C" int rados_watch_check(rados_ioctx_t io, uint64_t handle)
5211{
5212 tracepoint(librados, rados_watch_check_enter, io, handle);
5213 uint64_t cookie = handle;
5214 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5215 int retval = ctx->watch_check(cookie);
5216 tracepoint(librados, rados_watch_check_exit, retval);
5217 return retval;
5218}
5219
5220extern "C" int rados_notify(rados_ioctx_t io, const char *o,
5221 uint64_t ver, const char *buf, int buf_len)
5222{
5223 tracepoint(librados, rados_notify_enter, io, o, ver, buf, buf_len);
5224 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5225 object_t oid(o);
5226 bufferlist bl;
5227 if (buf) {
5228 bufferptr p = buffer::create(buf_len);
5229 memcpy(p.c_str(), buf, buf_len);
5230 bl.push_back(p);
5231 }
5232 int retval = ctx->notify(oid, bl, 0, NULL, NULL, NULL);
5233 tracepoint(librados, rados_notify_exit, retval);
5234 return retval;
5235}
5236
5237extern "C" int rados_notify2(rados_ioctx_t io, const char *o,
5238 const char *buf, int buf_len,
5239 uint64_t timeout_ms,
5240 char **reply_buffer,
5241 size_t *reply_buffer_len)
5242{
5243 tracepoint(librados, rados_notify2_enter, io, o, buf, buf_len, timeout_ms);
5244 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5245 object_t oid(o);
5246 bufferlist bl;
5247 if (buf) {
5248 bufferptr p = buffer::create(buf_len);
5249 memcpy(p.c_str(), buf, buf_len);
5250 bl.push_back(p);
5251 }
5252 int ret = ctx->notify(oid, bl, timeout_ms, NULL, reply_buffer, reply_buffer_len);
5253 tracepoint(librados, rados_notify2_exit, ret);
5254 return ret;
5255}
5256
5257extern "C" int rados_aio_notify(rados_ioctx_t io, const char *o,
5258 rados_completion_t completion,
5259 const char *buf, int buf_len,
5260 uint64_t timeout_ms, char **reply_buffer,
5261 size_t *reply_buffer_len)
5262{
5263 tracepoint(librados, rados_aio_notify_enter, io, o, completion, buf, buf_len,
5264 timeout_ms);
5265 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5266 object_t oid(o);
5267 bufferlist bl;
5268 if (buf) {
5269 bl.push_back(buffer::copy(buf, buf_len));
5270 }
5271 librados::AioCompletionImpl *c =
5272 reinterpret_cast<librados::AioCompletionImpl*>(completion);
5273 int ret = ctx->aio_notify(oid, c, bl, timeout_ms, NULL, reply_buffer,
5274 reply_buffer_len);
5275 tracepoint(librados, rados_aio_notify_exit, ret);
5276 return ret;
5277}
5278
5279extern "C" int rados_notify_ack(rados_ioctx_t io, const char *o,
5280 uint64_t notify_id, uint64_t handle,
5281 const char *buf, int buf_len)
5282{
5283 tracepoint(librados, rados_notify_ack_enter, io, o, notify_id, handle, buf, buf_len);
5284 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5285 object_t oid(o);
5286 bufferlist bl;
5287 if (buf) {
5288 bufferptr p = buffer::create(buf_len);
5289 memcpy(p.c_str(), buf, buf_len);
5290 bl.push_back(p);
5291 }
5292 ctx->notify_ack(oid, notify_id, handle, bl);
5293 tracepoint(librados, rados_notify_ack_exit, 0);
5294 return 0;
5295}
5296
5297extern "C" int rados_watch_flush(rados_t cluster)
5298{
5299 tracepoint(librados, rados_watch_flush_enter, cluster);
5300 librados::RadosClient *client = (librados::RadosClient *)cluster;
5301 int retval = client->watch_flush();
5302 tracepoint(librados, rados_watch_flush_exit, retval);
5303 return retval;
5304}
5305
5306extern "C" int rados_aio_watch_flush(rados_t cluster, rados_completion_t completion)
5307{
5308 tracepoint(librados, rados_aio_watch_flush_enter, cluster, completion);
5309 librados::RadosClient *client = (librados::RadosClient *)cluster;
5310 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
5311 int retval = client->async_watch_flush(c);
5312 tracepoint(librados, rados_aio_watch_flush_exit, retval);
5313 return retval;
5314}
5315
5316extern "C" int rados_set_alloc_hint(rados_ioctx_t io, const char *o,
5317 uint64_t expected_object_size,
5318 uint64_t expected_write_size)
5319{
5320 tracepoint(librados, rados_set_alloc_hint_enter, io, o, expected_object_size, expected_write_size);
5321 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5322 object_t oid(o);
5323 int retval = ctx->set_alloc_hint(oid, expected_object_size,
5324 expected_write_size, 0);
5325 tracepoint(librados, rados_set_alloc_hint_exit, retval);
5326 return retval;
5327}
5328
5329extern "C" int rados_set_alloc_hint2(rados_ioctx_t io, const char *o,
5330 uint64_t expected_object_size,
5331 uint64_t expected_write_size,
5332 uint32_t flags)
5333{
5334 tracepoint(librados, rados_set_alloc_hint2_enter, io, o, expected_object_size, expected_write_size, flags);
5335 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5336 object_t oid(o);
5337 int retval = ctx->set_alloc_hint(oid, expected_object_size,
5338 expected_write_size, flags);
5339 tracepoint(librados, rados_set_alloc_hint2_exit, retval);
5340 return retval;
5341}
5342
5343extern "C" int rados_lock_exclusive(rados_ioctx_t io, const char * o,
5344 const char * name, const char * cookie,
5345 const char * desc, struct timeval * duration,
5346 uint8_t flags)
5347{
5348 tracepoint(librados, rados_lock_exclusive_enter, io, o, name, cookie, desc, duration, flags);
5349 librados::IoCtx ctx;
5350 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5351
5352 int retval = ctx.lock_exclusive(o, name, cookie, desc, duration, flags);
5353 tracepoint(librados, rados_lock_exclusive_exit, retval);
5354 return retval;
5355}
5356
5357extern "C" int rados_lock_shared(rados_ioctx_t io, const char * o,
5358 const char * name, const char * cookie,
5359 const char * tag, const char * desc,
5360 struct timeval * duration, uint8_t flags)
5361{
5362 tracepoint(librados, rados_lock_shared_enter, io, o, name, cookie, tag, desc, duration, flags);
5363 librados::IoCtx ctx;
5364 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5365
5366 int retval = ctx.lock_shared(o, name, cookie, tag, desc, duration, flags);
5367 tracepoint(librados, rados_lock_shared_exit, retval);
5368 return retval;
5369}
5370extern "C" int rados_unlock(rados_ioctx_t io, const char *o, const char *name,
5371 const char *cookie)
5372{
5373 tracepoint(librados, rados_unlock_enter, io, o, name, cookie);
5374 librados::IoCtx ctx;
5375 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5376
5377 int retval = ctx.unlock(o, name, cookie);
5378 tracepoint(librados, rados_unlock_exit, retval);
5379 return retval;
5380}
5381
5382extern "C" int rados_aio_unlock(rados_ioctx_t io, const char *o, const char *name,
5383 const char *cookie, rados_completion_t completion)
5384{
5385 tracepoint(librados, rados_aio_unlock_enter, io, o, name, cookie, completion);
5386 librados::IoCtx ctx;
5387 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5388 librados::AioCompletionImpl *comp = (librados::AioCompletionImpl*)completion;
5389 librados::AioCompletion c(comp);
5390 int retval = ctx.aio_unlock(o, name, cookie, &c);
5391 tracepoint(librados, rados_aio_unlock_exit, retval);
5392 return retval;
5393}
5394
5395extern "C" ssize_t rados_list_lockers(rados_ioctx_t io, const char *o,
5396 const char *name, int *exclusive,
5397 char *tag, size_t *tag_len,
5398 char *clients, size_t *clients_len,
5399 char *cookies, size_t *cookies_len,
5400 char *addrs, size_t *addrs_len)
5401{
5402 tracepoint(librados, rados_list_lockers_enter, io, o, name, *tag_len, *clients_len, *cookies_len, *addrs_len);
5403 librados::IoCtx ctx;
5404 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5405 std::string name_str = name;
5406 std::string oid = o;
5407 std::string tag_str;
5408 int tmp_exclusive;
5409 std::list<librados::locker_t> lockers;
5410 int r = ctx.list_lockers(oid, name_str, &tmp_exclusive, &tag_str, &lockers);
5411 if (r < 0) {
5412 tracepoint(librados, rados_list_lockers_exit, r, *exclusive, "", *tag_len, *clients_len, *cookies_len, *addrs_len);
5413 return r;
5414 }
5415
5416 size_t clients_total = 0;
5417 size_t cookies_total = 0;
5418 size_t addrs_total = 0;
5419 list<librados::locker_t>::const_iterator it;
5420 for (it = lockers.begin(); it != lockers.end(); ++it) {
5421 clients_total += it->client.length() + 1;
5422 cookies_total += it->cookie.length() + 1;
5423 addrs_total += it->address.length() + 1;
5424 }
5425
5426 bool too_short = ((clients_total > *clients_len) ||
5427 (cookies_total > *cookies_len) ||
5428 (addrs_total > *addrs_len) ||
5429 (tag_str.length() + 1 > *tag_len));
5430 *clients_len = clients_total;
5431 *cookies_len = cookies_total;
5432 *addrs_len = addrs_total;
5433 *tag_len = tag_str.length() + 1;
5434 if (too_short) {
5435 tracepoint(librados, rados_list_lockers_exit, -ERANGE, *exclusive, "", *tag_len, *clients_len, *cookies_len, *addrs_len);
5436 return -ERANGE;
5437 }
5438
5439 strcpy(tag, tag_str.c_str());
5440 char *clients_p = clients;
5441 char *cookies_p = cookies;
5442 char *addrs_p = addrs;
5443 for (it = lockers.begin(); it != lockers.end(); ++it) {
5444 strcpy(clients_p, it->client.c_str());
5445 strcpy(cookies_p, it->cookie.c_str());
5446 strcpy(addrs_p, it->address.c_str());
5447 tracepoint(librados, rados_list_lockers_locker, clients_p, cookies_p, addrs_p);
5448 clients_p += it->client.length() + 1;
5449 cookies_p += it->cookie.length() + 1;
5450 addrs_p += it->address.length() + 1;
5451 }
5452 if (tmp_exclusive)
5453 *exclusive = 1;
5454 else
5455 *exclusive = 0;
5456
5457 int retval = lockers.size();
5458 tracepoint(librados, rados_list_lockers_exit, retval, *exclusive, tag, *tag_len, *clients_len, *cookies_len, *addrs_len);
5459 return retval;
5460}
5461
5462extern "C" int rados_break_lock(rados_ioctx_t io, const char *o,
5463 const char *name, const char *client,
5464 const char *cookie)
5465{
5466 tracepoint(librados, rados_break_lock_enter, io, o, name, client, cookie);
5467 librados::IoCtx ctx;
5468 librados::IoCtx::from_rados_ioctx_t(io, ctx);
5469
5470 int retval = ctx.break_lock(o, name, client, cookie);
5471 tracepoint(librados, rados_break_lock_exit, retval);
5472 return retval;
5473}
5474
5475extern "C" rados_write_op_t rados_create_write_op()
5476{
5477 tracepoint(librados, rados_create_write_op_enter);
5478 rados_write_op_t retval = new (std::nothrow)::ObjectOperation;
5479 tracepoint(librados, rados_create_write_op_exit, retval);
5480 return retval;
5481}
5482
5483extern "C" void rados_release_write_op(rados_write_op_t write_op)
5484{
5485 tracepoint(librados, rados_release_write_op_enter, write_op);
5486 delete (::ObjectOperation*)write_op;
5487 tracepoint(librados, rados_release_write_op_exit);
5488}
5489
5490extern "C" void rados_write_op_set_flags(rados_write_op_t write_op, int flags)
5491{
5492 tracepoint(librados, rados_write_op_set_flags_enter, write_op, flags);
5493 set_op_flags((::ObjectOperation *)write_op, flags);
5494 tracepoint(librados, rados_write_op_set_flags_exit);
5495}
5496
5497extern "C" void rados_write_op_assert_version(rados_write_op_t write_op, uint64_t ver)
5498{
5499 tracepoint(librados, rados_write_op_assert_version_enter, write_op, ver);
5500 ((::ObjectOperation *)write_op)->assert_version(ver);
5501 tracepoint(librados, rados_write_op_assert_version_exit);
5502}
5503
5504extern "C" void rados_write_op_assert_exists(rados_write_op_t write_op)
5505{
5506 tracepoint(librados, rados_write_op_assert_exists_enter, write_op);
5507 ((::ObjectOperation *)write_op)->stat(NULL, (ceph::real_time *)NULL, NULL);
5508 tracepoint(librados, rados_write_op_assert_exists_exit);
5509}
5510
5511extern "C" void rados_write_op_cmpext(rados_write_op_t write_op,
5512 const char *cmp_buf,
5513 size_t cmp_len,
5514 uint64_t off,
5515 int *prval)
5516{
5517 tracepoint(librados, rados_write_op_cmpext_enter, write_op, cmp_buf,
5518 cmp_len, off, prval);
5519 ((::ObjectOperation *)write_op)->cmpext(off, cmp_len, cmp_buf, prval);
5520 tracepoint(librados, rados_write_op_cmpext_exit);
5521}
5522
5523extern "C" void rados_write_op_cmpxattr(rados_write_op_t write_op,
5524 const char *name,
5525 uint8_t comparison_operator,
5526 const char *value,
5527 size_t value_len)
5528{
5529 tracepoint(librados, rados_write_op_cmpxattr_enter, write_op, name, comparison_operator, value, value_len);
5530 bufferlist bl;
5531 bl.append(value, value_len);
5532 ((::ObjectOperation *)write_op)->cmpxattr(name,
5533 comparison_operator,
5534 CEPH_OSD_CMPXATTR_MODE_STRING,
5535 bl);
5536 tracepoint(librados, rados_write_op_cmpxattr_exit);
5537}
5538
5539static void rados_c_omap_cmp(ObjectOperation *op,
5540 const char *key,
5541 uint8_t comparison_operator,
5542 const char *val,
5543 size_t val_len,
5544 int *prval)
5545{
5546 bufferlist bl;
5547 bl.append(val, val_len);
5548 std::map<std::string, pair<bufferlist, int> > assertions;
5549 assertions[key] = std::make_pair(bl, comparison_operator);
5550 op->omap_cmp(assertions, prval);
5551}
5552
5553extern "C" void rados_write_op_omap_cmp(rados_write_op_t write_op,
5554 const char *key,
5555 uint8_t comparison_operator,
5556 const char *val,
5557 size_t val_len,
5558 int *prval)
5559{
5560 tracepoint(librados, rados_write_op_omap_cmp_enter, write_op, key, comparison_operator, val, val_len, prval);
5561 rados_c_omap_cmp((::ObjectOperation *)write_op, key, comparison_operator,
5562 val, val_len, prval);
5563 tracepoint(librados, rados_write_op_omap_cmp_exit);
5564}
5565
5566extern "C" void rados_write_op_setxattr(rados_write_op_t write_op,
5567 const char *name,
5568 const char *value,
5569 size_t value_len)
5570{
5571 tracepoint(librados, rados_write_op_setxattr_enter, write_op, name, value, value_len);
5572 bufferlist bl;
5573 bl.append(value, value_len);
5574 ((::ObjectOperation *)write_op)->setxattr(name, bl);
5575 tracepoint(librados, rados_write_op_setxattr_exit);
5576}
5577
5578extern "C" void rados_write_op_rmxattr(rados_write_op_t write_op,
5579 const char *name)
5580{
5581 tracepoint(librados, rados_write_op_rmxattr_enter, write_op, name);
5582 ((::ObjectOperation *)write_op)->rmxattr(name);
5583 tracepoint(librados, rados_write_op_rmxattr_exit);
5584}
5585
5586extern "C" void rados_write_op_create(rados_write_op_t write_op,
5587 int exclusive,
5588 const char* category) // unused
5589{
5590 tracepoint(librados, rados_write_op_create_enter, write_op, exclusive);
5591 ::ObjectOperation *oo = (::ObjectOperation *) write_op;
5592 oo->create(!!exclusive);
5593 tracepoint(librados, rados_write_op_create_exit);
5594}
5595
5596extern "C" void rados_write_op_write(rados_write_op_t write_op,
5597 const char *buffer,
5598 size_t len,
5599 uint64_t offset)
5600{
5601 tracepoint(librados, rados_write_op_write_enter, write_op, buffer, len, offset);
5602 bufferlist bl;
5603 bl.append(buffer,len);
5604 ((::ObjectOperation *)write_op)->write(offset, bl);
5605 tracepoint(librados, rados_write_op_write_exit);
5606}
5607
5608extern "C" void rados_write_op_write_full(rados_write_op_t write_op,
5609 const char *buffer,
5610 size_t len)
5611{
5612 tracepoint(librados, rados_write_op_write_full_enter, write_op, buffer, len);
5613 bufferlist bl;
5614 bl.append(buffer,len);
5615 ((::ObjectOperation *)write_op)->write_full(bl);
5616 tracepoint(librados, rados_write_op_write_full_exit);
5617}
5618
5619extern "C" void rados_write_op_writesame(rados_write_op_t write_op,
5620 const char *buffer,
5621 size_t data_len,
5622 size_t write_len,
5623 uint64_t offset)
5624{
5625 tracepoint(librados, rados_write_op_writesame_enter, write_op, buffer, data_len, write_len, offset);
5626 bufferlist bl;
5627 bl.append(buffer, data_len);
5628 ((::ObjectOperation *)write_op)->writesame(offset, write_len, bl);
5629 tracepoint(librados, rados_write_op_writesame_exit);
5630}
5631
5632extern "C" void rados_write_op_append(rados_write_op_t write_op,
5633 const char *buffer,
5634 size_t len)
5635{
5636 tracepoint(librados, rados_write_op_append_enter, write_op, buffer, len);
5637 bufferlist bl;
5638 bl.append(buffer,len);
5639 ((::ObjectOperation *)write_op)->append(bl);
5640 tracepoint(librados, rados_write_op_append_exit);
5641}
5642
5643extern "C" void rados_write_op_remove(rados_write_op_t write_op)
5644{
5645 tracepoint(librados, rados_write_op_remove_enter, write_op);
5646 ((::ObjectOperation *)write_op)->remove();
5647 tracepoint(librados, rados_write_op_remove_exit);
5648}
5649
5650extern "C" void rados_write_op_truncate(rados_write_op_t write_op,
5651 uint64_t offset)
5652{
5653 tracepoint(librados, rados_write_op_truncate_enter, write_op, offset);
5654 ((::ObjectOperation *)write_op)->truncate(offset);
5655 tracepoint(librados, rados_write_op_truncate_exit);
5656}
5657
5658extern "C" void rados_write_op_zero(rados_write_op_t write_op,
5659 uint64_t offset,
5660 uint64_t len)
5661{
5662 tracepoint(librados, rados_write_op_zero_enter, write_op, offset, len);
5663 ((::ObjectOperation *)write_op)->zero(offset, len);
5664 tracepoint(librados, rados_write_op_zero_exit);
5665}
5666
5667extern "C" void rados_write_op_exec(rados_write_op_t write_op,
5668 const char *cls,
5669 const char *method,
5670 const char *in_buf,
5671 size_t in_len,
5672 int *prval)
5673{
5674 tracepoint(librados, rados_write_op_exec_enter, write_op, cls, method, in_buf, in_len, prval);
5675 bufferlist inbl;
5676 inbl.append(in_buf, in_len);
5677 ((::ObjectOperation *)write_op)->call(cls, method, inbl, NULL, NULL, prval);
5678 tracepoint(librados, rados_write_op_exec_exit);
5679}
5680
5681extern "C" void rados_write_op_omap_set(rados_write_op_t write_op,
5682 char const* const* keys,
5683 char const* const* vals,
5684 const size_t *lens,
5685 size_t num)
5686{
5687 tracepoint(librados, rados_write_op_omap_set_enter, write_op, num);
5688 std::map<std::string, bufferlist> entries;
5689 for (size_t i = 0; i < num; ++i) {
5690 tracepoint(librados, rados_write_op_omap_set_entry, keys[i], vals[i], lens[i]);
5691 bufferlist bl(lens[i]);
5692 bl.append(vals[i], lens[i]);
5693 entries[keys[i]] = bl;
5694 }
5695 ((::ObjectOperation *)write_op)->omap_set(entries);
5696 tracepoint(librados, rados_write_op_omap_set_exit);
5697}
5698
5699extern "C" void rados_write_op_omap_rm_keys(rados_write_op_t write_op,
5700 char const* const* keys,
5701 size_t keys_len)
5702{
5703 tracepoint(librados, rados_write_op_omap_rm_keys_enter, write_op, keys_len);
5704 for(size_t i = 0; i < keys_len; i++) {
5705 tracepoint(librados, rados_write_op_omap_rm_keys_entry, keys[i]);
5706 }
5707 std::set<std::string> to_remove(keys, keys + keys_len);
5708 ((::ObjectOperation *)write_op)->omap_rm_keys(to_remove);
5709 tracepoint(librados, rados_write_op_omap_rm_keys_exit);
5710}
5711
5712extern "C" void rados_write_op_omap_clear(rados_write_op_t write_op)
5713{
5714 tracepoint(librados, rados_write_op_omap_clear_enter, write_op);
5715 ((::ObjectOperation *)write_op)->omap_clear();
5716 tracepoint(librados, rados_write_op_omap_clear_exit);
5717}
5718
5719extern "C" void rados_write_op_set_alloc_hint(rados_write_op_t write_op,
5720 uint64_t expected_object_size,
5721 uint64_t expected_write_size)
5722{
5723 tracepoint(librados, rados_write_op_set_alloc_hint_enter, write_op, expected_object_size, expected_write_size);
5724 ((::ObjectOperation *)write_op)->set_alloc_hint(expected_object_size,
5725 expected_write_size, 0);
5726 tracepoint(librados, rados_write_op_set_alloc_hint_exit);
5727}
5728
5729extern "C" void rados_write_op_set_alloc_hint2(rados_write_op_t write_op,
5730 uint64_t expected_object_size,
5731 uint64_t expected_write_size,
5732 uint32_t flags)
5733{
5734 tracepoint(librados, rados_write_op_set_alloc_hint2_enter, write_op, expected_object_size, expected_write_size, flags);
5735 ((::ObjectOperation *)write_op)->set_alloc_hint(expected_object_size,
5736 expected_write_size,
5737 flags);
5738 tracepoint(librados, rados_write_op_set_alloc_hint2_exit);
5739}
5740
5741extern "C" int rados_write_op_operate(rados_write_op_t write_op,
5742 rados_ioctx_t io,
5743 const char *oid,
5744 time_t *mtime,
5745 int flags)
5746{
5747 tracepoint(librados, rados_write_op_operate_enter, write_op, io, oid, mtime, flags);
5748 object_t obj(oid);
5749 ::ObjectOperation *oo = (::ObjectOperation *) write_op;
5750 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5751
5752 ceph::real_time *prt = NULL;
5753 ceph::real_time rt;
5754
5755 if (mtime) {
5756 rt = ceph::real_clock::from_time_t(*mtime);
5757 prt = &rt;
5758 }
5759
5760 int retval = ctx->operate(obj, oo, prt, translate_flags(flags));
5761 tracepoint(librados, rados_write_op_operate_exit, retval);
5762 return retval;
5763}
5764
5765extern "C" int rados_write_op_operate2(rados_write_op_t write_op,
5766 rados_ioctx_t io,
5767 const char *oid,
5768 struct timespec *ts,
5769 int flags)
5770{
5771 tracepoint(librados, rados_write_op_operate2_enter, write_op, io, oid, ts, flags);
5772 object_t obj(oid);
5773 ::ObjectOperation *oo = (::ObjectOperation *) write_op;
5774 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5775
5776 ceph::real_time *prt = NULL;
5777 ceph::real_time rt;
5778
5779 if (ts) {
5780 rt = ceph::real_clock::from_timespec(*ts);
5781 prt = &rt;
5782 }
5783
5784 int retval = ctx->operate(obj, oo, prt, translate_flags(flags));
5785 tracepoint(librados, rados_write_op_operate_exit, retval);
5786 return retval;
5787}
5788
5789extern "C" int rados_aio_write_op_operate(rados_write_op_t write_op,
5790 rados_ioctx_t io,
5791 rados_completion_t completion,
5792 const char *oid,
5793 time_t *mtime,
5794 int flags)
5795{
5796 tracepoint(librados, rados_aio_write_op_operate_enter, write_op, io, completion, oid, mtime, flags);
5797 object_t obj(oid);
5798 ::ObjectOperation *oo = (::ObjectOperation *) write_op;
5799 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
5800 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
5801 int retval = ctx->aio_operate(obj, oo, c, ctx->snapc, translate_flags(flags));
5802 tracepoint(librados, rados_aio_write_op_operate_exit, retval);
5803 return retval;
5804}
5805
5806extern "C" rados_read_op_t rados_create_read_op()
5807{
5808 tracepoint(librados, rados_create_read_op_enter);
5809 rados_read_op_t retval = new (std::nothrow)::ObjectOperation;
5810 tracepoint(librados, rados_create_read_op_exit, retval);
5811 return retval;
5812}
5813
5814extern "C" void rados_release_read_op(rados_read_op_t read_op)
5815{
5816 tracepoint(librados, rados_release_read_op_enter, read_op);
5817 delete (::ObjectOperation *)read_op;
5818 tracepoint(librados, rados_release_read_op_exit);
5819}
5820
5821extern "C" void rados_read_op_set_flags(rados_read_op_t read_op, int flags)
5822{
5823 tracepoint(librados, rados_read_op_set_flags_enter, read_op, flags);
5824 set_op_flags((::ObjectOperation *)read_op, flags);
5825 tracepoint(librados, rados_read_op_set_flags_exit);
5826}
5827
5828extern "C" void rados_read_op_assert_version(rados_read_op_t read_op, uint64_t ver)
5829{
5830 tracepoint(librados, rados_read_op_assert_version_enter, read_op, ver);
5831 ((::ObjectOperation *)read_op)->assert_version(ver);
5832 tracepoint(librados, rados_read_op_assert_version_exit);
5833}
5834
5835extern "C" void rados_read_op_assert_exists(rados_read_op_t read_op)
5836{
5837 tracepoint(librados, rados_read_op_assert_exists_enter, read_op);
5838 ((::ObjectOperation *)read_op)->stat(NULL, (ceph::real_time *)NULL, NULL);
5839 tracepoint(librados, rados_read_op_assert_exists_exit);
5840}
5841
5842extern "C" void rados_read_op_cmpext(rados_read_op_t read_op,
5843 const char *cmp_buf,
5844 size_t cmp_len,
5845 uint64_t off,
5846 int *prval)
5847{
5848 tracepoint(librados, rados_read_op_cmpext_enter, read_op, cmp_buf,
5849 cmp_len, off, prval);
5850 ((::ObjectOperation *)read_op)->cmpext(off, cmp_len, cmp_buf, prval);
5851 tracepoint(librados, rados_read_op_cmpext_exit);
5852}
5853
5854extern "C" void rados_read_op_cmpxattr(rados_read_op_t read_op,
5855 const char *name,
5856 uint8_t comparison_operator,
5857 const char *value,
5858 size_t value_len)
5859{
5860 tracepoint(librados, rados_read_op_cmpxattr_enter, read_op, name, comparison_operator, value, value_len);
5861 bufferlist bl;
5862 bl.append(value, value_len);
5863 ((::ObjectOperation *)read_op)->cmpxattr(name,
5864 comparison_operator,
5865 CEPH_OSD_CMPXATTR_MODE_STRING,
5866 bl);
5867 tracepoint(librados, rados_read_op_cmpxattr_exit);
5868}
5869
5870extern "C" void rados_read_op_omap_cmp(rados_read_op_t read_op,
5871 const char *key,
5872 uint8_t comparison_operator,
5873 const char *val,
5874 size_t val_len,
5875 int *prval)
5876{
5877 tracepoint(librados, rados_read_op_omap_cmp_enter, read_op, key, comparison_operator, val, val_len, prval);
5878 rados_c_omap_cmp((::ObjectOperation *)read_op, key, comparison_operator,
5879 val, val_len, prval);
5880 tracepoint(librados, rados_read_op_omap_cmp_exit);
5881}
5882
5883extern "C" void rados_read_op_stat(rados_read_op_t read_op,
5884 uint64_t *psize,
5885 time_t *pmtime,
5886 int *prval)
5887{
5888 tracepoint(librados, rados_read_op_stat_enter, read_op, psize, pmtime, prval);
5889 ((::ObjectOperation *)read_op)->stat(psize, pmtime, prval);
5890 tracepoint(librados, rados_read_op_stat_exit);
5891}
5892
5893class C_bl_to_buf : public Context {
5894 char *out_buf;
5895 size_t out_len;
5896 size_t *bytes_read;
5897 int *prval;
5898public:
5899 bufferlist out_bl;
5900 C_bl_to_buf(char *out_buf,
5901 size_t out_len,
5902 size_t *bytes_read,
5903 int *prval) : out_buf(out_buf), out_len(out_len),
5904 bytes_read(bytes_read), prval(prval) {}
5905 void finish(int r) override {
5906 if (out_bl.length() > out_len) {
5907 if (prval)
5908 *prval = -ERANGE;
5909 if (bytes_read)
5910 *bytes_read = 0;
5911 return;
5912 }
5913 if (bytes_read)
5914 *bytes_read = out_bl.length();
5915 if (out_buf && !out_bl.is_provided_buffer(out_buf))
5916 out_bl.copy(0, out_bl.length(), out_buf);
5917 }
5918};
5919
5920extern "C" void rados_read_op_read(rados_read_op_t read_op,
5921 uint64_t offset,
5922 size_t len,
5923 char *buf,
5924 size_t *bytes_read,
5925 int *prval)
5926{
5927 tracepoint(librados, rados_read_op_read_enter, read_op, offset, len, buf, bytes_read, prval);
5928 C_bl_to_buf *ctx = new C_bl_to_buf(buf, len, bytes_read, prval);
5929 ctx->out_bl.push_back(buffer::create_static(len, buf));
5930 ((::ObjectOperation *)read_op)->read(offset, len, &ctx->out_bl, prval, ctx);
5931 tracepoint(librados, rados_read_op_read_exit);
5932}
5933
5934extern "C" void rados_read_op_checksum(rados_read_op_t read_op,
5935 rados_checksum_type_t type,
5936 const char *init_value,
5937 size_t init_value_len,
5938 uint64_t offset, size_t len,
5939 size_t chunk_size, char *pchecksum,
5940 size_t checksum_len, int *prval)
5941{
5942 tracepoint(librados, rados_read_op_checksum_enter, read_op, type, init_value,
5943 init_value_len, offset, len, chunk_size);
5944 bufferlist init_value_bl;
5945 init_value_bl.append(init_value, init_value_len);
5946
5947 C_bl_to_buf *ctx = nullptr;
5948 if (pchecksum != nullptr) {
5949 ctx = new C_bl_to_buf(pchecksum, checksum_len, nullptr, prval);
5950 }
5951 ((::ObjectOperation *)read_op)->checksum(get_checksum_op_type(type),
5952 init_value_bl, offset, len,
5953 chunk_size,
5954 (ctx ? &ctx->out_bl : nullptr),
5955 prval, ctx);
5956 tracepoint(librados, rados_read_op_checksum_exit);
5957}
5958
5959class C_out_buffer : public Context {
5960 char **out_buf;
5961 size_t *out_len;
5962public:
5963 bufferlist out_bl;
5964 C_out_buffer(char **out_buf, size_t *out_len) : out_buf(out_buf),
5965 out_len(out_len) {}
5966 void finish(int r) override {
5967 // ignore r since we don't know the meaning of return values
5968 // from custom class methods
5969 do_out_buffer(out_bl, out_buf, out_len);
5970 }
5971};
5972
5973extern "C" void rados_read_op_exec(rados_read_op_t read_op,
5974 const char *cls,
5975 const char *method,
5976 const char *in_buf,
5977 size_t in_len,
5978 char **out_buf,
5979 size_t *out_len,
5980 int *prval)
5981{
5982 tracepoint(librados, rados_read_op_exec_enter, read_op, cls, method, in_buf, in_len, out_buf, out_len, prval);
5983 bufferlist inbl;
5984 inbl.append(in_buf, in_len);
5985 C_out_buffer *ctx = new C_out_buffer(out_buf, out_len);
5986 ((::ObjectOperation *)read_op)->call(cls, method, inbl, &ctx->out_bl, ctx,
5987 prval);
5988 tracepoint(librados, rados_read_op_exec_exit);
5989}
5990
5991extern "C" void rados_read_op_exec_user_buf(rados_read_op_t read_op,
5992 const char *cls,
5993 const char *method,
5994 const char *in_buf,
5995 size_t in_len,
5996 char *out_buf,
5997 size_t out_len,
5998 size_t *used_len,
5999 int *prval)
6000{
6001 tracepoint(librados, rados_read_op_exec_user_buf_enter, read_op, cls, method, in_buf, in_len, out_buf, out_len, used_len, prval);
6002 C_bl_to_buf *ctx = new C_bl_to_buf(out_buf, out_len, used_len, prval);
6003 bufferlist inbl;
6004 inbl.append(in_buf, in_len);
6005 ((::ObjectOperation *)read_op)->call(cls, method, inbl, &ctx->out_bl, ctx,
6006 prval);
6007 tracepoint(librados, rados_read_op_exec_user_buf_exit);
6008}
6009
6010struct RadosOmapIter {
6011 std::map<std::string, bufferlist> values;
6012 std::map<std::string, bufferlist>::iterator i;
6013};
6014
6015class C_OmapIter : public Context {
6016 RadosOmapIter *iter;
6017public:
6018 explicit C_OmapIter(RadosOmapIter *iter) : iter(iter) {}
6019 void finish(int r) override {
6020 iter->i = iter->values.begin();
6021 }
6022};
6023
6024class C_XattrsIter : public Context {
6025 librados::RadosXattrsIter *iter;
6026public:
6027 explicit C_XattrsIter(librados::RadosXattrsIter *iter) : iter(iter) {}
6028 void finish(int r) override {
6029 iter->i = iter->attrset.begin();
6030 }
6031};
6032
6033extern "C" void rados_read_op_getxattrs(rados_read_op_t read_op,
6034 rados_xattrs_iter_t *iter,
6035 int *prval)
6036{
6037 tracepoint(librados, rados_read_op_getxattrs_enter, read_op, prval);
6038 librados::RadosXattrsIter *xattrs_iter = new librados::RadosXattrsIter;
6039 ((::ObjectOperation *)read_op)->getxattrs(&xattrs_iter->attrset, prval);
6040 ((::ObjectOperation *)read_op)->add_handler(new C_XattrsIter(xattrs_iter));
6041 *iter = xattrs_iter;
6042 tracepoint(librados, rados_read_op_getxattrs_exit, *iter);
6043}
6044
6045extern "C" void rados_read_op_omap_get_vals(rados_read_op_t read_op,
6046 const char *start_after,
6047 const char *filter_prefix,
6048 uint64_t max_return,
6049 rados_omap_iter_t *iter,
6050 int *prval)
6051{
6052 tracepoint(librados, rados_read_op_omap_get_vals_enter, read_op, start_after, filter_prefix, max_return, prval);
6053 RadosOmapIter *omap_iter = new RadosOmapIter;
6054 const char *start = start_after ? start_after : "";
6055 const char *filter = filter_prefix ? filter_prefix : "";
6056 ((::ObjectOperation *)read_op)->omap_get_vals(
6057 start,
6058 filter,
6059 max_return,
6060 &omap_iter->values,
6061 nullptr,
6062 prval);
6063 ((::ObjectOperation *)read_op)->add_handler(new C_OmapIter(omap_iter));
6064 *iter = omap_iter;
6065 tracepoint(librados, rados_read_op_omap_get_vals_exit, *iter);
6066}
6067
6068extern "C" void rados_read_op_omap_get_vals2(rados_read_op_t read_op,
6069 const char *start_after,
6070 const char *filter_prefix,
6071 uint64_t max_return,
6072 rados_omap_iter_t *iter,
6073 unsigned char *pmore,
6074 int *prval)
6075{
6076 tracepoint(librados, rados_read_op_omap_get_vals_enter, read_op, start_after, filter_prefix, max_return, prval);
6077 RadosOmapIter *omap_iter = new RadosOmapIter;
6078 const char *start = start_after ? start_after : "";
6079 const char *filter = filter_prefix ? filter_prefix : "";
6080 ((::ObjectOperation *)read_op)->omap_get_vals(
6081 start,
6082 filter,
6083 max_return,
6084 &omap_iter->values,
6085 (bool*)pmore,
6086 prval);
6087 ((::ObjectOperation *)read_op)->add_handler(new C_OmapIter(omap_iter));
6088 *iter = omap_iter;
6089 tracepoint(librados, rados_read_op_omap_get_vals_exit, *iter);
6090}
6091
6092struct C_OmapKeysIter : public Context {
6093 RadosOmapIter *iter;
6094 std::set<std::string> keys;
6095 explicit C_OmapKeysIter(RadosOmapIter *iter) : iter(iter) {}
6096 void finish(int r) override {
6097 // map each key to an empty bl
6098 for (std::set<std::string>::const_iterator i = keys.begin();
6099 i != keys.end(); ++i) {
6100 iter->values[*i];
6101 }
6102 iter->i = iter->values.begin();
6103 }
6104};
6105
6106extern "C" void rados_read_op_omap_get_keys(rados_read_op_t read_op,
6107 const char *start_after,
6108 uint64_t max_return,
6109 rados_omap_iter_t *iter,
6110 int *prval)
6111{
6112 tracepoint(librados, rados_read_op_omap_get_keys_enter, read_op, start_after, max_return, prval);
6113 RadosOmapIter *omap_iter = new RadosOmapIter;
6114 C_OmapKeysIter *ctx = new C_OmapKeysIter(omap_iter);
6115 ((::ObjectOperation *)read_op)->omap_get_keys(
6116 start_after ? start_after : "",
6117 max_return, &ctx->keys, nullptr, prval);
6118 ((::ObjectOperation *)read_op)->add_handler(ctx);
6119 *iter = omap_iter;
6120 tracepoint(librados, rados_read_op_omap_get_keys_exit, *iter);
6121}
6122
6123extern "C" void rados_read_op_omap_get_keys2(rados_read_op_t read_op,
6124 const char *start_after,
6125 uint64_t max_return,
6126 rados_omap_iter_t *iter,
6127 unsigned char *pmore,
6128 int *prval)
6129{
6130 tracepoint(librados, rados_read_op_omap_get_keys_enter, read_op, start_after, max_return, prval);
6131 RadosOmapIter *omap_iter = new RadosOmapIter;
6132 C_OmapKeysIter *ctx = new C_OmapKeysIter(omap_iter);
6133 ((::ObjectOperation *)read_op)->omap_get_keys(
6134 start_after ? start_after : "",
6135 max_return, &ctx->keys,
6136 (bool*)pmore, prval);
6137 ((::ObjectOperation *)read_op)->add_handler(ctx);
6138 *iter = omap_iter;
6139 tracepoint(librados, rados_read_op_omap_get_keys_exit, *iter);
6140}
6141
6142extern "C" void rados_read_op_omap_get_vals_by_keys(rados_read_op_t read_op,
6143 char const* const* keys,
6144 size_t keys_len,
6145 rados_omap_iter_t *iter,
6146 int *prval)
6147{
6148 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_enter, read_op, keys, keys_len, iter, prval);
6149 std::set<std::string> to_get(keys, keys + keys_len);
6150
6151 RadosOmapIter *omap_iter = new RadosOmapIter;
6152 ((::ObjectOperation *)read_op)->omap_get_vals_by_keys(to_get,
6153 &omap_iter->values,
6154 prval);
6155 ((::ObjectOperation *)read_op)->add_handler(new C_OmapIter(omap_iter));
6156 *iter = omap_iter;
6157 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_exit, *iter);
6158}
6159
6160extern "C" int rados_omap_get_next(rados_omap_iter_t iter,
6161 char **key,
6162 char **val,
6163 size_t *len)
6164{
6165 tracepoint(librados, rados_omap_get_next_enter, iter);
6166 RadosOmapIter *it = static_cast<RadosOmapIter *>(iter);
6167 if (it->i == it->values.end()) {
6168 *key = NULL;
6169 *val = NULL;
6170 *len = 0;
6171 tracepoint(librados, rados_omap_get_next_exit, 0, key, val, len);
6172 return 0;
6173 }
6174 if (key)
6175 *key = (char*)it->i->first.c_str();
6176 if (val)
6177 *val = it->i->second.c_str();
6178 if (len)
6179 *len = it->i->second.length();
6180 ++it->i;
6181 tracepoint(librados, rados_omap_get_next_exit, 0, key, val, len);
6182 return 0;
6183}
6184
6185extern "C" void rados_omap_get_end(rados_omap_iter_t iter)
6186{
6187 tracepoint(librados, rados_omap_get_end_enter, iter);
6188 RadosOmapIter *it = static_cast<RadosOmapIter *>(iter);
6189 delete it;
6190 tracepoint(librados, rados_omap_get_end_exit);
6191}
6192
6193extern "C" int rados_read_op_operate(rados_read_op_t read_op,
6194 rados_ioctx_t io,
6195 const char *oid,
6196 int flags)
6197{
6198 tracepoint(librados, rados_read_op_operate_enter, read_op, io, oid, flags);
6199 object_t obj(oid);
6200 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
6201 int retval = ctx->operate_read(obj, (::ObjectOperation *)read_op, NULL,
6202 translate_flags(flags));
6203 tracepoint(librados, rados_read_op_operate_exit, retval);
6204 return retval;
6205}
6206
6207extern "C" int rados_aio_read_op_operate(rados_read_op_t read_op,
6208 rados_ioctx_t io,
6209 rados_completion_t completion,
6210 const char *oid,
6211 int flags)
6212{
6213 tracepoint(librados, rados_aio_read_op_operate_enter, read_op, io, completion, oid, flags);
6214 object_t obj(oid);
6215 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
6216 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
6217 int retval = ctx->aio_operate_read(obj, (::ObjectOperation *)read_op,
6218 c, translate_flags(flags), NULL);
6219 tracepoint(librados, rados_aio_read_op_operate_exit, retval);
6220 return retval;
6221}
6222
6223extern "C" int rados_cache_pin(rados_ioctx_t io, const char *o)
6224{
6225 tracepoint(librados, rados_cache_pin_enter, io, o);
6226 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
6227 object_t oid(o);
6228 int retval = ctx->cache_pin(oid);
6229 tracepoint(librados, rados_cache_pin_exit, retval);
6230 return retval;
6231}
6232
6233extern "C" int rados_cache_unpin(rados_ioctx_t io, const char *o)
6234{
6235 tracepoint(librados, rados_cache_unpin_enter, io, o);
6236 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
6237 object_t oid(o);
6238 int retval = ctx->cache_unpin(oid);
6239 tracepoint(librados, rados_cache_unpin_exit, retval);
6240 return retval;
6241}
6242
6243
6244///////////////////////////// ListObject //////////////////////////////
6245librados::ListObject::ListObject() : impl(NULL)
6246{
6247}
6248
6249librados::ListObject::ListObject(librados::ListObjectImpl *i): impl(i)
6250{
6251}
6252
6253librados::ListObject::ListObject(const ListObject& rhs)
6254{
6255 if (rhs.impl == NULL) {
6256 impl = NULL;
6257 return;
6258 }
6259 impl = new ListObjectImpl();
6260 *impl = *(rhs.impl);
6261}
6262
6263librados::ListObject& librados::ListObject::operator=(const ListObject& rhs)
6264{
6265 if (rhs.impl == NULL) {
6266 delete impl;
6267 impl = NULL;
6268 return *this;
6269 }
6270 if (impl == NULL)
6271 impl = new ListObjectImpl();
6272 *impl = *(rhs.impl);
6273 return *this;
6274}
6275
6276librados::ListObject::~ListObject()
6277{
6278 if (impl)
6279 delete impl;
6280 impl = NULL;
6281}
6282
6283const std::string& librados::ListObject::get_nspace() const
6284{
6285 return impl->get_nspace();
6286}
6287
6288const std::string& librados::ListObject::get_oid() const
6289{
6290 return impl->get_oid();
6291}
6292
6293const std::string& librados::ListObject::get_locator() const
6294{
6295 return impl->get_locator();
6296}
6297
6298std::ostream& librados::operator<<(std::ostream& out, const librados::ListObject& lop)
6299{
6300 out << *(lop.impl);
6301 return out;
6302}
6303
6304CEPH_RADOS_API void rados_object_list_slice(
6305 rados_ioctx_t io,
6306 const rados_object_list_cursor start,
6307 const rados_object_list_cursor finish,
6308 const size_t n,
6309 const size_t m,
6310 rados_object_list_cursor *split_start,
6311 rados_object_list_cursor *split_finish)
6312{
6313 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
6314
6315 assert(split_start);
6316 assert(split_finish);
6317 hobject_t *split_start_hobj = (hobject_t*)(*split_start);
6318 hobject_t *split_finish_hobj = (hobject_t*)(*split_finish);
6319 assert(split_start_hobj);
6320 assert(split_finish_hobj);
6321 hobject_t *start_hobj = (hobject_t*)(start);
6322 hobject_t *finish_hobj = (hobject_t*)(finish);
6323
6324 ctx->object_list_slice(
6325 *start_hobj,
6326 *finish_hobj,
6327 n,
6328 m,
6329 split_start_hobj,
6330 split_finish_hobj);
6331}
6332
6333librados::ObjectCursor::ObjectCursor()
6334{
6335 c_cursor = (rados_object_list_cursor)new hobject_t();
6336}
6337
6338librados::ObjectCursor::~ObjectCursor()
6339{
6340 hobject_t *h = (hobject_t *)c_cursor;
6341 delete h;
6342}
6343
6344librados::ObjectCursor::ObjectCursor(rados_object_list_cursor c)
6345{
6346 if (!c) {
6347 c_cursor = nullptr;
6348 } else {
6349 c_cursor = (rados_object_list_cursor)new hobject_t(*(hobject_t *)c);
6350 }
6351}
6352
6353librados::ObjectCursor& librados::ObjectCursor::operator=(const librados::ObjectCursor& rhs)
6354{
6355 if (rhs.c_cursor != nullptr) {
6356 hobject_t *h = (hobject_t*)rhs.c_cursor;
6357 c_cursor = (rados_object_list_cursor)(new hobject_t(*h));
6358 } else {
6359 c_cursor = nullptr;
6360 }
6361 return *this;
6362}
6363
6364bool librados::ObjectCursor::operator<(const librados::ObjectCursor &rhs) const
6365{
6366 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
6367 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
6368 return lhs_hobj < rhs_hobj;
6369}
6370
6371bool librados::ObjectCursor::operator==(const librados::ObjectCursor &rhs) const
6372{
6373 const hobject_t lhs_hobj = (c_cursor == nullptr) ? hobject_t() : *((hobject_t*)c_cursor);
6374 const hobject_t rhs_hobj = (rhs.c_cursor == nullptr) ? hobject_t() : *((hobject_t*)(rhs.c_cursor));
6375 return cmp(lhs_hobj, rhs_hobj) == 0;
6376}
6377librados::ObjectCursor::ObjectCursor(const librados::ObjectCursor &rhs)
6378{
6379 *this = rhs;
6380}
6381
6382librados::ObjectCursor librados::IoCtx::object_list_begin()
6383{
6384 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_begin());
6385 ObjectCursor oc;
6386 oc.set((rados_object_list_cursor)h);
6387 return oc;
6388}
6389
6390
6391librados::ObjectCursor librados::IoCtx::object_list_end()
6392{
6393 hobject_t *h = new hobject_t(io_ctx_impl->objecter->enumerate_objects_end());
6394 librados::ObjectCursor oc;
6395 oc.set((rados_object_list_cursor)h);
6396 return oc;
6397}
6398
6399
6400void librados::ObjectCursor::set(rados_object_list_cursor c)
6401{
6402 delete (hobject_t*)c_cursor;
6403 c_cursor = c;
6404}
6405
6406string librados::ObjectCursor::to_str() const
6407{
6408 stringstream ss;
6409 ss << *(hobject_t *)c_cursor;
6410 return ss.str();
6411}
6412
6413bool librados::ObjectCursor::from_str(const string& s)
6414{
6415 if (s.empty()) {
6416 *(hobject_t *)c_cursor = hobject_t();
6417 return true;
6418 }
6419 return ((hobject_t *)c_cursor)->parse(s);
6420}
6421
6422CEPH_RADOS_API std::ostream& librados::operator<<(std::ostream& os, const librados::ObjectCursor& oc)
6423{
6424 if (oc.c_cursor) {
6425 os << *(hobject_t *)oc.c_cursor;
6426 } else {
6427 os << hobject_t();
6428 }
6429 return os;
6430}
6431
6432bool librados::IoCtx::object_list_is_end(const ObjectCursor &oc)
6433{
6434 hobject_t *h = (hobject_t *)oc.c_cursor;
6435 return h->is_max();
6436}
6437
6438int librados::IoCtx::object_list(const ObjectCursor &start,
6439 const ObjectCursor &finish,
6440 const size_t result_item_count,
6441 const bufferlist &filter,
6442 std::vector<ObjectItem> *result,
6443 ObjectCursor *next)
6444{
6445 assert(result != nullptr);
6446 assert(next != nullptr);
6447 result->clear();
6448
6449 C_SaferCond cond;
6450 hobject_t next_hash;
6451 std::list<librados::ListObjectImpl> obj_result;
6452 io_ctx_impl->objecter->enumerate_objects(
6453 io_ctx_impl->poolid,
6454 io_ctx_impl->oloc.nspace,
6455 *((hobject_t*)start.c_cursor),
6456 *((hobject_t*)finish.c_cursor),
6457 result_item_count,
6458 filter,
6459 &obj_result,
6460 &next_hash,
6461 &cond);
6462
6463 int r = cond.wait();
6464 if (r < 0) {
6465 next->set((rados_object_list_cursor)(new hobject_t(hobject_t::get_max())));
6466 return r;
6467 }
6468
6469 next->set((rados_object_list_cursor)(new hobject_t(next_hash)));
6470
6471 for (std::list<librados::ListObjectImpl>::iterator i = obj_result.begin();
6472 i != obj_result.end(); ++i) {
6473 ObjectItem oi;
6474 oi.oid = i->oid;
6475 oi.nspace = i->nspace;
6476 oi.locator = i->locator;
6477 result->push_back(oi);
6478 }
6479
6480 return obj_result.size();
6481}
6482
6483void librados::IoCtx::object_list_slice(
6484 const ObjectCursor start,
6485 const ObjectCursor finish,
6486 const size_t n,
6487 const size_t m,
6488 ObjectCursor *split_start,
6489 ObjectCursor *split_finish)
6490{
6491 assert(split_start != nullptr);
6492 assert(split_finish != nullptr);
6493
6494 io_ctx_impl->object_list_slice(
6495 *((hobject_t*)(start.c_cursor)),
6496 *((hobject_t*)(finish.c_cursor)),
6497 n,
6498 m,
6499 (hobject_t*)(split_start->c_cursor),
6500 (hobject_t*)(split_finish->c_cursor));
6501}
6502
c07f9fc5
FG
6503int librados::IoCtx::application_enable(const std::string& app_name,
6504 bool force)
6505{
6506 return io_ctx_impl->application_enable(app_name, force);
6507}
6508
6509int librados::IoCtx::application_enable_async(const std::string& app_name,
6510 bool force,
6511 PoolAsyncCompletion *c)
6512{
6513 io_ctx_impl->application_enable_async(app_name, force, c->pc);
6514 return 0;
6515}
6516
6517int librados::IoCtx::application_list(std::set<std::string> *app_names)
6518{
6519 return io_ctx_impl->application_list(app_names);
6520}
6521
6522int librados::IoCtx::application_metadata_get(const std::string& app_name,
6523 const std::string &key,
6524 std::string* value)
6525{
6526 return io_ctx_impl->application_metadata_get(app_name, key, value);
6527}
6528
6529int librados::IoCtx::application_metadata_set(const std::string& app_name,
6530 const std::string &key,
6531 const std::string& value)
6532{
6533 return io_ctx_impl->application_metadata_set(app_name, key, value);
6534}
6535
6536int librados::IoCtx::application_metadata_remove(const std::string& app_name,
6537 const std::string &key)
6538{
6539 return io_ctx_impl->application_metadata_remove(app_name, key);
6540}
6541
6542int librados::IoCtx::application_metadata_list(const std::string& app_name,
6543 std::map<std::string, std::string> *values)
6544{
6545 return io_ctx_impl->application_metadata_list(app_name, values);
6546}
6547
6548