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