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