]> git.proxmox.com Git - ceph.git/blame - ceph/src/cls/rbd/cls_rbd_client.cc
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / cls / rbd / cls_rbd_client.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "cls/rbd/cls_rbd_client.h"
5#include "cls/lock/cls_lock_client.h"
6#include "include/buffer.h"
7c673cae
FG
7#include "include/encoding.h"
8#include "include/rbd_types.h"
31f18b77 9#include "include/rados/librados.hpp"
f67539c2 10#include "include/neorados/RADOS.hpp"
11fdf7f2 11#include "common/bit_vector.hpp"
7c673cae
FG
12
13#include <errno.h>
14
15namespace librbd {
11fdf7f2
TL
16namespace cls_client {
17
f67539c2
TL
18using std::map;
19using std::set;
20using std::string;
21
22using ceph::bufferlist;
23using ceph::decode;
24using ceph::encode;
25
11fdf7f2
TL
26void create_image(librados::ObjectWriteOperation *op, uint64_t size,
27 uint8_t order, uint64_t features,
28 const std::string &object_prefix, int64_t data_pool_id)
29{
30 bufferlist bl;
31 encode(size, bl);
32 encode(order, bl);
33 encode(features, bl);
34 encode(object_prefix, bl);
35 encode(data_pool_id, bl);
36
37 op->exec("rbd", "create", bl);
38}
39
40int create_image(librados::IoCtx *ioctx, const std::string &oid,
41 uint64_t size, uint8_t order, uint64_t features,
42 const std::string &object_prefix, int64_t data_pool_id)
43{
44 librados::ObjectWriteOperation op;
45 create_image(&op, size, order, features, object_prefix, data_pool_id);
46
47 return ioctx->operate(oid, &op);
48}
49
50void get_features_start(librados::ObjectReadOperation *op, bool read_only)
51{
52 bufferlist bl;
53 encode(static_cast<uint64_t>(CEPH_NOSNAP), bl);
54 encode(read_only, bl);
55 op->exec("rbd", "get_features", bl);
56}
57
58int get_features_finish(bufferlist::const_iterator *it, uint64_t *features,
59 uint64_t *incompatible_features)
60{
61 try {
62 decode(*features, *it);
63 decode(*incompatible_features, *it);
f67539c2 64 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
65 return -EBADMSG;
66 }
67
68 return 0;
69}
70
71int get_features(librados::IoCtx *ioctx, const std::string &oid,
72 bool read_only, uint64_t *features,
73 uint64_t *incompatible_features)
74{
75 librados::ObjectReadOperation op;
76 get_features_start(&op, read_only);
77
78 bufferlist out_bl;
79 int r = ioctx->operate(oid, &op, &out_bl);
80 if (r < 0) {
81 return r;
82 }
83
84 auto it = out_bl.cbegin();
85 return get_features_finish(&it, features, incompatible_features);
86}
87
88void set_features(librados::ObjectWriteOperation *op, uint64_t features,
89 uint64_t mask)
90{
91 bufferlist bl;
92 encode(features, bl);
93 encode(mask, bl);
94
95 op->exec("rbd", "set_features", bl);
96}
97
98int set_features(librados::IoCtx *ioctx, const std::string &oid,
99 uint64_t features, uint64_t mask)
100{
101 librados::ObjectWriteOperation op;
102 set_features(&op, features, mask);
103
104 return ioctx->operate(oid, &op);
105}
106
107void get_object_prefix_start(librados::ObjectReadOperation *op)
108{
109 bufferlist bl;
110 op->exec("rbd", "get_object_prefix", bl);
111}
112
113int get_object_prefix_finish(bufferlist::const_iterator *it,
114 std::string *object_prefix)
115{
116 try {
117 decode(*object_prefix, *it);
f67539c2 118 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
119 return -EBADMSG;
120 }
121 return 0;
122}
123
124int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid,
125 std::string *object_prefix)
126{
127 librados::ObjectReadOperation op;
128 get_object_prefix_start(&op);
129
130 bufferlist out_bl;
131 int r = ioctx->operate(oid, &op, &out_bl);
132 if (r < 0) {
133 return r;
134 }
135
136 auto it = out_bl.cbegin();
137 return get_object_prefix_finish(&it, object_prefix);
138}
139
140void get_data_pool_start(librados::ObjectReadOperation *op) {
141 bufferlist bl;
142 op->exec("rbd", "get_data_pool", bl);
143}
144
145int get_data_pool_finish(bufferlist::const_iterator *it, int64_t *data_pool_id) {
146 try {
147 decode(*data_pool_id, *it);
f67539c2 148 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
149 return -EBADMSG;
150 }
151 return 0;
152}
153
154int get_data_pool(librados::IoCtx *ioctx, const std::string &oid,
155 int64_t *data_pool_id) {
156 librados::ObjectReadOperation op;
157 get_data_pool_start(&op);
158
159 bufferlist out_bl;
160 int r = ioctx->operate(oid, &op, &out_bl);
161 if (r < 0) {
162 return r;
163 }
164
165 auto it = out_bl.cbegin();
166 return get_data_pool_finish(&it, data_pool_id);
167}
168
169void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id)
170{
171 bufferlist bl;
172 encode(snap_id, bl);
173 op->exec("rbd", "get_size", bl);
174}
175
176int get_size_finish(bufferlist::const_iterator *it, uint64_t *size,
177 uint8_t *order)
178{
179 try {
180 decode(*order, *it);
181 decode(*size, *it);
f67539c2 182 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
183 return -EBADMSG;
184 }
185 return 0;
186}
187
188int get_size(librados::IoCtx *ioctx, const std::string &oid,
189 snapid_t snap_id, uint64_t *size, uint8_t *order)
190{
191 librados::ObjectReadOperation op;
192 get_size_start(&op, snap_id);
193
194 bufferlist out_bl;
195 int r = ioctx->operate(oid, &op, &out_bl);
196 if (r < 0) {
197 return r;
198 }
199
200 auto it = out_bl.cbegin();
201 return get_size_finish(&it, size, order);
202}
203
204int set_size(librados::IoCtx *ioctx, const std::string &oid,
205 uint64_t size)
206{
207 librados::ObjectWriteOperation op;
208 set_size(&op, size);
209 return ioctx->operate(oid, &op);
210}
211
212void set_size(librados::ObjectWriteOperation *op, uint64_t size)
213{
214 bufferlist bl;
215 encode(size, bl);
216 op->exec("rbd", "set_size", bl);
217}
218
219void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id) {
220 bufferlist in_bl;
221 encode(static_cast<snapid_t>(snap_id), in_bl);
222 op->exec("rbd", "get_flags", in_bl);
223}
224
225int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags) {
226 try {
227 decode(*flags, *it);
f67539c2 228 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
229 return -EBADMSG;
230 }
231 return 0;
232}
233
234int get_flags(librados::IoCtx *ioctx, const std::string &oid,
235 snapid_t snap_id, uint64_t *flags)
236{
237 librados::ObjectReadOperation op;
238 get_flags_start(&op, snap_id);
239
240 bufferlist out_bl;
241 int r = ioctx->operate(oid, &op, &out_bl);
242 if (r < 0) {
243 return r;
244 }
245
246 auto it = out_bl.cbegin();
247 return get_flags_finish(&it, flags);
248}
249
250void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id,
251 uint64_t flags, uint64_t mask)
252{
253 bufferlist inbl;
254 encode(flags, inbl);
255 encode(mask, inbl);
256 encode(snap_id, inbl);
257 op->exec("rbd", "set_flags", inbl);
258}
259
260void op_features_get_start(librados::ObjectReadOperation *op)
261{
262 bufferlist in_bl;
263 op->exec("rbd", "op_features_get", in_bl);
264}
265
266int op_features_get_finish(bufferlist::const_iterator *it, uint64_t *op_features)
267{
268 try {
269 decode(*op_features, *it);
f67539c2 270 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
271 return -EBADMSG;
272 }
273 return 0;
274}
275
276int op_features_get(librados::IoCtx *ioctx, const std::string &oid,
277 uint64_t *op_features)
278{
279 librados::ObjectReadOperation op;
280 op_features_get_start(&op);
281
282 bufferlist out_bl;
283 int r = ioctx->operate(oid, &op, &out_bl);
284 if (r < 0) {
285 return r;
286 }
287
288 auto it = out_bl.cbegin();
289 return op_features_get_finish(&it, op_features);
290}
291
292void op_features_set(librados::ObjectWriteOperation *op,
293 uint64_t op_features, uint64_t mask)
294{
295 bufferlist inbl;
296 encode(op_features, inbl);
297 encode(mask, inbl);
298 op->exec("rbd", "op_features_set", inbl);
299}
300
301int op_features_set(librados::IoCtx *ioctx, const std::string &oid,
302 uint64_t op_features, uint64_t mask)
303{
304 librados::ObjectWriteOperation op;
305 op_features_set(&op, op_features, mask);
306
307 return ioctx->operate(oid, &op);
308}
309
310void get_parent_start(librados::ObjectReadOperation *op, snapid_t snap_id)
311{
312 bufferlist bl;
313 encode(snap_id, bl);
314 op->exec("rbd", "get_parent", bl);
315}
316
317int get_parent_finish(bufferlist::const_iterator *it,
318 cls::rbd::ParentImageSpec *pspec,
319 uint64_t *parent_overlap)
320{
321 *pspec = {};
322 try {
323 decode(pspec->pool_id, *it);
324 decode(pspec->image_id, *it);
325 decode(pspec->snap_id, *it);
326 decode(*parent_overlap, *it);
f67539c2 327 } catch (const ceph::buffer::error &) {
11fdf7f2
TL
328 return -EBADMSG;
329 }
330 return 0;
331}
332
333int get_parent(librados::IoCtx *ioctx, const std::string &oid,
334 snapid_t snap_id, cls::rbd::ParentImageSpec *pspec,
335 uint64_t *parent_overlap)
336{
337 librados::ObjectReadOperation op;
338 get_parent_start(&op, snap_id);
339
340 bufferlist out_bl;
341 int r = ioctx->operate(oid, &op, &out_bl);
342 if (r < 0) {
343 return r;
344 }
345
346 auto it = out_bl.cbegin();
347 return get_parent_finish(&it, pspec, parent_overlap);
348}
349
350int set_parent(librados::IoCtx *ioctx, const std::string &oid,
351 const cls::rbd::ParentImageSpec &pspec, uint64_t parent_overlap)
352{
353 librados::ObjectWriteOperation op;
354 set_parent(&op, pspec, parent_overlap);
355 return ioctx->operate(oid, &op);
356}
357
358void set_parent(librados::ObjectWriteOperation *op,
359 const cls::rbd::ParentImageSpec &pspec,
360 uint64_t parent_overlap) {
361 assert(pspec.pool_namespace.empty());
362
363 bufferlist in_bl;
364 encode(pspec.pool_id, in_bl);
365 encode(pspec.image_id, in_bl);
366 encode(pspec.snap_id, in_bl);
367 encode(parent_overlap, in_bl);
368
369 op->exec("rbd", "set_parent", in_bl);
370}
371
372int remove_parent(librados::IoCtx *ioctx, const std::string &oid)
373{
374 librados::ObjectWriteOperation op;
375 remove_parent(&op);
376 return ioctx->operate(oid, &op);
377}
378
379void remove_parent(librados::ObjectWriteOperation *op)
380{
381 bufferlist inbl;
382 op->exec("rbd", "remove_parent", inbl);
383}
384
385void parent_get_start(librados::ObjectReadOperation* op) {
386 bufferlist in_bl;
387 op->exec("rbd", "parent_get", in_bl);
388}
389
390int parent_get_finish(bufferlist::const_iterator* it,
391 cls::rbd::ParentImageSpec* parent_image_spec) {
392 try {
393 decode(*parent_image_spec, *it);
f67539c2 394 } catch (const ceph::buffer::error &) {
11fdf7f2
TL
395 return -EBADMSG;
396 }
397 return 0;
398}
399
400int parent_get(librados::IoCtx* ioctx, const std::string &oid,
401 cls::rbd::ParentImageSpec* parent_image_spec) {
402 librados::ObjectReadOperation op;
403 parent_get_start(&op);
404
405 bufferlist out_bl;
406 int r = ioctx->operate(oid, &op, &out_bl);
407 if (r < 0) {
408 return r;
409 }
410
411 auto it = out_bl.cbegin();
412 r = parent_get_finish(&it, parent_image_spec);
413 if (r < 0) {
414 return r;
415 }
416 return 0;
417}
418
419void parent_overlap_get_start(librados::ObjectReadOperation* op,
420 snapid_t snap_id) {
421 bufferlist in_bl;
422 encode(snap_id, in_bl);
423 op->exec("rbd", "parent_overlap_get", in_bl);
424}
425
426int parent_overlap_get_finish(bufferlist::const_iterator* it,
427 std::optional<uint64_t>* parent_overlap) {
428 try {
429 decode(*parent_overlap, *it);
f67539c2 430 } catch (const ceph::buffer::error &) {
11fdf7f2
TL
431 return -EBADMSG;
432 }
433 return 0;
434}
435
436int parent_overlap_get(librados::IoCtx* ioctx, const std::string &oid,
437 snapid_t snap_id,
438 std::optional<uint64_t>* parent_overlap) {
439 librados::ObjectReadOperation op;
440 parent_overlap_get_start(&op, snap_id);
441
442 bufferlist out_bl;
443 int r = ioctx->operate(oid, &op, &out_bl);
444 if (r < 0) {
445 return r;
446 }
447
448 auto it = out_bl.cbegin();
449 r = parent_overlap_get_finish(&it, parent_overlap);
450 if (r < 0) {
451 return r;
452 }
453 return 0;
454}
455
456void parent_attach(librados::ObjectWriteOperation* op,
457 const cls::rbd::ParentImageSpec& parent_image_spec,
458 uint64_t parent_overlap, bool reattach) {
459 bufferlist in_bl;
460 encode(parent_image_spec, in_bl);
461 encode(parent_overlap, in_bl);
462 encode(reattach, in_bl);
463 op->exec("rbd", "parent_attach", in_bl);
464}
465
466int parent_attach(librados::IoCtx *ioctx, const std::string &oid,
467 const cls::rbd::ParentImageSpec& parent_image_spec,
468 uint64_t parent_overlap, bool reattach) {
469 librados::ObjectWriteOperation op;
470 parent_attach(&op, parent_image_spec, parent_overlap, reattach);
471 return ioctx->operate(oid, &op);
472}
473
474void parent_detach(librados::ObjectWriteOperation* op) {
475 bufferlist in_bl;
476 op->exec("rbd", "parent_detach", in_bl);
477}
478
479int parent_detach(librados::IoCtx *ioctx, const std::string &oid) {
480 librados::ObjectWriteOperation op;
481 parent_detach(&op);
482 return ioctx->operate(oid, &op);
483}
484
485int add_child(librados::IoCtx *ioctx, const std::string &oid,
486 const cls::rbd::ParentImageSpec &pspec,
487 const std::string &c_imageid)
488{
489 librados::ObjectWriteOperation op;
490 add_child(&op, pspec, c_imageid);
491 return ioctx->operate(oid, &op);
492}
493
494void add_child(librados::ObjectWriteOperation *op,
495 const cls::rbd::ParentImageSpec& pspec,
496 const std::string &c_imageid)
497{
498 assert(pspec.pool_namespace.empty());
499
500 bufferlist in;
501 encode(pspec.pool_id, in);
502 encode(pspec.image_id, in);
503 encode(pspec.snap_id, in);
504 encode(c_imageid, in);
505
506 op->exec("rbd", "add_child", in);
507}
508
509void remove_child(librados::ObjectWriteOperation *op,
510 const cls::rbd::ParentImageSpec &pspec,
511 const std::string &c_imageid)
512{
513 assert(pspec.pool_namespace.empty());
514
515 bufferlist in;
516 encode(pspec.pool_id, in);
517 encode(pspec.image_id, in);
518 encode(pspec.snap_id, in);
519 encode(c_imageid, in);
520 op->exec("rbd", "remove_child", in);
521}
522
523int remove_child(librados::IoCtx *ioctx, const std::string &oid,
524 const cls::rbd::ParentImageSpec &pspec,
525 const std::string &c_imageid)
526{
527 librados::ObjectWriteOperation op;
528 remove_child(&op, pspec, c_imageid);
529 return ioctx->operate(oid, &op);
530}
531
532void get_children_start(librados::ObjectReadOperation *op,
533 const cls::rbd::ParentImageSpec &pspec) {
534 bufferlist in_bl;
535 encode(pspec.pool_id, in_bl);
536 encode(pspec.image_id, in_bl);
537 encode(pspec.snap_id, in_bl);
538 op->exec("rbd", "get_children", in_bl);
539}
540
541int get_children_finish(bufferlist::const_iterator *it,
542 std::set<std::string>* children) {
543 try {
544 decode(*children, *it);
f67539c2 545 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
546 return -EBADMSG;
547 }
548 return 0;
549}
550
551int get_children(librados::IoCtx *ioctx, const std::string &oid,
552 const cls::rbd::ParentImageSpec &pspec, set<string>& children)
553{
554 librados::ObjectReadOperation op;
555 get_children_start(&op, pspec);
556
557 bufferlist out_bl;
558 int r = ioctx->operate(oid, &op, &out_bl);
559 if (r < 0) {
560 return r;
561 }
562
563 auto it = out_bl.cbegin();
564 return get_children_finish(&it, &children);
565}
566
567void snapshot_get_start(librados::ObjectReadOperation *op, snapid_t snap_id)
568{
569 bufferlist bl;
570 encode(snap_id, bl);
571 op->exec("rbd", "snapshot_get", bl);
572}
573
574int snapshot_get_finish(bufferlist::const_iterator* it,
575 cls::rbd::SnapshotInfo* snap_info)
576{
577 try {
578 decode(*snap_info, *it);
f67539c2 579 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
580 return -EBADMSG;
581 }
582 return 0;
583}
584
585int snapshot_get(librados::IoCtx *ioctx, const std::string &oid,
586 snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info)
587{
588 librados::ObjectReadOperation op;
589 snapshot_get_start(&op, snap_id);
590
591 bufferlist out_bl;
592 int r = ioctx->operate(oid, &op, &out_bl);
593 if (r < 0) {
594 return r;
595 }
596
597 auto it = out_bl.cbegin();
598 return snapshot_get_finish(&it, snap_info);
599}
600
601void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id,
602 const std::string &snap_name,
603 const cls::rbd::SnapshotNamespace &snap_namespace)
604{
605 bufferlist bl;
606 encode(snap_name, bl);
607 encode(snap_id, bl);
608 encode(snap_namespace, bl);
609 op->exec("rbd", "snapshot_add", bl);
610}
611
612void snapshot_remove(librados::ObjectWriteOperation *op, snapid_t snap_id)
613{
614 bufferlist bl;
615 encode(snap_id, bl);
616 op->exec("rbd", "snapshot_remove", bl);
617}
618
619void snapshot_rename(librados::ObjectWriteOperation *op,
620 snapid_t src_snap_id,
621 const std::string &dst_name)
622{
623 bufferlist bl;
624 encode(src_snap_id, bl);
625 encode(dst_name, bl);
626 op->exec("rbd", "snapshot_rename", bl);
627}
628
629void snapshot_trash_add(librados::ObjectWriteOperation *op,
630 snapid_t snap_id)
631{
632 bufferlist bl;
633 encode(snap_id, bl);
634 op->exec("rbd", "snapshot_trash_add", bl);
635}
636
637void get_snapcontext_start(librados::ObjectReadOperation *op)
638{
639 bufferlist bl;
640 op->exec("rbd", "get_snapcontext", bl);
641}
642
643int get_snapcontext_finish(bufferlist::const_iterator *it,
644 ::SnapContext *snapc)
645{
646 try {
647 decode(*snapc, *it);
f67539c2 648 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
649 return -EBADMSG;
650 }
651 if (!snapc->is_valid()) {
652 return -EBADMSG;
653 }
654 return 0;
655}
656
657int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
658 ::SnapContext *snapc)
659{
660 librados::ObjectReadOperation op;
661 get_snapcontext_start(&op);
662
663 bufferlist out_bl;
664 int r = ioctx->operate(oid, &op, &out_bl);
665 if (r < 0) {
666 return r;
667 }
668
669 auto bl_it = out_bl.cbegin();
670 return get_snapcontext_finish(&bl_it, snapc);
671}
672
673void get_snapshot_name_start(librados::ObjectReadOperation *op,
674 snapid_t snap_id)
675{
676 bufferlist bl;
677 encode(snap_id, bl);
678 op->exec("rbd", "get_snapshot_name", bl);
679}
680
681int get_snapshot_name_finish(bufferlist::const_iterator *it,
682 std::string *name)
683{
684 try {
685 decode(*name, *it);
f67539c2 686 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
687 return -EBADMSG;
688 }
689 return 0;
690}
691
692int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid,
693 snapid_t snap_id, std::string *name)
694{
695 librados::ObjectReadOperation op;
696 get_snapshot_name_start(&op, snap_id);
697
698 bufferlist out_bl;
699 int r = ioctx->operate(oid, &op, &out_bl);
700 if (r < 0) {
701 return r;
702 }
703
704 auto it = out_bl.cbegin();
705 return get_snapshot_name_finish(&it, name);
706}
707
708void get_snapshot_timestamp_start(librados::ObjectReadOperation *op,
709 snapid_t snap_id)
710{
711 bufferlist bl;
712 encode(snap_id, bl);
713 op->exec("rbd", "get_snapshot_timestamp", bl);
714}
715
716int get_snapshot_timestamp_finish(bufferlist::const_iterator *it,
717 utime_t *timestamp)
718{
719 try {
720 decode(*timestamp, *it);
f67539c2 721 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
722 return -EBADMSG;
723 }
724 return 0;
725}
726
727int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid,
728 snapid_t snap_id, utime_t *timestamp)
729{
730 librados::ObjectReadOperation op;
731 get_snapshot_timestamp_start(&op, snap_id);
732
733 bufferlist out_bl;
734 int r = ioctx->operate(oid, &op, &out_bl);
735 if (r < 0) {
736 return r;
737 }
738
739 auto it = out_bl.cbegin();
740 return get_snapshot_timestamp_finish(&it, timestamp);
741}
742
743void old_snapshot_add(librados::ObjectWriteOperation *op,
744 snapid_t snap_id, const std::string &snap_name)
745{
746 bufferlist bl;
747 encode(snap_name, bl);
748 encode(snap_id, bl);
749 op->exec("rbd", "snap_add", bl);
750}
751
752void old_snapshot_remove(librados::ObjectWriteOperation *op,
753 const std::string &snap_name)
754{
755 bufferlist bl;
756 encode(snap_name, bl);
757 op->exec("rbd", "snap_remove", bl);
758}
759
760void old_snapshot_rename(librados::ObjectWriteOperation *op,
761 snapid_t src_snap_id, const std::string &dst_name)
762{
763 bufferlist bl;
764 encode(src_snap_id, bl);
765 encode(dst_name, bl);
766 op->exec("rbd", "snap_rename", bl);
767}
768
769void old_snapshot_list_start(librados::ObjectReadOperation *op) {
770 bufferlist in_bl;
771 op->exec("rbd", "snap_list", in_bl);
772}
773
774int old_snapshot_list_finish(bufferlist::const_iterator *it,
7c673cae
FG
775 std::vector<string> *names,
776 std::vector<uint64_t> *sizes,
11fdf7f2
TL
777 ::SnapContext *snapc) {
778 try {
779 uint32_t num_snaps;
780 decode(snapc->seq, *it);
781 decode(num_snaps, *it);
782
783 names->resize(num_snaps);
784 sizes->resize(num_snaps);
785 snapc->snaps.resize(num_snaps);
786 for (uint32_t i = 0; i < num_snaps; ++i) {
787 decode(snapc->snaps[i], *it);
788 decode((*sizes)[i], *it);
789 decode((*names)[i], *it);
790 }
f67539c2 791 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
792 return -EBADMSG;
793 }
794 return 0;
795}
796
797int old_snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
798 std::vector<string> *names,
799 std::vector<uint64_t> *sizes,
800 ::SnapContext *snapc)
801{
802 librados::ObjectReadOperation op;
803 old_snapshot_list_start(&op);
804
805 bufferlist out_bl;
806 int r = ioctx->operate(oid, &op, &out_bl);
807 if (r < 0) {
808 return r;
809 }
810
811 auto it = out_bl.cbegin();
812 return old_snapshot_list_finish(&it, names, sizes, snapc);
813}
814
815void get_all_features_start(librados::ObjectReadOperation *op) {
816 bufferlist in;
817 op->exec("rbd", "get_all_features", in);
818}
819
820int get_all_features_finish(bufferlist::const_iterator *it,
821 uint64_t *all_features) {
822 try {
823 decode(*all_features, *it);
f67539c2 824 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
825 return -EBADMSG;
826 }
827 return 0;
828}
829
830int get_all_features(librados::IoCtx *ioctx, const std::string &oid,
831 uint64_t *all_features) {
832 librados::ObjectReadOperation op;
833 get_all_features_start(&op);
834
835 bufferlist out_bl;
836 int r = ioctx->operate(oid, &op, &out_bl);
837 if (r < 0) {
838 return r;
839 }
840
841 auto it = out_bl.cbegin();
842 return get_all_features_finish(&it, all_features);
843}
844
f67539c2
TL
845template <typename O>
846void copyup(O* op, ceph::buffer::list data) {
9f95a23c
TL
847 op->exec("rbd", "copyup", data);
848}
849
f67539c2
TL
850void copyup(neorados::WriteOp* op, ceph::buffer::list data) {
851 copyup<neorados::WriteOp>(op, data);
852}
853
854void copyup(librados::ObjectWriteOperation *op, bufferlist data) {
855 copyup<librados::ObjectWriteOperation>(op, data);
856}
857
11fdf7f2
TL
858int copyup(librados::IoCtx *ioctx, const std::string &oid,
859 bufferlist data) {
9f95a23c
TL
860 librados::ObjectWriteOperation op;
861 copyup(&op, data);
862
863 return ioctx->operate(oid, &op);
864}
865
f67539c2
TL
866template <typename O, typename E>
867void sparse_copyup(O* op, const E& extent_map, ceph::buffer::list data) {
9f95a23c
TL
868 bufferlist bl;
869 encode(extent_map, bl);
870 encode(data, bl);
871 op->exec("rbd", "sparse_copyup", bl);
872}
873
f67539c2
TL
874void sparse_copyup(neorados::WriteOp* op,
875 const std::vector<std::pair<uint64_t, uint64_t>>& extent_map,
876 ceph::buffer::list data) {
877 sparse_copyup<neorados::WriteOp>(op, extent_map, data);
878}
879
880void sparse_copyup(librados::ObjectWriteOperation *op,
881 const std::map<uint64_t, uint64_t> &extent_map,
882 bufferlist data) {
883 sparse_copyup<librados::ObjectWriteOperation>(op, extent_map, data);
884}
885
9f95a23c
TL
886int sparse_copyup(librados::IoCtx *ioctx, const std::string &oid,
887 const std::map<uint64_t, uint64_t> &extent_map,
888 bufferlist data) {
889 librados::ObjectWriteOperation op;
890 sparse_copyup(&op, extent_map, data);
891
892 return ioctx->operate(oid, &op);
11fdf7f2
TL
893}
894
895void get_protection_status_start(librados::ObjectReadOperation *op,
896 snapid_t snap_id)
897{
898 bufferlist bl;
899 encode(snap_id, bl);
900 op->exec("rbd", "get_protection_status", bl);
901}
902
903int get_protection_status_finish(bufferlist::const_iterator *it,
904 uint8_t *protection_status)
905{
906 try {
907 decode(*protection_status, *it);
f67539c2 908 } catch (const ceph::buffer::error &) {
11fdf7f2
TL
909 return -EBADMSG;
910 }
911 return 0;
912}
913
914int get_protection_status(librados::IoCtx *ioctx, const std::string &oid,
915 snapid_t snap_id, uint8_t *protection_status)
916{
917 librados::ObjectReadOperation op;
918 get_protection_status_start(&op, snap_id);
919
920 bufferlist out_bl;
921 int r = ioctx->operate(oid, &op, &out_bl);
922 if (r < 0) {
923 return r;
924 }
925
926 auto it = out_bl.cbegin();
927 return get_protection_status_finish(&it, protection_status);
928}
929
930int set_protection_status(librados::IoCtx *ioctx, const std::string &oid,
931 snapid_t snap_id, uint8_t protection_status)
932{
933 // TODO remove
934 librados::ObjectWriteOperation op;
935 set_protection_status(&op, snap_id, protection_status);
936 return ioctx->operate(oid, &op);
937}
938
939void set_protection_status(librados::ObjectWriteOperation *op,
940 snapid_t snap_id, uint8_t protection_status)
941{
942 bufferlist in;
943 encode(snap_id, in);
944 encode(protection_status, in);
945 op->exec("rbd", "set_protection_status", in);
946}
947
9f95a23c
TL
948void snapshot_get_limit_start(librados::ObjectReadOperation *op)
949{
950 bufferlist bl;
951 op->exec("rbd", "snapshot_get_limit", bl);
952}
953
954int snapshot_get_limit_finish(bufferlist::const_iterator *it, uint64_t *limit)
955{
956 try {
957 decode(*limit, *it);
f67539c2 958 } catch (const ceph::buffer::error &err) {
9f95a23c
TL
959 return -EBADMSG;
960 }
961 return 0;
962}
963
11fdf7f2
TL
964int snapshot_get_limit(librados::IoCtx *ioctx, const std::string &oid,
965 uint64_t *limit)
966{
9f95a23c
TL
967 librados::ObjectReadOperation op;
968 snapshot_get_limit_start(&op);
11fdf7f2 969
9f95a23c
TL
970 bufferlist out_bl;
971 int r = ioctx->operate(oid, &op, &out_bl);
11fdf7f2
TL
972 if (r < 0) {
973 return r;
974 }
975
9f95a23c
TL
976 auto it = out_bl.cbegin();
977 return snapshot_get_limit_finish(&it, limit);
11fdf7f2
TL
978}
979
980void snapshot_set_limit(librados::ObjectWriteOperation *op, uint64_t limit)
981{
982 bufferlist in;
983 encode(limit, in);
984 op->exec("rbd", "snapshot_set_limit", in);
985}
986
987void get_stripe_unit_count_start(librados::ObjectReadOperation *op) {
988 bufferlist empty_bl;
989 op->exec("rbd", "get_stripe_unit_count", empty_bl);
990}
991
992int get_stripe_unit_count_finish(bufferlist::const_iterator *it,
993 uint64_t *stripe_unit,
994 uint64_t *stripe_count) {
995 ceph_assert(stripe_unit);
996 ceph_assert(stripe_count);
997
998 try {
999 decode(*stripe_unit, *it);
1000 decode(*stripe_count, *it);
f67539c2 1001 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1002 return -EBADMSG;
1003 }
1004 return 0;
1005}
1006
1007int get_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
1008 uint64_t *stripe_unit, uint64_t *stripe_count)
1009{
1010 librados::ObjectReadOperation op;
1011 get_stripe_unit_count_start(&op);
1012
1013 bufferlist out_bl;
1014 int r = ioctx->operate(oid, &op, &out_bl);
1015 if (r < 0) {
1016 return r;
1017 }
1018
1019 auto it = out_bl.cbegin();
1020 return get_stripe_unit_count_finish(&it, stripe_unit, stripe_count);
1021}
1022
1023void set_stripe_unit_count(librados::ObjectWriteOperation *op,
1024 uint64_t stripe_unit, uint64_t stripe_count)
1025{
1026 bufferlist bl;
1027 encode(stripe_unit, bl);
1028 encode(stripe_count, bl);
1029
1030 op->exec("rbd", "set_stripe_unit_count", bl);
1031}
1032
1033int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
1034 uint64_t stripe_unit, uint64_t stripe_count)
1035{
1036 librados::ObjectWriteOperation op;
1037 set_stripe_unit_count(&op, stripe_unit, stripe_count);
1038
1039 return ioctx->operate(oid, &op);
1040}
1041
1042void get_create_timestamp_start(librados::ObjectReadOperation *op) {
1043 bufferlist empty_bl;
1044 op->exec("rbd", "get_create_timestamp", empty_bl);
1045}
1046
1047int get_create_timestamp_finish(bufferlist::const_iterator *it,
1048 utime_t *timestamp) {
1049 ceph_assert(timestamp);
1050
1051 try {
1052 decode(*timestamp, *it);
f67539c2 1053 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1054 return -EBADMSG;
1055 }
1056 return 0;
1057}
1058
1059int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1060 utime_t *timestamp)
1061{
1062 librados::ObjectReadOperation op;
1063 get_create_timestamp_start(&op);
1064
1065 bufferlist out_bl;
1066 int r = ioctx->operate(oid, &op, &out_bl);
1067 if (r < 0) {
1068 return r;
1069 }
1070
1071 auto it = out_bl.cbegin();
1072 return get_create_timestamp_finish(&it, timestamp);
1073}
1074
1075void get_access_timestamp_start(librados::ObjectReadOperation *op) {
1076 bufferlist empty_bl;
1077 op->exec("rbd", "get_access_timestamp", empty_bl);
1078}
1079
1080int get_access_timestamp_finish(bufferlist::const_iterator *it,
1081 utime_t *timestamp) {
1082 ceph_assert(timestamp);
1083
1084 try {
1085 decode(*timestamp, *it);
f67539c2 1086 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1087 return -EBADMSG;
1088 }
1089 return 0;
1090}
1091
1092int get_access_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1093 utime_t *timestamp)
1094{
1095 librados::ObjectReadOperation op;
1096 get_access_timestamp_start(&op);
1097
1098 bufferlist out_bl;
1099 int r = ioctx->operate(oid, &op, &out_bl);
1100 if (r < 0) {
1101 return r;
1102 }
1103
1104 auto it = out_bl.cbegin();
1105 return get_access_timestamp_finish(&it, timestamp);
1106}
1107
1108void set_access_timestamp(librados::ObjectWriteOperation *op)
1109{
1110 bufferlist empty_bl;
1111 op->exec("rbd","set_access_timestamp",empty_bl);
1112}
1113
1114int set_access_timestamp(librados::IoCtx *ioctx, const std::string &oid)
1115{
1116 librados::ObjectWriteOperation op;
1117 set_access_timestamp(&op);
1118 return ioctx->operate(oid, &op);
1119}
1120
1121void get_modify_timestamp_start(librados::ObjectReadOperation *op) {
1122 bufferlist empty_bl;
1123 op->exec("rbd", "get_modify_timestamp", empty_bl);
1124}
1125
1126int get_modify_timestamp_finish(bufferlist::const_iterator *it,
1127 utime_t *timestamp) {
1128 ceph_assert(timestamp);
1129
1130 try {
1131 decode(*timestamp, *it);
f67539c2 1132 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1133 return -EBADMSG;
1134 }
1135 return 0;
1136}
1137
1138int get_modify_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1139 utime_t *timestamp)
1140{
1141 librados::ObjectReadOperation op;
1142 get_modify_timestamp_start(&op);
1143
1144 bufferlist out_bl;
1145 int r = ioctx->operate(oid, &op, &out_bl);
1146 if (r < 0) {
1147 return r;
1148 }
1149
1150 auto it = out_bl.cbegin();
1151 return get_modify_timestamp_finish(&it, timestamp);
1152}
1153
1154void set_modify_timestamp(librados::ObjectWriteOperation *op)
1155{
1156 bufferlist empty_bl;
1157 op->exec("rbd","set_modify_timestamp",empty_bl);
1158}
1159
1160int set_modify_timestamp(librados::IoCtx *ioctx, const std::string &oid)
1161{
1162 librados::ObjectWriteOperation op;
1163 set_modify_timestamp(&op);
1164 return ioctx->operate(oid, &op);
1165}
1166
1167
1168/************************ rbd_id object methods ************************/
1169
1170void get_id_start(librados::ObjectReadOperation *op) {
1171 bufferlist empty_bl;
1172 op->exec("rbd", "get_id", empty_bl);
1173}
1174
1175int get_id_finish(bufferlist::const_iterator *it, std::string *id) {
1176 try {
1177 decode(*id, *it);
f67539c2 1178 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1179 return -EBADMSG;
1180 }
1181 return 0;
1182}
1183
1184int get_id(librados::IoCtx *ioctx, const std::string &oid, std::string *id)
1185{
1186 librados::ObjectReadOperation op;
1187 get_id_start(&op);
1188
1189 bufferlist out_bl;
1190 int r = ioctx->operate(oid, &op, &out_bl);
1191 if (r < 0) {
1192 return r;
1193 }
1194
1195 auto it = out_bl.cbegin();
1196 return get_id_finish(&it, id);
1197}
1198
1199void set_id(librados::ObjectWriteOperation *op, const std::string &id)
1200{
1201 bufferlist bl;
1202 encode(id, bl);
1203 op->exec("rbd", "set_id", bl);
1204}
1205
1206int set_id(librados::IoCtx *ioctx, const std::string &oid, const std::string &id)
1207{
1208 librados::ObjectWriteOperation op;
1209 set_id(&op, id);
1210
1211 return ioctx->operate(oid, &op);
1212}
1213
1214/******************** rbd_directory object methods ********************/
1215
1216void dir_get_id_start(librados::ObjectReadOperation *op,
1217 const std::string &image_name) {
1218 bufferlist bl;
1219 encode(image_name, bl);
1220
1221 op->exec("rbd", "dir_get_id", bl);
1222}
1223
1224int dir_get_id_finish(bufferlist::const_iterator *iter, std::string *image_id) {
1225 try {
1226 decode(*image_id, *iter);
f67539c2 1227 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1228 return -EBADMSG;
1229 }
1230
1231 return 0;
1232}
1233
1234int dir_get_id(librados::IoCtx *ioctx, const std::string &oid,
1235 const std::string &name, std::string *id) {
1236 librados::ObjectReadOperation op;
1237 dir_get_id_start(&op, name);
1238
1239 bufferlist out_bl;
1240 int r = ioctx->operate(oid, &op, &out_bl);
1241 if (r < 0) {
1242 return r;
1243 }
1244
1245 auto iter = out_bl.cbegin();
1246 return dir_get_id_finish(&iter, id);
1247}
1248
1249void dir_get_name_start(librados::ObjectReadOperation *op,
1250 const std::string &id) {
1251 bufferlist in_bl;
1252 encode(id, in_bl);
1253 op->exec("rbd", "dir_get_name", in_bl);
1254}
1255
1256int dir_get_name_finish(bufferlist::const_iterator *it, std::string *name) {
1257 try {
1258 decode(*name, *it);
f67539c2 1259 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1260 return -EBADMSG;
1261 }
1262 return 0;
1263}
1264
1265int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
1266 const std::string &id, std::string *name) {
1267 librados::ObjectReadOperation op;
1268 dir_get_name_start(&op, id);
1269
1270 bufferlist out_bl;
1271 int r = ioctx->operate(oid, &op, &out_bl);
1272 if (r < 0) {
1273 return r;
1274 }
1275
1276 auto it = out_bl.cbegin();
1277 return dir_get_name_finish(&it, name);
1278}
1279
1280void dir_list_start(librados::ObjectReadOperation *op,
1281 const std::string &start, uint64_t max_return)
1282{
1283 bufferlist in_bl;
1284 encode(start, in_bl);
1285 encode(max_return, in_bl);
1286
1287 op->exec("rbd", "dir_list", in_bl);
1288}
1289
1290int dir_list_finish(bufferlist::const_iterator *it, map<string, string> *images)
1291{
1292 try {
1293 decode(*images, *it);
f67539c2 1294 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1295 return -EBADMSG;
1296 }
1297 return 0;
1298}
1299
1300int dir_list(librados::IoCtx *ioctx, const std::string &oid,
1301 const std::string &start, uint64_t max_return,
1302 map<string, string> *images)
1303{
1304 librados::ObjectReadOperation op;
1305 dir_list_start(&op, start, max_return);
1306
1307 bufferlist out_bl;
1308 int r = ioctx->operate(oid, &op, &out_bl);
1309 if (r < 0) {
1310 return r;
1311 }
1312
1313 auto iter = out_bl.cbegin();
1314 return dir_list_finish(&iter, images);
1315}
1316
1317void dir_add_image(librados::ObjectWriteOperation *op,
1318 const std::string &name, const std::string &id)
1319{
1320 bufferlist bl;
1321 encode(name, bl);
1322 encode(id, bl);
1323 op->exec("rbd", "dir_add_image", bl);
1324}
1325
1326int dir_add_image(librados::IoCtx *ioctx, const std::string &oid,
1327 const std::string &name, const std::string &id)
1328{
1329 librados::ObjectWriteOperation op;
1330 dir_add_image(&op, name, id);
1331
1332 return ioctx->operate(oid, &op);
1333}
1334
1335int dir_remove_image(librados::IoCtx *ioctx, const std::string &oid,
1336 const std::string &name, const std::string &id)
1337{
1338 librados::ObjectWriteOperation op;
1339 dir_remove_image(&op, name, id);
1340
1341 return ioctx->operate(oid, &op);
1342}
1343
1344void dir_state_assert(librados::ObjectOperation *op,
1345 cls::rbd::DirectoryState directory_state)
1346{
1347 bufferlist bl;
1348 encode(directory_state, bl);
1349 op->exec("rbd", "dir_state_assert", bl);
1350}
1351
1352int dir_state_assert(librados::IoCtx *ioctx, const std::string &oid,
1353 cls::rbd::DirectoryState directory_state)
1354{
1355 librados::ObjectWriteOperation op;
1356 dir_state_assert(&op, directory_state);
1357
1358 return ioctx->operate(oid, &op);
1359}
1360
1361void dir_state_set(librados::ObjectWriteOperation *op,
1362 cls::rbd::DirectoryState directory_state)
1363{
1364 bufferlist bl;
1365 encode(directory_state, bl);
1366 op->exec("rbd", "dir_state_set", bl);
1367}
1368
1369int dir_state_set(librados::IoCtx *ioctx, const std::string &oid,
1370 cls::rbd::DirectoryState directory_state)
1371{
1372 librados::ObjectWriteOperation op;
1373 dir_state_set(&op, directory_state);
1374
1375 return ioctx->operate(oid, &op);
1376}
1377
1378void dir_remove_image(librados::ObjectWriteOperation *op,
1379 const std::string &name, const std::string &id)
1380{
1381 bufferlist bl;
1382 encode(name, bl);
1383 encode(id, bl);
1384
1385 op->exec("rbd", "dir_remove_image", bl);
1386}
1387
1388void dir_rename_image(librados::ObjectWriteOperation *op,
1389 const std::string &src, const std::string &dest,
1390 const std::string &id)
1391{
1392 bufferlist in;
1393 encode(src, in);
1394 encode(dest, in);
1395 encode(id, in);
1396 op->exec("rbd", "dir_rename_image", in);
1397}
1398
1399void object_map_load_start(librados::ObjectReadOperation *op) {
1400 bufferlist in_bl;
1401 op->exec("rbd", "object_map_load", in_bl);
1402}
1403
1404int object_map_load_finish(bufferlist::const_iterator *it,
1405 ceph::BitVector<2> *object_map) {
1406 try {
1407 decode(*object_map, *it);
f67539c2 1408 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1409 return -EBADMSG;
1410 }
1411 return 0;
1412}
1413
1414int object_map_load(librados::IoCtx *ioctx, const std::string &oid,
1415 ceph::BitVector<2> *object_map)
1416{
1417 librados::ObjectReadOperation op;
1418 object_map_load_start(&op);
1419
1420 bufferlist out_bl;
1421 int r = ioctx->operate(oid, &op, &out_bl);
1422 if (r < 0) {
1423 return r;
1424 }
1425
1426 auto it = out_bl.cbegin();
1427 return object_map_load_finish(&it, object_map);
1428}
1429
1430void object_map_save(librados::ObjectWriteOperation *rados_op,
1431 const ceph::BitVector<2> &object_map)
1432{
1433 ceph::BitVector<2> object_map_copy(object_map);
1434 object_map_copy.set_crc_enabled(false);
1435
1436 bufferlist in;
1437 encode(object_map_copy, in);
1438 rados_op->exec("rbd", "object_map_save", in);
1439}
1440
1441void object_map_resize(librados::ObjectWriteOperation *rados_op,
1442 uint64_t object_count, uint8_t default_state)
1443{
1444 bufferlist in;
1445 encode(object_count, in);
1446 encode(default_state, in);
1447 rados_op->exec("rbd", "object_map_resize", in);
1448}
1449
1450void object_map_update(librados::ObjectWriteOperation *rados_op,
1451 uint64_t start_object_no, uint64_t end_object_no,
1452 uint8_t new_object_state,
1453 const boost::optional<uint8_t> &current_object_state)
1454{
1455 bufferlist in;
1456 encode(start_object_no, in);
1457 encode(end_object_no, in);
1458 encode(new_object_state, in);
1459 encode(current_object_state, in);
1460 rados_op->exec("rbd", "object_map_update", in);
1461}
1462
1463void object_map_snap_add(librados::ObjectWriteOperation *rados_op)
1464{
1465 bufferlist in;
1466 rados_op->exec("rbd", "object_map_snap_add", in);
1467}
1468
1469void object_map_snap_remove(librados::ObjectWriteOperation *rados_op,
1470 const ceph::BitVector<2> &object_map)
1471{
1472 ceph::BitVector<2> object_map_copy(object_map);
1473 object_map_copy.set_crc_enabled(false);
1474
1475 bufferlist in;
1476 encode(object_map_copy, in);
1477 rados_op->exec("rbd", "object_map_snap_remove", in);
1478}
1479
1480void metadata_set(librados::ObjectWriteOperation *op,
1481 const map<string, bufferlist> &data)
1482{
1483 bufferlist bl;
1484 encode(data, bl);
1485
1486 op->exec("rbd", "metadata_set", bl);
1487}
1488
1489int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
1490 const map<string, bufferlist> &data)
1491{
1492 librados::ObjectWriteOperation op;
1493 metadata_set(&op, data);
1494
1495 return ioctx->operate(oid, &op);
1496}
1497
1498void metadata_remove(librados::ObjectWriteOperation *op,
7c673cae 1499 const std::string &key)
11fdf7f2
TL
1500{
1501 bufferlist bl;
1502 encode(key, bl);
1503
1504 op->exec("rbd", "metadata_remove", bl);
1505}
1506
1507int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
1508 const std::string &key)
1509{
1510 librados::ObjectWriteOperation op;
1511 metadata_remove(&op, key);
1512
1513 return ioctx->operate(oid, &op);
1514}
1515
1516int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
1517 const std::string &start, uint64_t max_return,
1518 map<string, bufferlist> *pairs)
1519{
1520 librados::ObjectReadOperation op;
1521 metadata_list_start(&op, start, max_return);
1522
1523 bufferlist out_bl;
1524 int r = ioctx->operate(oid, &op, &out_bl);
1525 if (r < 0) {
1526 return r;
1527 }
1528
1529 auto it = out_bl.cbegin();
1530 return metadata_list_finish(&it, pairs);
1531}
1532
1533void metadata_list_start(librados::ObjectReadOperation *op,
1534 const std::string &start, uint64_t max_return)
1535{
1536 bufferlist in_bl;
1537 encode(start, in_bl);
1538 encode(max_return, in_bl);
1539 op->exec("rbd", "metadata_list", in_bl);
1540}
1541
1542int metadata_list_finish(bufferlist::const_iterator *it,
1543 std::map<std::string, bufferlist> *pairs)
1544{
1545 ceph_assert(pairs);
1546 try {
1547 decode(*pairs, *it);
f67539c2 1548 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1549 return -EBADMSG;
1550 }
1551 return 0;
1552}
1553
9f95a23c
TL
1554void metadata_get_start(librados::ObjectReadOperation* op,
1555 const std::string &key) {
1556 bufferlist bl;
1557 encode(key, bl);
1558
1559 op->exec("rbd", "metadata_get", bl);
1560}
1561
1562int metadata_get_finish(bufferlist::const_iterator *it,
1563 std::string* value) {
1564 try {
1565 decode(*value, *it);
f67539c2 1566 } catch (const ceph::buffer::error &err) {
9f95a23c
TL
1567 return -EBADMSG;
1568 }
1569 return 0;
1570}
1571
11fdf7f2
TL
1572int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
1573 const std::string &key, string *s)
1574{
1575 ceph_assert(s);
9f95a23c
TL
1576 librados::ObjectReadOperation op;
1577 metadata_get_start(&op, key);
11fdf7f2 1578
9f95a23c
TL
1579 bufferlist out_bl;
1580 int r = ioctx->operate(oid, &op, &out_bl);
1581 if (r < 0) {
1582 return r;
11fdf7f2
TL
1583 }
1584
9f95a23c
TL
1585 auto it = out_bl.cbegin();
1586 r = metadata_get_finish(&it, s);
1587 if (r < 0) {
1588 return r;
1589 }
11fdf7f2
TL
1590 return 0;
1591}
1592
1593void child_attach(librados::ObjectWriteOperation *op, snapid_t snap_id,
1594 const cls::rbd::ChildImageSpec& child_image)
1595{
1596 bufferlist bl;
1597 encode(snap_id, bl);
1598 encode(child_image, bl);
1599 op->exec("rbd", "child_attach", bl);
1600}
1601
1602int child_attach(librados::IoCtx *ioctx, const std::string &oid,
1603 snapid_t snap_id,
1604 const cls::rbd::ChildImageSpec& child_image)
1605{
1606 librados::ObjectWriteOperation op;
1607 child_attach(&op, snap_id, child_image);
1608
1609 int r = ioctx->operate(oid, &op);
1610 if (r < 0) {
1611 return r;
1612 }
1613 return 0;
1614}
1615
1616void child_detach(librados::ObjectWriteOperation *op, snapid_t snap_id,
1617 const cls::rbd::ChildImageSpec& child_image)
1618{
1619 bufferlist bl;
1620 encode(snap_id, bl);
1621 encode(child_image, bl);
1622 op->exec("rbd", "child_detach", bl);
1623}
1624
1625int child_detach(librados::IoCtx *ioctx, const std::string &oid,
1626 snapid_t snap_id,
1627 const cls::rbd::ChildImageSpec& child_image)
1628{
1629 librados::ObjectWriteOperation op;
1630 child_detach(&op, snap_id, child_image);
1631
1632 int r = ioctx->operate(oid, &op);
1633 if (r < 0) {
1634 return r;
1635 }
1636 return 0;
1637}
1638
1639void children_list_start(librados::ObjectReadOperation *op,
1640 snapid_t snap_id)
1641{
1642 bufferlist bl;
1643 encode(snap_id, bl);
1644 op->exec("rbd", "children_list", bl);
1645}
1646
1647int children_list_finish(bufferlist::const_iterator *it,
1648 cls::rbd::ChildImageSpecs *child_images)
1649{
1650 child_images->clear();
1651 try {
1652 decode(*child_images, *it);
f67539c2 1653 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1654 return -EBADMSG;
1655 }
1656 return 0;
1657}
1658
1659int children_list(librados::IoCtx *ioctx, const std::string &oid,
1660 snapid_t snap_id,
1661 cls::rbd::ChildImageSpecs *child_images)
1662{
1663 librados::ObjectReadOperation op;
1664 children_list_start(&op, snap_id);
1665
1666 bufferlist out_bl;
1667 int r = ioctx->operate(oid, &op, &out_bl);
1668 if (r < 0) {
1669 return r;
1670 }
1671
1672 auto it = out_bl.cbegin();
1673 r = children_list_finish(&it, child_images);
1674 if (r < 0) {
1675 return r;
1676 }
1677 return 0;
1678}
1679
1680int migration_set(librados::IoCtx *ioctx, const std::string &oid,
1681 const cls::rbd::MigrationSpec &migration_spec) {
1682 librados::ObjectWriteOperation op;
1683 migration_set(&op, migration_spec);
1684 return ioctx->operate(oid, &op);
1685}
1686
1687void migration_set(librados::ObjectWriteOperation *op,
1688 const cls::rbd::MigrationSpec &migration_spec) {
1689 bufferlist bl;
1690 encode(migration_spec, bl);
1691 op->exec("rbd", "migration_set", bl);
1692}
1693
1694int migration_set_state(librados::IoCtx *ioctx, const std::string &oid,
1695 cls::rbd::MigrationState state,
1696 const std::string &description) {
1697 librados::ObjectWriteOperation op;
1698 migration_set_state(&op, state, description);
1699 return ioctx->operate(oid, &op);
1700}
1701
1702void migration_set_state(librados::ObjectWriteOperation *op,
1703 cls::rbd::MigrationState state,
1704 const std::string &description) {
1705 bufferlist bl;
1706 encode(state, bl);
1707 encode(description, bl);
1708 op->exec("rbd", "migration_set_state", bl);
1709}
1710
1711void migration_get_start(librados::ObjectReadOperation *op) {
1712 bufferlist bl;
1713 op->exec("rbd", "migration_get", bl);
1714}
1715
1716int migration_get_finish(bufferlist::const_iterator *it,
1717 cls::rbd::MigrationSpec *migration_spec) {
1718 try {
1719 decode(*migration_spec, *it);
f67539c2 1720 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1721 return -EBADMSG;
1722 }
1723 return 0;
1724}
1725
1726int migration_get(librados::IoCtx *ioctx, const std::string &oid,
1727 cls::rbd::MigrationSpec *migration_spec) {
1728 librados::ObjectReadOperation op;
1729 migration_get_start(&op);
1730
1731 bufferlist out_bl;
1732 int r = ioctx->operate(oid, &op, &out_bl);
1733 if (r < 0) {
1734 return r;
1735 }
1736
1737 auto iter = out_bl.cbegin();
1738 r = migration_get_finish(&iter, migration_spec);
1739 if (r < 0) {
1740 return r;
1741 }
1742 return 0;
1743}
1744
1745int migration_remove(librados::IoCtx *ioctx, const std::string &oid) {
1746 librados::ObjectWriteOperation op;
1747 migration_remove(&op);
1748 return ioctx->operate(oid, &op);
1749}
1750
1751void migration_remove(librados::ObjectWriteOperation *op) {
1752 bufferlist bl;
1753 op->exec("rbd", "migration_remove", bl);
1754}
1755
f67539c2
TL
1756template <typename O>
1757void assert_snapc_seq(O* op, uint64_t snapc_seq,
1758 cls::rbd::AssertSnapcSeqState state) {
1759 bufferlist bl;
1760 encode(snapc_seq, bl);
1761 encode(state, bl);
1762 op->exec("rbd", "assert_snapc_seq", bl);
1763}
1764
1765void assert_snapc_seq(neorados::WriteOp* op,
1766 uint64_t snapc_seq,
1767 cls::rbd::AssertSnapcSeqState state) {
1768 assert_snapc_seq<neorados::WriteOp>(op, snapc_seq, state);
1769}
1770
1771void assert_snapc_seq(librados::ObjectWriteOperation *op,
1772 uint64_t snapc_seq,
1773 cls::rbd::AssertSnapcSeqState state) {
1774 assert_snapc_seq<librados::ObjectWriteOperation>(op, snapc_seq, state);
1775}
1776
11fdf7f2
TL
1777int assert_snapc_seq(librados::IoCtx *ioctx, const std::string &oid,
1778 uint64_t snapc_seq,
1779 cls::rbd::AssertSnapcSeqState state) {
1780 librados::ObjectWriteOperation op;
1781 assert_snapc_seq(&op, snapc_seq, state);
1782 return ioctx->operate(oid, &op);
1783}
1784
11fdf7f2
TL
1785void mirror_uuid_get_start(librados::ObjectReadOperation *op) {
1786 bufferlist bl;
1787 op->exec("rbd", "mirror_uuid_get", bl);
1788}
1789
1790int mirror_uuid_get_finish(bufferlist::const_iterator *it,
1791 std::string *uuid) {
1792 try {
1793 decode(*uuid, *it);
f67539c2 1794 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1795 return -EBADMSG;
1796 }
1797 return 0;
1798}
1799
1800int mirror_uuid_get(librados::IoCtx *ioctx, std::string *uuid) {
1801 librados::ObjectReadOperation op;
1802 mirror_uuid_get_start(&op);
1803
1804 bufferlist out_bl;
1805 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1806 if (r < 0) {
1807 return r;
1808 }
1809
1810 auto it = out_bl.cbegin();
1811 r = mirror_uuid_get_finish(&it, uuid);
1812 if (r < 0) {
1813 return r;
1814 }
1815 return 0;
1816}
1817
1818int mirror_uuid_set(librados::IoCtx *ioctx, const std::string &uuid) {
1819 bufferlist in_bl;
1820 encode(uuid, in_bl);
1821
1822 bufferlist out_bl;
1823 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_uuid_set", in_bl,
1824 out_bl);
1825 if (r < 0) {
1826 return r;
1827 }
1828 return 0;
1829}
1830
1831void mirror_mode_get_start(librados::ObjectReadOperation *op) {
1832 bufferlist bl;
1833 op->exec("rbd", "mirror_mode_get", bl);
1834}
1835
1836int mirror_mode_get_finish(bufferlist::const_iterator *it,
1837 cls::rbd::MirrorMode *mirror_mode) {
1838 try {
1839 uint32_t mirror_mode_decode;
1840 decode(mirror_mode_decode, *it);
1841 *mirror_mode = static_cast<cls::rbd::MirrorMode>(mirror_mode_decode);
f67539c2 1842 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
1843 return -EBADMSG;
1844 }
1845
1846 return 0;
1847}
1848
1849int mirror_mode_get(librados::IoCtx *ioctx,
1850 cls::rbd::MirrorMode *mirror_mode) {
1851 librados::ObjectReadOperation op;
1852 mirror_mode_get_start(&op);
1853
1854 bufferlist out_bl;
1855 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1856 if (r == -ENOENT) {
1857 *mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
1858 return 0;
1859 } else if (r < 0) {
1860 return r;
1861 }
1862
1863 auto it = out_bl.cbegin();
1864 r = mirror_mode_get_finish(&it, mirror_mode);
1865 if (r < 0) {
1866 return r;
1867 }
1868 return 0;
1869}
1870
1871int mirror_mode_set(librados::IoCtx *ioctx,
1872 cls::rbd::MirrorMode mirror_mode) {
1873 bufferlist in_bl;
1874 encode(static_cast<uint32_t>(mirror_mode), in_bl);
1875
1876 bufferlist out_bl;
1877 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_mode_set", in_bl,
1878 out_bl);
1879 if (r < 0) {
1880 return r;
1881 }
1882 return 0;
1883}
1884
9f95a23c
TL
1885void mirror_peer_list_start(librados::ObjectReadOperation *op) {
1886 bufferlist bl;
1887 op->exec("rbd", "mirror_peer_list", bl);
1888}
1889
1890int mirror_peer_list_finish(bufferlist::const_iterator *it,
1891 std::vector<cls::rbd::MirrorPeer> *peers) {
1892 peers->clear();
1893 try {
1894 decode(*peers, *it);
f67539c2 1895 } catch (const ceph::buffer::error &err) {
9f95a23c
TL
1896 return -EBADMSG;
1897 }
1898 return 0;
1899}
1900
11fdf7f2
TL
1901int mirror_peer_list(librados::IoCtx *ioctx,
1902 std::vector<cls::rbd::MirrorPeer> *peers) {
9f95a23c
TL
1903 librados::ObjectReadOperation op;
1904 mirror_peer_list_start(&op);
1905
11fdf7f2 1906 bufferlist out_bl;
9f95a23c 1907 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
11fdf7f2
TL
1908 if (r < 0) {
1909 return r;
1910 }
1911
9f95a23c
TL
1912 auto it = out_bl.cbegin();
1913 r = mirror_peer_list_finish(&it, peers);
1914 if (r < 0) {
1915 return r;
11fdf7f2
TL
1916 }
1917 return 0;
1918}
1919
9f95a23c
TL
1920int mirror_peer_ping(librados::IoCtx *ioctx,
1921 const std::string& site_name,
1922 const std::string& fsid) {
1923 librados::ObjectWriteOperation op;
1924 mirror_peer_ping(&op, site_name, fsid);
1925
1926 int r = ioctx->operate(RBD_MIRRORING, &op);
1927 if (r < 0) {
1928 return r;
1929 }
1930
1931 return 0;
1932}
1933
1934void mirror_peer_ping(librados::ObjectWriteOperation *op,
1935 const std::string& site_name,
1936 const std::string& fsid) {
11fdf7f2 1937 bufferlist in_bl;
9f95a23c
TL
1938 encode(site_name, in_bl);
1939 encode(fsid, in_bl);
1940 encode(static_cast<uint8_t>(cls::rbd::MIRROR_PEER_DIRECTION_TX), in_bl);
11fdf7f2 1941
9f95a23c
TL
1942 op->exec("rbd", "mirror_peer_ping", in_bl);
1943}
1944
1945int mirror_peer_add(librados::IoCtx *ioctx,
1946 const cls::rbd::MirrorPeer& mirror_peer) {
1947 librados::ObjectWriteOperation op;
1948 mirror_peer_add(&op, mirror_peer);
1949
1950 int r = ioctx->operate(RBD_MIRRORING, &op);
11fdf7f2
TL
1951 if (r < 0) {
1952 return r;
1953 }
9f95a23c 1954
11fdf7f2
TL
1955 return 0;
1956}
1957
9f95a23c
TL
1958void mirror_peer_add(librados::ObjectWriteOperation *op,
1959 const cls::rbd::MirrorPeer& mirror_peer) {
1960 bufferlist in_bl;
1961 encode(mirror_peer, in_bl);
1962
1963 op->exec("rbd", "mirror_peer_add", in_bl);
1964}
1965
11fdf7f2
TL
1966int mirror_peer_remove(librados::IoCtx *ioctx,
1967 const std::string &uuid) {
1968 bufferlist in_bl;
1969 encode(uuid, in_bl);
1970
1971 bufferlist out_bl;
1972 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_remove", in_bl,
1973 out_bl);
1974 if (r < 0) {
1975 return r;
1976 }
1977 return 0;
1978}
1979
1980int mirror_peer_set_client(librados::IoCtx *ioctx,
1981 const std::string &uuid,
1982 const std::string &client_name) {
1983 bufferlist in_bl;
1984 encode(uuid, in_bl);
1985 encode(client_name, in_bl);
1986
1987 bufferlist out_bl;
1988 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_client",
1989 in_bl, out_bl);
1990 if (r < 0) {
1991 return r;
1992 }
1993 return 0;
1994}
1995
1996int mirror_peer_set_cluster(librados::IoCtx *ioctx,
1997 const std::string &uuid,
1998 const std::string &cluster_name) {
1999 bufferlist in_bl;
2000 encode(uuid, in_bl);
2001 encode(cluster_name, in_bl);
2002
2003 bufferlist out_bl;
2004 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_cluster",
2005 in_bl, out_bl);
2006 if (r < 0) {
2007 return r;
2008 }
2009 return 0;
2010}
2011
9f95a23c
TL
2012int mirror_peer_set_direction(
2013 librados::IoCtx *ioctx, const std::string &uuid,
2014 cls::rbd::MirrorPeerDirection mirror_peer_direction) {
2015 bufferlist in_bl;
2016 encode(uuid, in_bl);
2017 encode(static_cast<uint8_t>(mirror_peer_direction), in_bl);
2018
2019 bufferlist out_bl;
2020 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_direction",
2021 in_bl, out_bl);
2022 if (r < 0) {
2023 return r;
2024 }
2025 return 0;
2026}
2027
11fdf7f2 2028void mirror_image_list_start(librados::ObjectReadOperation *op,
7c673cae 2029 const std::string &start, uint64_t max_return)
11fdf7f2
TL
2030{
2031 bufferlist in_bl;
2032 encode(start, in_bl);
2033 encode(max_return, in_bl);
2034 op->exec("rbd", "mirror_image_list", in_bl);
2035}
2036
2037int mirror_image_list_finish(bufferlist::const_iterator *it,
2038 std::map<string, string> *mirror_image_ids)
2039{
2040 try {
2041 decode(*mirror_image_ids, *it);
f67539c2 2042 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2043 return -EBADMSG;
2044 }
2045 return 0;
2046}
2047
2048int mirror_image_list(librados::IoCtx *ioctx,
2049 const std::string &start, uint64_t max_return,
2050 std::map<std::string, std::string> *mirror_image_ids) {
2051 librados::ObjectReadOperation op;
2052 mirror_image_list_start(&op, start, max_return);
2053
2054 bufferlist out_bl;
2055 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2056 if (r < 0) {
2057 return r;
2058 }
2059
2060 auto bl_it = out_bl.cbegin();
2061 return mirror_image_list_finish(&bl_it, mirror_image_ids);
2062}
2063
2064void mirror_image_get_image_id_start(librados::ObjectReadOperation *op,
2065 const std::string &global_image_id) {
2066 bufferlist in_bl;
2067 encode(global_image_id, in_bl);
2068 op->exec( "rbd", "mirror_image_get_image_id", in_bl);
2069}
2070
2071int mirror_image_get_image_id_finish(bufferlist::const_iterator *it,
2072 std::string *image_id) {
2073 try {
2074 decode(*image_id, *it);
f67539c2 2075 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2076 return -EBADMSG;
2077 }
2078 return 0;
2079}
2080
2081int mirror_image_get_image_id(librados::IoCtx *ioctx,
2082 const std::string &global_image_id,
2083 std::string *image_id) {
2084 librados::ObjectReadOperation op;
2085 mirror_image_get_image_id_start(&op, global_image_id);
2086
2087 bufferlist out_bl;
2088 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2089 if (r < 0) {
2090 return r;
2091 }
2092
2093 auto it = out_bl.cbegin();
2094 return mirror_image_get_image_id_finish(&it, image_id);
2095}
2096
2097int mirror_image_get(librados::IoCtx *ioctx, const std::string &image_id,
2098 cls::rbd::MirrorImage *mirror_image) {
2099 librados::ObjectReadOperation op;
2100 mirror_image_get_start(&op, image_id);
2101
2102 bufferlist out_bl;
2103 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2104 if (r < 0) {
2105 return r;
2106 }
2107
2108 auto iter = out_bl.cbegin();
2109 r = mirror_image_get_finish(&iter, mirror_image);
2110 if (r < 0) {
2111 return r;
2112 }
2113 return 0;
2114}
2115
2116void mirror_image_get_start(librados::ObjectReadOperation *op,
2117 const std::string &image_id) {
2118 bufferlist in_bl;
2119 encode(image_id, in_bl);
2120
2121 op->exec("rbd", "mirror_image_get", in_bl);
2122}
2123
2124int mirror_image_get_finish(bufferlist::const_iterator *iter,
2125 cls::rbd::MirrorImage *mirror_image) {
2126 try {
2127 decode(*mirror_image, *iter);
f67539c2 2128 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2129 return -EBADMSG;
2130 }
2131 return 0;
2132}
2133
2134void mirror_image_set(librados::ObjectWriteOperation *op,
2135 const std::string &image_id,
2136 const cls::rbd::MirrorImage &mirror_image) {
2137 bufferlist bl;
2138 encode(image_id, bl);
2139 encode(mirror_image, bl);
2140
2141 op->exec("rbd", "mirror_image_set", bl);
2142}
2143
2144int mirror_image_set(librados::IoCtx *ioctx, const std::string &image_id,
2145 const cls::rbd::MirrorImage &mirror_image) {
2146 librados::ObjectWriteOperation op;
2147 mirror_image_set(&op, image_id, mirror_image);
2148
2149 int r = ioctx->operate(RBD_MIRRORING, &op);
2150 if (r < 0) {
2151 return r;
2152 }
2153 return 0;
2154}
2155
2156void mirror_image_remove(librados::ObjectWriteOperation *op,
2157 const std::string &image_id) {
2158 bufferlist bl;
2159 encode(image_id, bl);
2160
2161 op->exec("rbd", "mirror_image_remove", bl);
2162}
2163
2164int mirror_image_remove(librados::IoCtx *ioctx, const std::string &image_id) {
2165 librados::ObjectWriteOperation op;
2166 mirror_image_remove(&op, image_id);
2167
2168 int r = ioctx->operate(RBD_MIRRORING, &op);
2169 if (r < 0) {
2170 return r;
2171 }
2172 return 0;
2173}
2174
2175int mirror_image_status_set(librados::IoCtx *ioctx,
2176 const std::string &global_image_id,
9f95a23c 2177 const cls::rbd::MirrorImageSiteStatus &status) {
11fdf7f2
TL
2178 librados::ObjectWriteOperation op;
2179 mirror_image_status_set(&op, global_image_id, status);
2180 return ioctx->operate(RBD_MIRRORING, &op);
2181}
2182
2183void mirror_image_status_set(librados::ObjectWriteOperation *op,
2184 const std::string &global_image_id,
9f95a23c 2185 const cls::rbd::MirrorImageSiteStatus &status) {
11fdf7f2
TL
2186 bufferlist bl;
2187 encode(global_image_id, bl);
2188 encode(status, bl);
2189 op->exec("rbd", "mirror_image_status_set", bl);
2190}
2191
11fdf7f2
TL
2192int mirror_image_status_get(librados::IoCtx *ioctx,
2193 const std::string &global_image_id,
2194 cls::rbd::MirrorImageStatus *status) {
2195 librados::ObjectReadOperation op;
2196 mirror_image_status_get_start(&op, global_image_id);
2197
2198 bufferlist out_bl;
2199 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2200 if (r < 0) {
2201 return r;
2202 }
2203
2204 auto iter = out_bl.cbegin();
2205 r = mirror_image_status_get_finish(&iter, status);
2206 if (r < 0) {
2207 return r;
2208 }
2209 return 0;
2210}
2211
2212void mirror_image_status_get_start(librados::ObjectReadOperation *op,
2213 const std::string &global_image_id) {
2214 bufferlist bl;
2215 encode(global_image_id, bl);
2216 op->exec("rbd", "mirror_image_status_get", bl);
2217}
2218
2219int mirror_image_status_get_finish(bufferlist::const_iterator *iter,
2220 cls::rbd::MirrorImageStatus *status) {
2221 try {
2222 decode(*status, *iter);
f67539c2 2223 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2224 return -EBADMSG;
2225 }
2226 return 0;
2227}
2228
2229int mirror_image_status_list(librados::IoCtx *ioctx,
2230 const std::string &start, uint64_t max_return,
2231 std::map<std::string, cls::rbd::MirrorImage> *images,
2232 std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
2233 librados::ObjectReadOperation op;
2234 mirror_image_status_list_start(&op, start, max_return);
2235
2236 bufferlist out_bl;
2237 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2238 if (r < 0) {
2239 return r;
2240 }
2241
2242 auto iter = out_bl.cbegin();
2243 r = mirror_image_status_list_finish(&iter, images, statuses);
2244 if (r < 0) {
2245 return r;
2246 }
2247 return 0;
2248}
2249
2250void mirror_image_status_list_start(librados::ObjectReadOperation *op,
2251 const std::string &start,
2252 uint64_t max_return) {
2253 bufferlist bl;
2254 encode(start, bl);
2255 encode(max_return, bl);
2256 op->exec("rbd", "mirror_image_status_list", bl);
2257}
2258
2259int mirror_image_status_list_finish(bufferlist::const_iterator *iter,
2260 std::map<std::string, cls::rbd::MirrorImage> *images,
2261 std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
2262 images->clear();
2263 statuses->clear();
2264 try {
2265 decode(*images, *iter);
2266 decode(*statuses, *iter);
f67539c2 2267 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2268 return -EBADMSG;
2269 }
2270 return 0;
2271}
2272
9f95a23c
TL
2273int mirror_image_status_get_summary(
2274 librados::IoCtx *ioctx,
2275 const std::vector<cls::rbd::MirrorPeer>& mirror_peer_sites,
f67539c2 2276 std::map<cls::rbd::MirrorImageStatusState, int32_t> *states) {
11fdf7f2 2277 librados::ObjectReadOperation op;
9f95a23c 2278 mirror_image_status_get_summary_start(&op, mirror_peer_sites);
11fdf7f2
TL
2279
2280 bufferlist out_bl;
2281 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2282 if (r < 0) {
2283 return r;
2284 }
2285
2286 auto iter = out_bl.cbegin();
2287 r = mirror_image_status_get_summary_finish(&iter, states);
2288 if (r < 0) {
2289 return r;
2290 }
2291 return 0;
2292}
2293
9f95a23c
TL
2294void mirror_image_status_get_summary_start(
2295 librados::ObjectReadOperation *op,
2296 const std::vector<cls::rbd::MirrorPeer>& mirror_peer_sites) {
11fdf7f2 2297 bufferlist bl;
9f95a23c 2298 encode(mirror_peer_sites, bl);
11fdf7f2
TL
2299 op->exec("rbd", "mirror_image_status_get_summary", bl);
2300}
2301
9f95a23c
TL
2302int mirror_image_status_get_summary_finish(
2303 bufferlist::const_iterator *iter,
f67539c2 2304 std::map<cls::rbd::MirrorImageStatusState, int32_t> *states) {
11fdf7f2
TL
2305 try {
2306 decode(*states, *iter);
f67539c2 2307 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2308 return -EBADMSG;
2309 }
2310 return 0;
2311}
2312
a4b75251
TL
2313int mirror_image_status_remove(librados::IoCtx *ioctx,
2314 const std::string &global_image_id) {
2315 librados::ObjectWriteOperation op;
2316 mirror_image_status_remove(&op, global_image_id);
2317 return ioctx->operate(RBD_MIRRORING, &op);
2318}
2319
2320void mirror_image_status_remove(librados::ObjectWriteOperation *op,
2321 const std::string &global_image_id) {
2322 bufferlist bl;
2323 encode(global_image_id, bl);
2324 op->exec("rbd", "mirror_image_status_remove", bl);
2325}
2326
11fdf7f2
TL
2327int mirror_image_status_remove_down(librados::IoCtx *ioctx) {
2328 librados::ObjectWriteOperation op;
2329 mirror_image_status_remove_down(&op);
2330 return ioctx->operate(RBD_MIRRORING, &op);
2331}
2332
2333void mirror_image_status_remove_down(librados::ObjectWriteOperation *op) {
2334 bufferlist bl;
2335 op->exec("rbd", "mirror_image_status_remove_down", bl);
2336}
2337
2338int mirror_image_instance_get(librados::IoCtx *ioctx,
2339 const std::string &global_image_id,
2340 entity_inst_t *instance) {
2341 librados::ObjectReadOperation op;
2342 mirror_image_instance_get_start(&op, global_image_id);
2343
2344 bufferlist out_bl;
2345 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2346 if (r < 0) {
2347 return r;
2348 }
2349
2350 auto iter = out_bl.cbegin();
2351 r = mirror_image_instance_get_finish(&iter, instance);
2352 if (r < 0) {
2353 return r;
2354 }
2355 return 0;
2356}
2357
2358void mirror_image_instance_get_start(librados::ObjectReadOperation *op,
2359 const std::string &global_image_id) {
2360 bufferlist bl;
2361 encode(global_image_id, bl);
2362 op->exec("rbd", "mirror_image_instance_get", bl);
2363}
2364
2365int mirror_image_instance_get_finish(bufferlist::const_iterator *iter,
2366 entity_inst_t *instance) {
2367 try {
2368 decode(*instance, *iter);
f67539c2 2369 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2370 return -EBADMSG;
2371 }
2372 return 0;
2373}
2374
2375int mirror_image_instance_list(
2376 librados::IoCtx *ioctx, const std::string &start, uint64_t max_return,
2377 std::map<std::string, entity_inst_t> *instances) {
2378 librados::ObjectReadOperation op;
2379 mirror_image_instance_list_start(&op, start, max_return);
2380
2381 bufferlist out_bl;
2382 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2383 if (r < 0) {
2384 return r;
2385 }
2386
2387 auto iter = out_bl.cbegin();
2388 r = mirror_image_instance_list_finish(&iter, instances);
2389 if (r < 0) {
2390 return r;
2391 }
2392 return 0;
2393}
2394
2395void mirror_image_instance_list_start(librados::ObjectReadOperation *op,
2396 const std::string &start,
2397 uint64_t max_return) {
2398 bufferlist bl;
2399 encode(start, bl);
2400 encode(max_return, bl);
2401 op->exec("rbd", "mirror_image_instance_list", bl);
2402}
2403
2404int mirror_image_instance_list_finish(
2405 bufferlist::const_iterator *iter,
2406 std::map<std::string, entity_inst_t> *instances) {
2407 instances->clear();
2408 try {
2409 decode(*instances, *iter);
f67539c2 2410 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2411 return -EBADMSG;
2412 }
2413 return 0;
2414}
2415
2416void mirror_instances_list_start(librados::ObjectReadOperation *op) {
2417 bufferlist bl;
2418 op->exec("rbd", "mirror_instances_list", bl);
2419}
2420
2421int mirror_instances_list_finish(bufferlist::const_iterator *iter,
2422 std::vector<std::string> *instance_ids) {
2423 instance_ids->clear();
2424 try {
2425 decode(*instance_ids, *iter);
f67539c2 2426 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2427 return -EBADMSG;
2428 }
2429 return 0;
2430}
2431
2432int mirror_instances_list(librados::IoCtx *ioctx,
2433 std::vector<std::string> *instance_ids) {
2434 librados::ObjectReadOperation op;
2435 mirror_instances_list_start(&op);
2436
2437 bufferlist out_bl;
2438 int r = ioctx->operate(RBD_MIRROR_LEADER, &op, &out_bl);
2439 if (r < 0) {
2440 return r;
2441 }
2442
2443 auto iter = out_bl.cbegin();
2444 r = mirror_instances_list_finish(&iter, instance_ids);
2445 if (r < 0) {
2446 return r;
2447 }
2448 return 0;
2449}
2450
2451void mirror_instances_add(librados::ObjectWriteOperation *op,
2452 const std::string &instance_id) {
2453 bufferlist bl;
2454 encode(instance_id, bl);
2455 op->exec("rbd", "mirror_instances_add", bl);
2456}
2457
2458int mirror_instances_add(librados::IoCtx *ioctx,
2459 const std::string &instance_id) {
2460 librados::ObjectWriteOperation op;
2461 mirror_instances_add(&op, instance_id);
2462 return ioctx->operate(RBD_MIRROR_LEADER, &op);
2463}
2464
2465void mirror_instances_remove(librados::ObjectWriteOperation *op,
7c673cae 2466 const std::string &instance_id) {
11fdf7f2
TL
2467 bufferlist bl;
2468 encode(instance_id, bl);
2469 op->exec("rbd", "mirror_instances_remove", bl);
2470}
2471
2472int mirror_instances_remove(librados::IoCtx *ioctx,
2473 const std::string &instance_id) {
2474 librados::ObjectWriteOperation op;
2475 mirror_instances_remove(&op, instance_id);
2476 return ioctx->operate(RBD_MIRROR_LEADER, &op);
2477}
2478
2479void mirror_image_map_list_start(librados::ObjectReadOperation *op,
2480 const std::string &start_after,
2481 uint64_t max_read) {
2482 bufferlist bl;
2483 encode(start_after, bl);
2484 encode(max_read, bl);
2485
2486 op->exec("rbd", "mirror_image_map_list", bl);
2487}
2488
2489int mirror_image_map_list_finish(bufferlist::const_iterator *iter,
2490 std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping) {
2491 try {
2492 decode(*image_mapping, *iter);
f67539c2 2493 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2494 return -EBADMSG;
2495 }
2496 return 0;
2497}
2498
2499int mirror_image_map_list(
2500 librados::IoCtx *ioctx, const std::string &start_after,
2501 uint64_t max_read,
2502 std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping) {
2503 librados::ObjectReadOperation op;
2504 mirror_image_map_list_start(&op, start_after, max_read);
2505
2506 bufferlist out_bl;
2507 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2508 if (r < 0) {
2509 return r;
2510 }
2511
2512 auto iter = out_bl.cbegin();
2513 return mirror_image_map_list_finish(&iter, image_mapping);
2514}
2515
2516void mirror_image_map_update(librados::ObjectWriteOperation *op,
2517 const std::string &global_image_id,
2518 const cls::rbd::MirrorImageMap &image_map) {
2519 bufferlist bl;
2520 encode(global_image_id, bl);
2521 encode(image_map, bl);
2522
2523 op->exec("rbd", "mirror_image_map_update", bl);
2524}
2525
2526void mirror_image_map_remove(librados::ObjectWriteOperation *op,
2527 const std::string &global_image_id) {
2528 bufferlist bl;
2529 encode(global_image_id, bl);
2530
2531 op->exec("rbd", "mirror_image_map_remove", bl);
2532}
2533
9f95a23c
TL
2534void mirror_image_snapshot_unlink_peer(librados::ObjectWriteOperation *op,
2535 snapid_t snap_id,
2536 const std::string &mirror_peer_uuid) {
2537 bufferlist bl;
2538 encode(snap_id, bl);
2539 encode(mirror_peer_uuid, bl);
2540
2541 op->exec("rbd", "mirror_image_snapshot_unlink_peer", bl);
2542}
2543
2544int mirror_image_snapshot_unlink_peer(librados::IoCtx *ioctx,
2545 const std::string &oid,
2546 snapid_t snap_id,
2547 const std::string &mirror_peer_uuid) {
2548 librados::ObjectWriteOperation op;
2549 mirror_image_snapshot_unlink_peer(&op, snap_id, mirror_peer_uuid);
2550 return ioctx->operate(oid, &op);
2551}
2552
2553void mirror_image_snapshot_set_copy_progress(librados::ObjectWriteOperation *op,
2554 snapid_t snap_id, bool complete,
2555 uint64_t copy_progress) {
2556 bufferlist bl;
2557 encode(snap_id, bl);
2558 encode(complete, bl);
2559 encode(copy_progress, bl);
2560
2561 op->exec("rbd", "mirror_image_snapshot_set_copy_progress", bl);
2562}
2563
2564int mirror_image_snapshot_set_copy_progress(librados::IoCtx *ioctx,
2565 const std::string &oid,
2566 snapid_t snap_id, bool complete,
2567 uint64_t copy_progress) {
2568 librados::ObjectWriteOperation op;
2569 mirror_image_snapshot_set_copy_progress(&op, snap_id, complete,
2570 copy_progress);
2571 return ioctx->operate(oid, &op);
2572}
2573
11fdf7f2
TL
2574// Groups functions
2575int group_dir_list(librados::IoCtx *ioctx, const std::string &oid,
2576 const std::string &start, uint64_t max_return,
2577 map<string, string> *cgs)
2578{
2579 bufferlist in, out;
2580 encode(start, in);
2581 encode(max_return, in);
2582 int r = ioctx->exec(oid, "rbd", "group_dir_list", in, out);
2583 if (r < 0)
2584 return r;
2585
2586 auto iter = out.cbegin();
2587 try {
2588 decode(*cgs, iter);
f67539c2 2589 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2590 return -EBADMSG;
2591 }
2592
2593 return 0;
2594}
2595
2596int group_dir_add(librados::IoCtx *ioctx, const std::string &oid,
2597 const std::string &name, const std::string &id)
2598{
2599 bufferlist in, out;
2600 encode(name, in);
2601 encode(id, in);
2602 return ioctx->exec(oid, "rbd", "group_dir_add", in, out);
2603}
2604
2605int group_dir_rename(librados::IoCtx *ioctx, const std::string &oid,
2606 const std::string &src, const std::string &dest,
2607 const std::string &id)
2608{
2609 bufferlist in, out;
2610 encode(src, in);
2611 encode(dest, in);
2612 encode(id, in);
2613 return ioctx->exec(oid, "rbd", "group_dir_rename", in, out);
2614}
2615
2616int group_dir_remove(librados::IoCtx *ioctx, const std::string &oid,
2617 const std::string &name, const std::string &id)
2618{
2619 bufferlist in, out;
2620 encode(name, in);
2621 encode(id, in);
2622 return ioctx->exec(oid, "rbd", "group_dir_remove", in, out);
2623}
2624
2625int group_image_remove(librados::IoCtx *ioctx, const std::string &oid,
2626 const cls::rbd::GroupImageSpec &spec)
2627{
2628 bufferlist bl, bl2;
2629 encode(spec, bl);
2630
2631 return ioctx->exec(oid, "rbd", "group_image_remove", bl, bl2);
2632}
2633
2634int group_image_list(librados::IoCtx *ioctx,
2635 const std::string &oid,
2636 const cls::rbd::GroupImageSpec &start,
2637 uint64_t max_return,
2638 std::vector<cls::rbd::GroupImageStatus> *images)
2639{
2640 bufferlist bl, bl2;
2641 encode(start, bl);
2642 encode(max_return, bl);
2643
2644 int r = ioctx->exec(oid, "rbd", "group_image_list", bl, bl2);
2645 if (r < 0)
2646 return r;
2647
2648 auto iter = bl2.cbegin();
2649 try {
2650 decode(*images, iter);
f67539c2 2651 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2652 return -EBADMSG;
2653 }
2654
2655 return 0;
2656}
2657
2658int group_image_set(librados::IoCtx *ioctx, const std::string &oid,
2659 const cls::rbd::GroupImageStatus &st)
2660{
2661 bufferlist bl, bl2;
2662 encode(st, bl);
2663
2664 return ioctx->exec(oid, "rbd", "group_image_set", bl, bl2);
2665}
2666
2667int image_group_add(librados::IoCtx *ioctx, const std::string &oid,
2668 const cls::rbd::GroupSpec &group_spec)
2669{
2670 bufferlist bl, bl2;
2671 encode(group_spec, bl);
2672
2673 return ioctx->exec(oid, "rbd", "image_group_add", bl, bl2);
2674}
2675
2676int image_group_remove(librados::IoCtx *ioctx, const std::string &oid,
2677 const cls::rbd::GroupSpec &group_spec)
2678{
2679 bufferlist bl, bl2;
2680 encode(group_spec, bl);
2681
2682 return ioctx->exec(oid, "rbd", "image_group_remove", bl, bl2);
2683}
2684
2685void image_group_get_start(librados::ObjectReadOperation *op)
2686{
2687 bufferlist in_bl;
2688 op->exec("rbd", "image_group_get", in_bl);
2689}
2690
2691int image_group_get_finish(bufferlist::const_iterator *iter,
2692 cls::rbd::GroupSpec *group_spec)
2693{
2694 try {
2695 decode(*group_spec, *iter);
f67539c2 2696 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2697 return -EBADMSG;
2698 }
2699 return 0;
2700}
2701
2702int image_group_get(librados::IoCtx *ioctx, const std::string &oid,
2703 cls::rbd::GroupSpec *group_spec)
2704{
2705 librados::ObjectReadOperation op;
2706 image_group_get_start(&op);
2707
2708 bufferlist out_bl;
2709 int r = ioctx->operate(oid, &op, &out_bl);
2710 if (r < 0) {
2711 return r;
2712 }
2713
2714 auto iter = out_bl.cbegin();
2715 return image_group_get_finish(&iter, group_spec);
2716}
2717
2718int group_snap_set(librados::IoCtx *ioctx, const std::string &oid,
2719 const cls::rbd::GroupSnapshot &snapshot)
2720{
2721 using ceph::encode;
2722 bufferlist inbl, outbl;
2723 encode(snapshot, inbl);
2724 int r = ioctx->exec(oid, "rbd", "group_snap_set", inbl, outbl);
2725 return r;
2726}
2727
2728int group_snap_remove(librados::IoCtx *ioctx, const std::string &oid,
2729 const std::string &snap_id)
2730{
2731 using ceph::encode;
2732 bufferlist inbl, outbl;
2733 encode(snap_id, inbl);
2734 return ioctx->exec(oid, "rbd", "group_snap_remove", inbl, outbl);
2735}
2736
2737int group_snap_get_by_id(librados::IoCtx *ioctx, const std::string &oid,
2738 const std::string &snap_id,
2739 cls::rbd::GroupSnapshot *snapshot)
2740{
2741 using ceph::encode;
2742 using ceph::decode;
2743 bufferlist inbl, outbl;
2744
2745 encode(snap_id, inbl);
2746 int r = ioctx->exec(oid, "rbd", "group_snap_get_by_id", inbl, outbl);
2747 if (r < 0) {
2748 return r;
2749 }
2750
2751 auto iter = outbl.cbegin();
2752 try {
2753 decode(*snapshot, iter);
f67539c2 2754 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2755 return -EBADMSG;
2756 }
2757
2758 return 0;
2759}
2760int group_snap_list(librados::IoCtx *ioctx, const std::string &oid,
2761 const cls::rbd::GroupSnapshot &start,
2762 uint64_t max_return,
2763 std::vector<cls::rbd::GroupSnapshot> *snapshots)
2764{
2765 using ceph::encode;
2766 using ceph::decode;
2767 bufferlist inbl, outbl;
2768 encode(start, inbl);
2769 encode(max_return, inbl);
2770
2771 int r = ioctx->exec(oid, "rbd", "group_snap_list", inbl, outbl);
2772 if (r < 0) {
2773 return r;
2774 }
2775 auto iter = outbl.cbegin();
2776 try {
2777 decode(*snapshots, iter);
f67539c2 2778 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2779 return -EBADMSG;
2780 }
2781
2782 return 0;
2783}
2784
2785// rbd_trash functions
2786void trash_add(librados::ObjectWriteOperation *op,
2787 const std::string &id,
2788 const cls::rbd::TrashImageSpec &trash_spec)
2789{
2790 bufferlist bl;
2791 encode(id, bl);
2792 encode(trash_spec, bl);
2793 op->exec("rbd", "trash_add", bl);
2794}
2795
2796int trash_add(librados::IoCtx *ioctx, const std::string &id,
2797 const cls::rbd::TrashImageSpec &trash_spec)
2798{
2799 librados::ObjectWriteOperation op;
2800 trash_add(&op, id, trash_spec);
2801
2802 return ioctx->operate(RBD_TRASH, &op);
2803}
2804
2805void trash_remove(librados::ObjectWriteOperation *op,
2806 const std::string &id)
2807{
2808 bufferlist bl;
2809 encode(id, bl);
2810 op->exec("rbd", "trash_remove", bl);
2811}
2812
2813int trash_remove(librados::IoCtx *ioctx, const std::string &id)
2814{
2815 librados::ObjectWriteOperation op;
2816 trash_remove(&op, id);
2817
2818 return ioctx->operate(RBD_TRASH, &op);
2819}
2820
2821void trash_list_start(librados::ObjectReadOperation *op,
2822 const std::string &start, uint64_t max_return)
2823{
2824 bufferlist bl;
2825 encode(start, bl);
2826 encode(max_return, bl);
2827 op->exec("rbd", "trash_list", bl);
2828}
2829
2830int trash_list_finish(bufferlist::const_iterator *it,
2831 map<string, cls::rbd::TrashImageSpec> *entries)
2832{
2833 ceph_assert(entries);
2834
2835 try {
2836 decode(*entries, *it);
f67539c2 2837 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2838 return -EBADMSG;
2839 }
2840
2841 return 0;
2842}
2843
2844int trash_list(librados::IoCtx *ioctx,
2845 const std::string &start, uint64_t max_return,
2846 map<string, cls::rbd::TrashImageSpec> *entries)
2847{
2848 librados::ObjectReadOperation op;
2849 trash_list_start(&op, start, max_return);
2850
2851 bufferlist out_bl;
2852 int r = ioctx->operate(RBD_TRASH, &op, &out_bl);
2853 if (r < 0) {
2854 return r;
2855 }
2856
2857 auto iter = out_bl.cbegin();
2858 return trash_list_finish(&iter, entries);
2859}
2860
2861void trash_get_start(librados::ObjectReadOperation *op,
2862 const std::string &id)
2863{
2864 bufferlist bl;
2865 encode(id, bl);
2866 op->exec("rbd", "trash_get", bl);
2867}
2868
2869int trash_get_finish(bufferlist::const_iterator *it,
2870 cls::rbd::TrashImageSpec *trash_spec) {
2871 ceph_assert(trash_spec);
2872 try {
2873 decode(*trash_spec, *it);
f67539c2 2874 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2875 return -EBADMSG;
2876 }
2877
2878 return 0;
2879}
2880
2881int trash_get(librados::IoCtx *ioctx, const std::string &id,
2882 cls::rbd::TrashImageSpec *trash_spec)
2883{
2884 librados::ObjectReadOperation op;
2885 trash_get_start(&op, id);
2886
2887 bufferlist out_bl;
2888 int r = ioctx->operate(RBD_TRASH, &op, &out_bl);
2889 if (r < 0) {
2890 return r;
2891 }
2892
2893 auto it = out_bl.cbegin();
2894 return trash_get_finish(&it, trash_spec);
2895}
2896
2897void trash_state_set(librados::ObjectWriteOperation *op,
2898 const std::string &id,
2899 const cls::rbd::TrashImageState &trash_state,
2900 const cls::rbd::TrashImageState &expect_state)
2901{
2902 bufferlist bl;
2903 encode(id, bl);
2904 encode(trash_state, bl);
2905 encode(expect_state, bl);
2906 op->exec("rbd", "trash_state_set", bl);
2907}
2908
2909int trash_state_set(librados::IoCtx *ioctx, const std::string &id,
2910 const cls::rbd::TrashImageState &trash_state,
2911 const cls::rbd::TrashImageState &expect_state)
2912{
2913 librados::ObjectWriteOperation op;
2914 trash_state_set(&op, id, trash_state, expect_state);
2915
2916 return ioctx->operate(RBD_TRASH, &op);
2917}
2918
2919void namespace_add(librados::ObjectWriteOperation *op,
2920 const std::string &name)
2921{
2922 bufferlist bl;
2923 encode(name, bl);
2924 op->exec("rbd", "namespace_add", bl);
2925}
2926
2927int namespace_add(librados::IoCtx *ioctx, const std::string &name)
2928{
2929 librados::ObjectWriteOperation op;
2930 namespace_add(&op, name);
2931
2932 return ioctx->operate(RBD_NAMESPACE, &op);
2933}
2934
2935void namespace_remove(librados::ObjectWriteOperation *op,
2936 const std::string &name)
2937{
2938 bufferlist bl;
2939 encode(name, bl);
2940 op->exec("rbd", "namespace_remove", bl);
2941}
2942
2943int namespace_remove(librados::IoCtx *ioctx, const std::string &name)
2944{
2945 librados::ObjectWriteOperation op;
2946 namespace_remove(&op, name);
2947
2948 return ioctx->operate(RBD_NAMESPACE, &op);
2949}
2950
2951void namespace_list_start(librados::ObjectReadOperation *op,
c07f9fc5 2952 const std::string &start, uint64_t max_return)
11fdf7f2
TL
2953{
2954 bufferlist bl;
2955 encode(start, bl);
2956 encode(max_return, bl);
2957 op->exec("rbd", "namespace_list", bl);
2958}
2959
2960int namespace_list_finish(bufferlist::const_iterator *it,
2961 std::list<std::string> *entries)
2962{
2963 ceph_assert(entries);
2964
2965 try {
2966 decode(*entries, *it);
f67539c2 2967 } catch (const ceph::buffer::error &err) {
11fdf7f2
TL
2968 return -EBADMSG;
2969 }
2970
2971 return 0;
2972}
2973
2974int namespace_list(librados::IoCtx *ioctx,
c07f9fc5 2975 const std::string &start, uint64_t max_return,
11fdf7f2
TL
2976 std::list<std::string> *entries)
2977{
2978 librados::ObjectReadOperation op;
2979 namespace_list_start(&op, start, max_return);
2980
2981 bufferlist out_bl;
2982 int r = ioctx->operate(RBD_NAMESPACE, &op, &out_bl);
2983 if (r < 0) {
2984 return r;
2985 }
2986
2987 auto iter = out_bl.cbegin();
2988 return namespace_list_finish(&iter, entries);
2989}
2990
20effc67 2991void sparsify(librados::ObjectWriteOperation *op, uint64_t sparse_size,
11fdf7f2
TL
2992 bool remove_empty)
2993{
2994 bufferlist bl;
2995 encode(sparse_size, bl);
2996 encode(remove_empty, bl);
2997 op->exec("rbd", "sparsify", bl);
2998}
2999
20effc67 3000int sparsify(librados::IoCtx *ioctx, const std::string &oid, uint64_t sparse_size,
11fdf7f2
TL
3001 bool remove_empty)
3002{
3003 librados::ObjectWriteOperation op;
3004 sparsify(&op, sparse_size, remove_empty);
3005
3006 return ioctx->operate(oid, &op);
3007}
3008
3009} // namespace cls_client
7c673cae 3010} // namespace librbd