]> git.proxmox.com Git - ceph.git/blob - ceph/src/librados/librados_c.cc
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / librados / librados_c.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <limits.h>
5
6 #include "acconfig.h"
7 #include "common/config.h"
8 #include "common/errno.h"
9 #include "common/ceph_argparse.h"
10 #include "common/ceph_json.h"
11 #include "common/common_init.h"
12 #include "common/TracepointProvider.h"
13 #include "common/hobject.h"
14 #include "common/async/waiter.h"
15 #include "include/rados/librados.h"
16 #include "include/types.h"
17 #include <include/stringify.h>
18
19 #include "librados/librados_c.h"
20 #include "librados/AioCompletionImpl.h"
21 #include "librados/IoCtxImpl.h"
22 #include "librados/ObjectOperationImpl.h"
23 #include "librados/PoolAsyncCompletionImpl.h"
24 #include "librados/RadosClient.h"
25 #include "librados/RadosXattrIter.h"
26 #include "librados/ListObjectImpl.h"
27 #include "librados/librados_util.h"
28 #include <cls/lock/cls_lock_client.h>
29
30 #include <string>
31 #include <map>
32 #include <set>
33 #include <vector>
34 #include <list>
35 #include <stdexcept>
36
37 #ifdef WITH_LTTNG
38 #define TRACEPOINT_DEFINE
39 #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
40 #include "tracing/librados.h"
41 #undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
42 #undef TRACEPOINT_DEFINE
43 #else
44 #define tracepoint(...)
45 #endif
46
47 #if defined(HAVE_ASM_SYMVER) || defined(HAVE_ATTR_SYMVER)
48 // prefer __attribute__() over global asm(".symver"). because the latter
49 // is not parsed by the compiler and is partitioned away by GCC if
50 // lto-partitions is enabled, in other words, these asm() statements
51 // are dropped by the -flto option by default. the way to address it is
52 // to use __attribute__. so this information can be processed by the
53 // C compiler, and be preserved after LTO partitions the code
54 #ifdef HAVE_ATTR_SYMVER
55 #define LIBRADOS_C_API_BASE(fn) \
56 extern __typeof (_##fn##_base) _##fn##_base __attribute__((__symver__ (#fn "@")))
57 #define LIBRADOS_C_API_BASE_DEFAULT(fn) \
58 extern __typeof (_##fn) _##fn __attribute__((__symver__ (#fn "@@")))
59 #define LIBRADOS_C_API_DEFAULT(fn, ver) \
60 extern __typeof (_##fn) _##fn __attribute__((__symver__ (#fn "@@LIBRADOS_" #ver)))
61 #else
62 #define LIBRADOS_C_API_BASE(fn) \
63 asm(".symver _" #fn "_base, " #fn "@")
64 #define LIBRADOS_C_API_BASE_DEFAULT(fn) \
65 asm(".symver _" #fn ", " #fn "@@")
66 #define LIBRADOS_C_API_DEFAULT(fn, ver) \
67 asm(".symver _" #fn ", " #fn "@@LIBRADOS_" #ver)
68 #endif
69
70 #define LIBRADOS_C_API_BASE_F(fn) _ ## fn ## _base
71 #define LIBRADOS_C_API_DEFAULT_F(fn) _ ## fn
72
73 #else
74 #define LIBRADOS_C_API_BASE(fn)
75 #define LIBRADOS_C_API_BASE_DEFAULT(fn)
76 #define LIBRADOS_C_API_DEFAULT(fn, ver)
77
78 #define LIBRADOS_C_API_BASE_F(fn) _ ## fn ## _base
79 // There shouldn't be multiple default versions of the same
80 // function.
81 #define LIBRADOS_C_API_DEFAULT_F(fn) fn
82 #endif
83
84 using std::ostringstream;
85 using std::pair;
86 using std::string;
87 using std::map;
88 using std::set;
89 using std::vector;
90 using std::list;
91
92 #define dout_subsys ceph_subsys_rados
93 #undef dout_prefix
94 #define dout_prefix *_dout << "librados: "
95
96 #define RADOS_LIST_MAX_ENTRIES 1024
97
98 static TracepointProvider::Traits tracepoint_traits("librados_tp.so", "rados_tracing");
99
100 /*
101 * Structure of this file
102 *
103 * RadosClient and the related classes are the internal implementation of librados.
104 * Above that layer sits the C API, found in include/rados/librados.h, and
105 * the C++ API, found in include/rados/librados.hpp
106 *
107 * The C++ API sometimes implements things in terms of the C API.
108 * Both the C++ and C API rely on RadosClient.
109 *
110 * Visually:
111 * +--------------------------------------+
112 * | C++ API |
113 * +--------------------+ |
114 * | C API | |
115 * +--------------------+-----------------+
116 * | RadosClient |
117 * +--------------------------------------+
118 */
119
120 ///////////////////////////// C API //////////////////////////////
121
122 static CephContext *rados_create_cct(
123 const char * const clustername,
124 CephInitParameters *iparams)
125 {
126 // missing things compared to global_init:
127 // g_ceph_context, g_conf, g_lockdep, signal handlers
128 CephContext *cct = common_preinit(*iparams, CODE_ENVIRONMENT_LIBRARY, 0);
129 if (clustername)
130 cct->_conf->cluster = clustername;
131 cct->_conf.parse_env(cct->get_module_type()); // environment variables override
132 cct->_conf.apply_changes(nullptr);
133
134 TracepointProvider::initialize<tracepoint_traits>(cct);
135 return cct;
136 }
137
138 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_create)(
139 rados_t *pcluster,
140 const char * const id)
141 {
142 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
143 if (id) {
144 iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
145 }
146 CephContext *cct = rados_create_cct("", &iparams);
147
148 tracepoint(librados, rados_create_enter, id);
149 *pcluster = reinterpret_cast<rados_t>(new librados::RadosClient(cct));
150 tracepoint(librados, rados_create_exit, 0, *pcluster);
151
152 cct->put();
153 return 0;
154 }
155 LIBRADOS_C_API_BASE_DEFAULT(rados_create);
156
157 // as above, but
158 // 1) don't assume 'client.'; name is a full type.id namestr
159 // 2) allow setting clustername
160 // 3) flags is for future expansion (maybe some of the global_init()
161 // behavior is appropriate for some consumers of librados, for instance)
162
163 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_create2)(
164 rados_t *pcluster,
165 const char *const clustername,
166 const char * const name,
167 uint64_t flags)
168 {
169 // client is assumed, but from_str will override
170 int retval = 0;
171 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
172 if (!name || !iparams.name.from_str(name)) {
173 retval = -EINVAL;
174 }
175
176 CephContext *cct = rados_create_cct(clustername, &iparams);
177 tracepoint(librados, rados_create2_enter, clustername, name, flags);
178 if (retval == 0) {
179 *pcluster = reinterpret_cast<rados_t>(new librados::RadosClient(cct));
180 }
181 tracepoint(librados, rados_create2_exit, retval, *pcluster);
182
183 cct->put();
184 return retval;
185 }
186 LIBRADOS_C_API_BASE_DEFAULT(rados_create2);
187
188 /* This function is intended for use by Ceph daemons. These daemons have
189 * already called global_init and want to use that particular configuration for
190 * their cluster.
191 */
192 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_create_with_context)(
193 rados_t *pcluster,
194 rados_config_t cct_)
195 {
196 CephContext *cct = (CephContext *)cct_;
197 TracepointProvider::initialize<tracepoint_traits>(cct);
198
199 tracepoint(librados, rados_create_with_context_enter, cct_);
200 librados::RadosClient *radosp = new librados::RadosClient(cct);
201 *pcluster = (void *)radosp;
202 tracepoint(librados, rados_create_with_context_exit, 0, *pcluster);
203 return 0;
204 }
205 LIBRADOS_C_API_BASE_DEFAULT(rados_create_with_context);
206
207 extern "C" rados_config_t LIBRADOS_C_API_DEFAULT_F(rados_cct)(rados_t cluster)
208 {
209 tracepoint(librados, rados_cct_enter, cluster);
210 librados::RadosClient *client = (librados::RadosClient *)cluster;
211 rados_config_t retval = (rados_config_t)client->cct;
212 tracepoint(librados, rados_cct_exit, retval);
213 return retval;
214 }
215 LIBRADOS_C_API_BASE_DEFAULT(rados_cct);
216
217 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_connect)(rados_t cluster)
218 {
219 tracepoint(librados, rados_connect_enter, cluster);
220 librados::RadosClient *client = (librados::RadosClient *)cluster;
221 int retval = client->connect();
222 tracepoint(librados, rados_connect_exit, retval);
223 return retval;
224 }
225 LIBRADOS_C_API_BASE_DEFAULT(rados_connect);
226
227 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_shutdown)(rados_t cluster)
228 {
229 tracepoint(librados, rados_shutdown_enter, cluster);
230 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
231 radosp->shutdown();
232 delete radosp;
233 tracepoint(librados, rados_shutdown_exit);
234 }
235 LIBRADOS_C_API_BASE_DEFAULT(rados_shutdown);
236
237 extern "C" uint64_t LIBRADOS_C_API_DEFAULT_F(rados_get_instance_id)(
238 rados_t cluster)
239 {
240 tracepoint(librados, rados_get_instance_id_enter, cluster);
241 librados::RadosClient *client = (librados::RadosClient *)cluster;
242 uint64_t retval = client->get_instance_id();
243 tracepoint(librados, rados_get_instance_id_exit, retval);
244 return retval;
245 }
246 LIBRADOS_C_API_BASE_DEFAULT(rados_get_instance_id);
247
248 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_get_min_compatible_osd)(
249 rados_t cluster,
250 int8_t* require_osd_release)
251 {
252 librados::RadosClient *client = (librados::RadosClient *)cluster;
253 return client->get_min_compatible_osd(require_osd_release);
254 }
255 LIBRADOS_C_API_BASE_DEFAULT(rados_get_min_compatible_osd);
256
257 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_get_min_compatible_client)(
258 rados_t cluster,
259 int8_t* min_compat_client,
260 int8_t* require_min_compat_client)
261 {
262 librados::RadosClient *client = (librados::RadosClient *)cluster;
263 return client->get_min_compatible_client(min_compat_client,
264 require_min_compat_client);
265 }
266 LIBRADOS_C_API_BASE_DEFAULT(rados_get_min_compatible_client);
267
268 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_version)(
269 int *major, int *minor, int *extra)
270 {
271 tracepoint(librados, rados_version_enter, major, minor, extra);
272 if (major)
273 *major = LIBRADOS_VER_MAJOR;
274 if (minor)
275 *minor = LIBRADOS_VER_MINOR;
276 if (extra)
277 *extra = LIBRADOS_VER_EXTRA;
278 tracepoint(librados, rados_version_exit, LIBRADOS_VER_MAJOR, LIBRADOS_VER_MINOR, LIBRADOS_VER_EXTRA);
279 }
280 LIBRADOS_C_API_BASE_DEFAULT(rados_version);
281
282
283 // -- config --
284 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_read_file)(
285 rados_t cluster,
286 const char *path_list)
287 {
288 tracepoint(librados, rados_conf_read_file_enter, cluster, path_list);
289 librados::RadosClient *client = (librados::RadosClient *)cluster;
290 auto& conf = client->cct->_conf;
291 ostringstream warnings;
292 int ret = conf.parse_config_files(path_list, &warnings, 0);
293 if (ret) {
294 if (warnings.tellp() > 0)
295 lderr(client->cct) << warnings.str() << dendl;
296 client->cct->_conf.complain_about_parse_error(client->cct);
297 tracepoint(librados, rados_conf_read_file_exit, ret);
298 return ret;
299 }
300 conf.parse_env(client->cct->get_module_type()); // environment variables override
301
302 conf.apply_changes(nullptr);
303 client->cct->_conf.complain_about_parse_error(client->cct);
304 tracepoint(librados, rados_conf_read_file_exit, 0);
305 return 0;
306 }
307 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_read_file);
308
309 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_parse_argv)(
310 rados_t cluster,
311 int argc,
312 const char **argv)
313 {
314 tracepoint(librados, rados_conf_parse_argv_enter, cluster, argc);
315 int i;
316 for(i = 0; i < argc; i++) {
317 tracepoint(librados, rados_conf_parse_argv_arg, argv[i]);
318 }
319 librados::RadosClient *client = (librados::RadosClient *)cluster;
320 auto& conf = client->cct->_conf;
321 auto args = argv_to_vec(argc, argv);
322 int ret = conf.parse_argv(args);
323 if (ret) {
324 tracepoint(librados, rados_conf_parse_argv_exit, ret);
325 return ret;
326 }
327 conf.apply_changes(nullptr);
328 tracepoint(librados, rados_conf_parse_argv_exit, 0);
329 return 0;
330 }
331 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_parse_argv);
332
333 // like above, but return the remainder of argv to contain remaining
334 // unparsed args. Must be allocated to at least argc by caller.
335 // remargv will contain n <= argc pointers to original argv[], the end
336 // of which may be NULL
337
338 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_parse_argv_remainder)(
339 rados_t cluster, int argc,
340 const char **argv,
341 const char **remargv)
342 {
343 tracepoint(librados, rados_conf_parse_argv_remainder_enter, cluster, argc);
344 unsigned int i;
345 for(i = 0; i < (unsigned int) argc; i++) {
346 tracepoint(librados, rados_conf_parse_argv_remainder_arg, argv[i]);
347 }
348 librados::RadosClient *client = (librados::RadosClient *)cluster;
349 auto& conf = client->cct->_conf;
350 vector<const char*> args;
351 for (int i=0; i<argc; i++)
352 args.push_back(argv[i]);
353 int ret = conf.parse_argv(args);
354 if (ret) {
355 tracepoint(librados, rados_conf_parse_argv_remainder_exit, ret);
356 return ret;
357 }
358 conf.apply_changes(NULL);
359 ceph_assert(args.size() <= (unsigned int)argc);
360 for (i = 0; i < (unsigned int)argc; ++i) {
361 if (i < args.size())
362 remargv[i] = args[i];
363 else
364 remargv[i] = (const char *)NULL;
365 tracepoint(librados, rados_conf_parse_argv_remainder_remarg, remargv[i]);
366 }
367 tracepoint(librados, rados_conf_parse_argv_remainder_exit, 0);
368 return 0;
369 }
370 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_parse_argv_remainder);
371
372 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_parse_env)(
373 rados_t cluster, const char *env)
374 {
375 tracepoint(librados, rados_conf_parse_env_enter, cluster, env);
376 librados::RadosClient *client = (librados::RadosClient *)cluster;
377 auto& conf = client->cct->_conf;
378 conf.parse_env(client->cct->get_module_type(), env);
379 conf.apply_changes(nullptr);
380 tracepoint(librados, rados_conf_parse_env_exit, 0);
381 return 0;
382 }
383 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_parse_env);
384
385 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_set)(
386 rados_t cluster,
387 const char *option,
388 const char *value)
389 {
390 tracepoint(librados, rados_conf_set_enter, cluster, option, value);
391 librados::RadosClient *client = (librados::RadosClient *)cluster;
392 auto& conf = client->cct->_conf;
393 int ret = conf.set_val(option, value);
394 if (ret) {
395 tracepoint(librados, rados_conf_set_exit, ret);
396 return ret;
397 }
398 conf.apply_changes(nullptr);
399 tracepoint(librados, rados_conf_set_exit, 0);
400 return 0;
401 }
402 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_set);
403
404 /* cluster info */
405 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_cluster_stat)(
406 rados_t cluster,
407 rados_cluster_stat_t *result)
408 {
409 tracepoint(librados, rados_cluster_stat_enter, cluster);
410 librados::RadosClient *client = (librados::RadosClient *)cluster;
411
412 ceph_statfs stats;
413 int r = client->get_fs_stats(stats);
414 result->kb = stats.kb;
415 result->kb_used = stats.kb_used;
416 result->kb_avail = stats.kb_avail;
417 result->num_objects = stats.num_objects;
418 tracepoint(librados, rados_cluster_stat_exit, r, result->kb, result->kb_used, result->kb_avail, result->num_objects);
419 return r;
420 }
421 LIBRADOS_C_API_BASE_DEFAULT(rados_cluster_stat);
422
423 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_conf_get)(
424 rados_t cluster,
425 const char *option,
426 char *buf, size_t len)
427 {
428 tracepoint(librados, rados_conf_get_enter, cluster, option, len);
429 char *tmp = buf;
430 librados::RadosClient *client = (librados::RadosClient *)cluster;
431 const auto& conf = client->cct->_conf;
432 int retval = conf.get_val(option, &tmp, len);
433 tracepoint(librados, rados_conf_get_exit, retval, retval ? "" : option);
434 return retval;
435 }
436 LIBRADOS_C_API_BASE_DEFAULT(rados_conf_get);
437
438 extern "C" int64_t LIBRADOS_C_API_DEFAULT_F(rados_pool_lookup)(
439 rados_t cluster,
440 const char *name)
441 {
442 tracepoint(librados, rados_pool_lookup_enter, cluster, name);
443 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
444 int64_t retval = radosp->lookup_pool(name);
445 tracepoint(librados, rados_pool_lookup_exit, retval);
446 return retval;
447 }
448 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_lookup);
449
450 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_reverse_lookup)(
451 rados_t cluster,
452 int64_t id,
453 char *buf,
454 size_t maxlen)
455 {
456 tracepoint(librados, rados_pool_reverse_lookup_enter, cluster, id, maxlen);
457 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
458 std::string name;
459 int r = radosp->pool_get_name(id, &name, true);
460 if (r < 0) {
461 tracepoint(librados, rados_pool_reverse_lookup_exit, r, "");
462 return r;
463 }
464 if (name.length() >= maxlen) {
465 tracepoint(librados, rados_pool_reverse_lookup_exit, -ERANGE, "");
466 return -ERANGE;
467 }
468 strcpy(buf, name.c_str());
469 int retval = name.length();
470 tracepoint(librados, rados_pool_reverse_lookup_exit, retval, buf);
471 return retval;
472 }
473 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_reverse_lookup);
474
475 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_cluster_fsid)(
476 rados_t cluster,
477 char *buf,
478 size_t maxlen)
479 {
480 tracepoint(librados, rados_cluster_fsid_enter, cluster, maxlen);
481 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
482 std::string fsid;
483 radosp->get_fsid(&fsid);
484 if (fsid.length() >= maxlen) {
485 tracepoint(librados, rados_cluster_fsid_exit, -ERANGE, "");
486 return -ERANGE;
487 }
488 strcpy(buf, fsid.c_str());
489 int retval = fsid.length();
490 tracepoint(librados, rados_cluster_fsid_exit, retval, buf);
491 return retval;
492 }
493 LIBRADOS_C_API_BASE_DEFAULT(rados_cluster_fsid);
494
495 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_wait_for_latest_osdmap)(
496 rados_t cluster)
497 {
498 tracepoint(librados, rados_wait_for_latest_osdmap_enter, cluster);
499 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
500 int retval = radosp->wait_for_latest_osdmap();
501 tracepoint(librados, rados_wait_for_latest_osdmap_exit, retval);
502 return retval;
503 }
504 LIBRADOS_C_API_BASE_DEFAULT(rados_wait_for_latest_osdmap);
505
506 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_blocklist_add)(
507 rados_t cluster,
508 char *client_address,
509 uint32_t expire_seconds)
510 {
511 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
512 return radosp->blocklist_add(client_address, expire_seconds);
513 }
514 LIBRADOS_C_API_BASE_DEFAULT(rados_blocklist_add);
515
516 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_blacklist_add)(
517 rados_t cluster,
518 char *client_address,
519 uint32_t expire_seconds)
520 {
521 return LIBRADOS_C_API_DEFAULT_F(rados_blocklist_add)(
522 cluster, client_address, expire_seconds);
523 }
524 LIBRADOS_C_API_BASE_DEFAULT(rados_blacklist_add);
525
526 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_getaddrs)(
527 rados_t cluster,
528 char** addrs)
529 {
530 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
531 auto s = radosp->get_addrs();
532 *addrs = strdup(s.c_str());
533 return 0;
534 }
535 LIBRADOS_C_API_BASE_DEFAULT(rados_getaddrs);
536
537 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_set_osdmap_full_try)(
538 rados_ioctx_t io)
539 {
540 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
541 ctx->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
542 }
543 LIBRADOS_C_API_BASE_DEFAULT(rados_set_osdmap_full_try);
544
545 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_unset_osdmap_full_try)(
546 rados_ioctx_t io)
547 {
548 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
549 ctx->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
550 }
551 LIBRADOS_C_API_BASE_DEFAULT(rados_unset_osdmap_full_try);
552
553 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_set_pool_full_try)(
554 rados_ioctx_t io)
555 {
556 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
557 ctx->extra_op_flags |= CEPH_OSD_FLAG_FULL_TRY;
558 }
559 LIBRADOS_C_API_BASE_DEFAULT(rados_set_pool_full_try);
560
561 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_unset_pool_full_try)(
562 rados_ioctx_t io)
563 {
564 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
565 ctx->extra_op_flags &= ~CEPH_OSD_FLAG_FULL_TRY;
566 }
567 LIBRADOS_C_API_BASE_DEFAULT(rados_unset_pool_full_try);
568
569 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_enable)(
570 rados_ioctx_t io,
571 const char *app_name,
572 int force)
573 {
574 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
575 return ctx->application_enable(app_name, force != 0);
576 }
577 LIBRADOS_C_API_BASE_DEFAULT(rados_application_enable);
578
579 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_list)(
580 rados_ioctx_t io,
581 char *values,
582 size_t *values_len)
583 {
584 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
585 std::set<std::string> app_names;
586 int r = ctx->application_list(&app_names);
587 if (r < 0) {
588 return r;
589 }
590
591 size_t total_len = 0;
592 for (auto app_name : app_names) {
593 total_len += app_name.size() + 1;
594 }
595
596 if (*values_len < total_len) {
597 *values_len = total_len;
598 return -ERANGE;
599 }
600
601 char *values_p = values;
602 for (auto app_name : app_names) {
603 size_t len = app_name.size() + 1;
604 strncpy(values_p, app_name.c_str(), len);
605 values_p += len;
606 }
607 *values_p = '\0';
608 *values_len = total_len;
609 return 0;
610 }
611 LIBRADOS_C_API_BASE_DEFAULT(rados_application_list);
612
613 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_metadata_get)(
614 rados_ioctx_t io,
615 const char *app_name,
616 const char *key,
617 char *value,
618 size_t *value_len)
619 {
620 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
621 std::string value_str;
622 int r = ctx->application_metadata_get(app_name, key, &value_str);
623 if (r < 0) {
624 return r;
625 }
626
627 size_t len = value_str.size() + 1;
628 if (*value_len < len) {
629 *value_len = len;
630 return -ERANGE;
631 }
632
633 strncpy(value, value_str.c_str(), len);
634 *value_len = len;
635 return 0;
636 }
637 LIBRADOS_C_API_BASE_DEFAULT(rados_application_metadata_get);
638
639 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_metadata_set)(
640 rados_ioctx_t io,
641 const char *app_name,
642 const char *key,
643 const char *value)
644 {
645 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
646 return ctx->application_metadata_set(app_name, key, value);
647 }
648 LIBRADOS_C_API_BASE_DEFAULT(rados_application_metadata_set);
649
650 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_metadata_remove)(
651 rados_ioctx_t io,
652 const char *app_name,
653 const char *key)
654 {
655 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
656 return ctx->application_metadata_remove(app_name, key);
657 }
658 LIBRADOS_C_API_BASE_DEFAULT(rados_application_metadata_remove);
659
660 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_application_metadata_list)(
661 rados_ioctx_t io,
662 const char *app_name,
663 char *keys, size_t *keys_len,
664 char *values, size_t *vals_len)
665 {
666 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
667 std::map<std::string, std::string> metadata;
668 int r = ctx->application_metadata_list(app_name, &metadata);
669 if (r < 0) {
670 return r;
671 }
672
673 size_t total_key_len = 0;
674 size_t total_val_len = 0;
675 for (auto pair : metadata) {
676 total_key_len += pair.first.size() + 1;
677 total_val_len += pair.second.size() + 1;
678 }
679
680 if (*keys_len < total_key_len || *vals_len < total_val_len) {
681 *keys_len = total_key_len;
682 *vals_len = total_val_len;
683 return -ERANGE;
684 }
685
686 char *keys_p = keys;
687 char *vals_p = values;
688 for (auto pair : metadata) {
689 size_t key_len = pair.first.size() + 1;
690 strncpy(keys_p, pair.first.c_str(), key_len);
691 keys_p += key_len;
692
693 size_t val_len = pair.second.size() + 1;
694 strncpy(vals_p, pair.second.c_str(), val_len);
695 vals_p += val_len;
696 }
697 *keys_p = '\0';
698 *keys_len = total_key_len;
699
700 *vals_p = '\0';
701 *vals_len = total_val_len;
702 return 0;
703 }
704 LIBRADOS_C_API_BASE_DEFAULT(rados_application_metadata_list);
705
706 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_list)(
707 rados_t cluster,
708 char *buf,
709 size_t len)
710 {
711 tracepoint(librados, rados_pool_list_enter, cluster, len);
712 librados::RadosClient *client = (librados::RadosClient *)cluster;
713 std::list<std::pair<int64_t, std::string> > pools;
714 int r = client->pool_list(pools);
715 if (r < 0) {
716 tracepoint(librados, rados_pool_list_exit, r);
717 return r;
718 }
719
720 if (len > 0 && !buf) {
721 tracepoint(librados, rados_pool_list_exit, -EINVAL);
722 return -EINVAL;
723 }
724
725 char *b = buf;
726 if (b) {
727 // FIPS zeroization audit 20191116: this memset is not security related.
728 memset(b, 0, len);
729 }
730 int needed = 0;
731 std::list<std::pair<int64_t, std::string> >::const_iterator i = pools.begin();
732 std::list<std::pair<int64_t, std::string> >::const_iterator p_end =
733 pools.end();
734 for (; i != p_end; ++i) {
735 int rl = i->second.length() + 1;
736 if (len < (unsigned)rl)
737 break;
738 const char* pool = i->second.c_str();
739 tracepoint(librados, rados_pool_list_pool, pool);
740 if (b) {
741 strncat(b, pool, rl);
742 b += rl;
743 }
744 needed += rl;
745 len -= rl;
746 }
747 for (; i != p_end; ++i) {
748 int rl = i->second.length() + 1;
749 needed += rl;
750 }
751 int retval = needed + 1;
752 tracepoint(librados, rados_pool_list_exit, retval);
753 return retval;
754 }
755 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_list);
756
757 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_inconsistent_pg_list)(
758 rados_t cluster,
759 int64_t pool_id,
760 char *buf,
761 size_t len)
762 {
763 tracepoint(librados, rados_inconsistent_pg_list_enter, cluster, pool_id, len);
764 librados::RadosClient *client = (librados::RadosClient *)cluster;
765 std::vector<std::string> pgs;
766 if (int r = client->get_inconsistent_pgs(pool_id, &pgs); r < 0) {
767 tracepoint(librados, rados_inconsistent_pg_list_exit, r);
768 return r;
769 }
770
771 if (len > 0 && !buf) {
772 tracepoint(librados, rados_inconsistent_pg_list_exit, -EINVAL);
773 return -EINVAL;
774 }
775
776 char *b = buf;
777 if (b) {
778 // FIPS zeroization audit 20191116: this memset is not security related.
779 memset(b, 0, len);
780 }
781 int needed = 0;
782 for (const auto& s : pgs) {
783 unsigned rl = s.length() + 1;
784 if (b && len >= rl) {
785 tracepoint(librados, rados_inconsistent_pg_list_pg, s.c_str());
786 strncat(b, s.c_str(), rl);
787 b += rl;
788 len -= rl;
789 }
790 needed += rl;
791 }
792 int retval = needed + 1;
793 tracepoint(librados, rados_inconsistent_pg_list_exit, retval);
794 return retval;
795 }
796 LIBRADOS_C_API_BASE_DEFAULT(rados_inconsistent_pg_list);
797
798
799 static void dict_to_map(const char *dict,
800 std::map<std::string, std::string>* dict_map)
801 {
802 while (*dict != '\0') {
803 const char* key = dict;
804 dict += strlen(key) + 1;
805 const char* value = dict;
806 dict += strlen(value) + 1;
807 (*dict_map)[key] = value;
808 }
809 }
810
811 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_service_register)(
812 rados_t cluster,
813 const char *service,
814 const char *daemon,
815 const char *metadata_dict)
816 {
817 librados::RadosClient *client = (librados::RadosClient *)cluster;
818
819 std::map<std::string, std::string> metadata;
820 dict_to_map(metadata_dict, &metadata);
821
822 return client->service_daemon_register(service, daemon, metadata);
823 }
824 LIBRADOS_C_API_BASE_DEFAULT(rados_service_register);
825
826 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_service_update_status)(
827 rados_t cluster,
828 const char *status_dict)
829 {
830 librados::RadosClient *client = (librados::RadosClient *)cluster;
831
832 std::map<std::string, std::string> status;
833 dict_to_map(status_dict, &status);
834
835 return client->service_daemon_update_status(std::move(status));
836 }
837 LIBRADOS_C_API_BASE_DEFAULT(rados_service_update_status);
838
839 static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
840 {
841 if (outbuf) {
842 if (outbl.length() > 0) {
843 *outbuf = (char *)malloc(outbl.length());
844 memcpy(*outbuf, outbl.c_str(), outbl.length());
845 } else {
846 *outbuf = NULL;
847 }
848 }
849 if (outbuflen)
850 *outbuflen = outbl.length();
851 }
852
853 static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
854 {
855 if (outbuf) {
856 if (outbl.length() > 0) {
857 *outbuf = (char *)malloc(outbl.length());
858 memcpy(*outbuf, outbl.c_str(), outbl.length());
859 } else {
860 *outbuf = NULL;
861 }
862 }
863 if (outbuflen)
864 *outbuflen = outbl.length();
865 }
866
867 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ping_monitor)(
868 rados_t cluster,
869 const char *mon_id,
870 char **outstr,
871 size_t *outstrlen)
872 {
873 tracepoint(librados, rados_ping_monitor_enter, cluster, mon_id);
874 librados::RadosClient *client = (librados::RadosClient *)cluster;
875 string str;
876
877 if (!mon_id) {
878 tracepoint(librados, rados_ping_monitor_exit, -EINVAL, NULL, NULL);
879 return -EINVAL;
880 }
881
882 int ret = client->ping_monitor(mon_id, &str);
883 if (ret == 0) {
884 do_out_buffer(str, outstr, outstrlen);
885 }
886 tracepoint(librados, rados_ping_monitor_exit, ret, ret < 0 ? NULL : outstr, ret < 0 ? NULL : outstrlen);
887 return ret;
888 }
889 LIBRADOS_C_API_BASE_DEFAULT(rados_ping_monitor);
890
891 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_mon_command)(
892 rados_t cluster,
893 const char **cmd, size_t cmdlen,
894 const char *inbuf, size_t inbuflen,
895 char **outbuf, size_t *outbuflen,
896 char **outs, size_t *outslen)
897 {
898 tracepoint(librados, rados_mon_command_enter, cluster, cmdlen, inbuf, inbuflen);
899 librados::RadosClient *client = (librados::RadosClient *)cluster;
900 bufferlist inbl;
901 bufferlist outbl;
902 string outstring;
903 vector<string> cmdvec;
904
905 for (size_t i = 0; i < cmdlen; i++) {
906 tracepoint(librados, rados_mon_command_cmd, cmd[i]);
907 cmdvec.push_back(cmd[i]);
908 }
909
910 inbl.append(inbuf, inbuflen);
911 int ret = client->mon_command(cmdvec, inbl, &outbl, &outstring);
912
913 do_out_buffer(outbl, outbuf, outbuflen);
914 do_out_buffer(outstring, outs, outslen);
915 tracepoint(librados, rados_mon_command_exit, ret, outbuf, outbuflen, outs, outslen);
916 return ret;
917 }
918 LIBRADOS_C_API_BASE_DEFAULT(rados_mon_command);
919
920 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_mon_command_target)(
921 rados_t cluster,
922 const char *name,
923 const char **cmd, size_t cmdlen,
924 const char *inbuf, size_t inbuflen,
925 char **outbuf, size_t *outbuflen,
926 char **outs, size_t *outslen)
927 {
928 tracepoint(librados, rados_mon_command_target_enter, cluster, name, cmdlen, inbuf, inbuflen);
929 librados::RadosClient *client = (librados::RadosClient *)cluster;
930 bufferlist inbl;
931 bufferlist outbl;
932 string outstring;
933 vector<string> cmdvec;
934
935 // is this a numeric id?
936 char *endptr;
937 errno = 0;
938 long rank = strtol(name, &endptr, 10);
939 if ((errno == ERANGE && (rank == LONG_MAX || rank == LONG_MIN)) ||
940 (errno != 0 && rank == 0) ||
941 endptr == name || // no digits
942 *endptr != '\0') { // extra characters
943 rank = -1;
944 }
945
946 for (size_t i = 0; i < cmdlen; i++) {
947 tracepoint(librados, rados_mon_command_target_cmd, cmd[i]);
948 cmdvec.push_back(cmd[i]);
949 }
950
951 inbl.append(inbuf, inbuflen);
952 int ret;
953 if (rank >= 0)
954 ret = client->mon_command(rank, cmdvec, inbl, &outbl, &outstring);
955 else
956 ret = client->mon_command(name, cmdvec, inbl, &outbl, &outstring);
957
958 do_out_buffer(outbl, outbuf, outbuflen);
959 do_out_buffer(outstring, outs, outslen);
960 tracepoint(librados, rados_mon_command_target_exit, ret, outbuf, outbuflen, outs, outslen);
961 return ret;
962 }
963 LIBRADOS_C_API_BASE_DEFAULT(rados_mon_command_target);
964
965 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_osd_command)(
966 rados_t cluster, int osdid, const char **cmd,
967 size_t cmdlen,
968 const char *inbuf, size_t inbuflen,
969 char **outbuf, size_t *outbuflen,
970 char **outs, size_t *outslen)
971 {
972 tracepoint(librados, rados_osd_command_enter, cluster, osdid, cmdlen, inbuf, inbuflen);
973 librados::RadosClient *client = (librados::RadosClient *)cluster;
974 bufferlist inbl;
975 bufferlist outbl;
976 string outstring;
977 vector<string> cmdvec;
978
979 for (size_t i = 0; i < cmdlen; i++) {
980 tracepoint(librados, rados_osd_command_cmd, cmd[i]);
981 cmdvec.push_back(cmd[i]);
982 }
983
984 inbl.append(inbuf, inbuflen);
985 int ret = client->osd_command(osdid, cmdvec, inbl, &outbl, &outstring);
986
987 do_out_buffer(outbl, outbuf, outbuflen);
988 do_out_buffer(outstring, outs, outslen);
989 tracepoint(librados, rados_osd_command_exit, ret, outbuf, outbuflen, outs, outslen);
990 return ret;
991 }
992 LIBRADOS_C_API_BASE_DEFAULT(rados_osd_command);
993
994 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_mgr_command)(
995 rados_t cluster, const char **cmd,
996 size_t cmdlen,
997 const char *inbuf, size_t inbuflen,
998 char **outbuf, size_t *outbuflen,
999 char **outs, size_t *outslen)
1000 {
1001 tracepoint(librados, rados_mgr_command_enter, cluster, cmdlen, inbuf,
1002 inbuflen);
1003
1004 librados::RadosClient *client = (librados::RadosClient *)cluster;
1005 bufferlist inbl;
1006 bufferlist outbl;
1007 string outstring;
1008 vector<string> cmdvec;
1009
1010 for (size_t i = 0; i < cmdlen; i++) {
1011 tracepoint(librados, rados_mgr_command_cmd, cmd[i]);
1012 cmdvec.push_back(cmd[i]);
1013 }
1014
1015 inbl.append(inbuf, inbuflen);
1016 int ret = client->mgr_command(cmdvec, inbl, &outbl, &outstring);
1017
1018 do_out_buffer(outbl, outbuf, outbuflen);
1019 do_out_buffer(outstring, outs, outslen);
1020 tracepoint(librados, rados_mgr_command_exit, ret, outbuf, outbuflen, outs,
1021 outslen);
1022 return ret;
1023 }
1024 LIBRADOS_C_API_BASE_DEFAULT(rados_mgr_command);
1025
1026 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_mgr_command_target)(
1027 rados_t cluster,
1028 const char *name,
1029 const char **cmd,
1030 size_t cmdlen,
1031 const char *inbuf, size_t inbuflen,
1032 char **outbuf, size_t *outbuflen,
1033 char **outs, size_t *outslen)
1034 {
1035 tracepoint(librados, rados_mgr_command_target_enter, cluster, name, cmdlen,
1036 inbuf, inbuflen);
1037
1038 librados::RadosClient *client = (librados::RadosClient *)cluster;
1039 bufferlist inbl;
1040 bufferlist outbl;
1041 string outstring;
1042 vector<string> cmdvec;
1043
1044 for (size_t i = 0; i < cmdlen; i++) {
1045 tracepoint(librados, rados_mgr_command_target_cmd, cmd[i]);
1046 cmdvec.push_back(cmd[i]);
1047 }
1048
1049 inbl.append(inbuf, inbuflen);
1050 int ret = client->mgr_command(name, cmdvec, inbl, &outbl, &outstring);
1051
1052 do_out_buffer(outbl, outbuf, outbuflen);
1053 do_out_buffer(outstring, outs, outslen);
1054 tracepoint(librados, rados_mgr_command_target_exit, ret, outbuf, outbuflen,
1055 outs, outslen);
1056 return ret;
1057 }
1058 LIBRADOS_C_API_BASE_DEFAULT(rados_mgr_command_target);
1059
1060 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pg_command)(
1061 rados_t cluster, const char *pgstr,
1062 const char **cmd, size_t cmdlen,
1063 const char *inbuf, size_t inbuflen,
1064 char **outbuf, size_t *outbuflen,
1065 char **outs, size_t *outslen)
1066 {
1067 tracepoint(librados, rados_pg_command_enter, cluster, pgstr, cmdlen, inbuf, inbuflen);
1068 librados::RadosClient *client = (librados::RadosClient *)cluster;
1069 bufferlist inbl;
1070 bufferlist outbl;
1071 string outstring;
1072 pg_t pgid;
1073 vector<string> cmdvec;
1074
1075 for (size_t i = 0; i < cmdlen; i++) {
1076 tracepoint(librados, rados_pg_command_cmd, cmd[i]);
1077 cmdvec.push_back(cmd[i]);
1078 }
1079
1080 inbl.append(inbuf, inbuflen);
1081 if (!pgid.parse(pgstr))
1082 return -EINVAL;
1083
1084 int ret = client->pg_command(pgid, cmdvec, inbl, &outbl, &outstring);
1085
1086 do_out_buffer(outbl, outbuf, outbuflen);
1087 do_out_buffer(outstring, outs, outslen);
1088 tracepoint(librados, rados_pg_command_exit, ret, outbuf, outbuflen, outs, outslen);
1089 return ret;
1090 }
1091 LIBRADOS_C_API_BASE_DEFAULT(rados_pg_command);
1092
1093 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_buffer_free)(char *buf)
1094 {
1095 tracepoint(librados, rados_buffer_free_enter, buf);
1096 if (buf)
1097 free(buf);
1098 tracepoint(librados, rados_buffer_free_exit);
1099 }
1100 LIBRADOS_C_API_BASE_DEFAULT(rados_buffer_free);
1101
1102 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_monitor_log)(
1103 rados_t cluster,
1104 const char *level,
1105 rados_log_callback_t cb,
1106 void *arg)
1107 {
1108 tracepoint(librados, rados_monitor_log_enter, cluster, level, cb, arg);
1109 librados::RadosClient *client = (librados::RadosClient *)cluster;
1110 int retval = client->monitor_log(level, cb, nullptr, arg);
1111 tracepoint(librados, rados_monitor_log_exit, retval);
1112 return retval;
1113 }
1114 LIBRADOS_C_API_BASE_DEFAULT(rados_monitor_log);
1115
1116 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_monitor_log2)(
1117 rados_t cluster,
1118 const char *level,
1119 rados_log_callback2_t cb,
1120 void *arg)
1121 {
1122 tracepoint(librados, rados_monitor_log2_enter, cluster, level, cb, arg);
1123 librados::RadosClient *client = (librados::RadosClient *)cluster;
1124 int retval = client->monitor_log(level, nullptr, cb, arg);
1125 tracepoint(librados, rados_monitor_log2_exit, retval);
1126 return retval;
1127 }
1128 LIBRADOS_C_API_BASE_DEFAULT(rados_monitor_log2);
1129
1130 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_create)(
1131 rados_t cluster,
1132 const char *name,
1133 rados_ioctx_t *io)
1134 {
1135 tracepoint(librados, rados_ioctx_create_enter, cluster, name);
1136 librados::RadosClient *client = (librados::RadosClient *)cluster;
1137 librados::IoCtxImpl *ctx;
1138
1139 int r = client->create_ioctx(name, &ctx);
1140 if (r < 0) {
1141 tracepoint(librados, rados_ioctx_create_exit, r, NULL);
1142 return r;
1143 }
1144
1145 *io = ctx;
1146 ctx->get();
1147 tracepoint(librados, rados_ioctx_create_exit, 0, ctx);
1148 return 0;
1149 }
1150 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_create);
1151
1152 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_create2)(
1153 rados_t cluster,
1154 int64_t pool_id,
1155 rados_ioctx_t *io)
1156 {
1157 tracepoint(librados, rados_ioctx_create2_enter, cluster, pool_id);
1158 librados::RadosClient *client = (librados::RadosClient *)cluster;
1159 librados::IoCtxImpl *ctx;
1160
1161 int r = client->create_ioctx(pool_id, &ctx);
1162 if (r < 0) {
1163 tracepoint(librados, rados_ioctx_create2_exit, r, NULL);
1164 return r;
1165 }
1166
1167 *io = ctx;
1168 ctx->get();
1169 tracepoint(librados, rados_ioctx_create2_exit, 0, ctx);
1170 return 0;
1171 }
1172 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_create2);
1173
1174 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_ioctx_destroy)(rados_ioctx_t io)
1175 {
1176 tracepoint(librados, rados_ioctx_destroy_enter, io);
1177 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1178 if (ctx) {
1179 ctx->put();
1180 }
1181 tracepoint(librados, rados_ioctx_destroy_exit);
1182 }
1183 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_destroy);
1184
1185 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_stat)(
1186 rados_ioctx_t io,
1187 struct rados_pool_stat_t *stats)
1188 {
1189 tracepoint(librados, rados_ioctx_pool_stat_enter, io);
1190 librados::IoCtxImpl *io_ctx_impl = (librados::IoCtxImpl *)io;
1191 list<string> ls;
1192 std::string pool_name;
1193
1194 int err = io_ctx_impl->client->pool_get_name(io_ctx_impl->get_id(), &pool_name);
1195 if (err) {
1196 tracepoint(librados, rados_ioctx_pool_stat_exit, err, stats);
1197 return err;
1198 }
1199 ls.push_back(pool_name);
1200
1201 map<string, ::pool_stat_t> rawresult;
1202 bool per_pool = false;
1203 err = io_ctx_impl->client->get_pool_stats(ls, &rawresult, &per_pool);
1204 if (err) {
1205 tracepoint(librados, rados_ioctx_pool_stat_exit, err, stats);
1206 return err;
1207 }
1208
1209 ::pool_stat_t& r = rawresult[pool_name];
1210 uint64_t allocated_bytes = r.get_allocated_data_bytes(per_pool) +
1211 r.get_allocated_omap_bytes(per_pool);
1212 // FIXME: raw_used_rate is unknown hence use 1.0 here
1213 // meaning we keep net amount aggregated over all replicas
1214 // Not a big deal so far since this field isn't exposed
1215 uint64_t user_bytes = r.get_user_data_bytes(1.0, per_pool) +
1216 r.get_user_omap_bytes(1.0, per_pool);
1217
1218 stats->num_kb = shift_round_up(allocated_bytes, 10);
1219 stats->num_bytes = allocated_bytes;
1220 stats->num_objects = r.stats.sum.num_objects;
1221 stats->num_object_clones = r.stats.sum.num_object_clones;
1222 stats->num_object_copies = r.stats.sum.num_object_copies;
1223 stats->num_objects_missing_on_primary = r.stats.sum.num_objects_missing_on_primary;
1224 stats->num_objects_unfound = r.stats.sum.num_objects_unfound;
1225 stats->num_objects_degraded =
1226 r.stats.sum.num_objects_degraded +
1227 r.stats.sum.num_objects_misplaced; // FIXME: this is imprecise
1228 stats->num_rd = r.stats.sum.num_rd;
1229 stats->num_rd_kb = r.stats.sum.num_rd_kb;
1230 stats->num_wr = r.stats.sum.num_wr;
1231 stats->num_wr_kb = r.stats.sum.num_wr_kb;
1232 stats->num_user_bytes = user_bytes;
1233 stats->compressed_bytes_orig = r.store_stats.data_compressed_original;
1234 stats->compressed_bytes = r.store_stats.data_compressed;
1235 stats->compressed_bytes_alloc = r.store_stats.data_compressed_allocated;
1236
1237 tracepoint(librados, rados_ioctx_pool_stat_exit, 0, stats);
1238 return 0;
1239 }
1240 LIBRADOS_C_API_DEFAULT(rados_ioctx_pool_stat, 14.2.0);
1241
1242 extern "C" int LIBRADOS_C_API_BASE_F(rados_ioctx_pool_stat)(
1243 rados_ioctx_t io, struct __librados_base::rados_pool_stat_t *stats)
1244 {
1245 struct rados_pool_stat_t new_stats;
1246 int r = LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_stat)(io, &new_stats);
1247 if (r < 0) {
1248 return r;
1249 }
1250
1251 stats->num_bytes = new_stats.num_bytes;
1252 stats->num_kb = new_stats.num_kb;
1253 stats->num_objects = new_stats.num_objects;
1254 stats->num_object_clones = new_stats.num_object_clones;
1255 stats->num_object_copies = new_stats.num_object_copies;
1256 stats->num_objects_missing_on_primary = new_stats.num_objects_missing_on_primary;
1257 stats->num_objects_unfound = new_stats.num_objects_unfound;
1258 stats->num_objects_degraded = new_stats.num_objects_degraded;
1259 stats->num_rd = new_stats.num_rd;
1260 stats->num_rd_kb = new_stats.num_rd_kb;
1261 stats->num_wr = new_stats.num_wr;
1262 stats->num_wr_kb = new_stats.num_wr_kb;
1263 return 0;
1264 }
1265 LIBRADOS_C_API_BASE(rados_ioctx_pool_stat);
1266
1267 extern "C" rados_config_t LIBRADOS_C_API_DEFAULT_F(rados_ioctx_cct)(
1268 rados_ioctx_t io)
1269 {
1270 tracepoint(librados, rados_ioctx_cct_enter, io);
1271 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1272 rados_config_t retval = (rados_config_t)ctx->client->cct;
1273 tracepoint(librados, rados_ioctx_cct_exit, retval);
1274 return retval;
1275 }
1276 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_cct);
1277
1278 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_set_read)(
1279 rados_ioctx_t io,
1280 rados_snap_t seq)
1281 {
1282 tracepoint(librados, rados_ioctx_snap_set_read_enter, io, seq);
1283 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1284 ctx->set_snap_read((snapid_t)seq);
1285 tracepoint(librados, rados_ioctx_snap_set_read_exit);
1286 }
1287 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_set_read);
1288
1289 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_selfmanaged_snap_set_write_ctx)(
1290 rados_ioctx_t io,
1291 rados_snap_t seq,
1292 rados_snap_t *snaps,
1293 int num_snaps)
1294 {
1295 tracepoint(librados, rados_ioctx_selfmanaged_snap_set_write_ctx_enter, io, seq, snaps, num_snaps);
1296 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1297 vector<snapid_t> snv;
1298 snv.resize(num_snaps);
1299 for (int i=0; i<num_snaps; i++) {
1300 snv[i] = (snapid_t)snaps[i];
1301 }
1302 int retval = ctx->set_snap_write_context((snapid_t)seq, snv);
1303 tracepoint(librados, rados_ioctx_selfmanaged_snap_set_write_ctx_exit, retval);
1304 return retval;
1305 }
1306 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_selfmanaged_snap_set_write_ctx);
1307
1308 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_write)(
1309 rados_ioctx_t io,
1310 const char *o,
1311 const char *buf,
1312 size_t len,
1313 uint64_t off)
1314 {
1315 tracepoint(librados, rados_write_enter, io, o, buf, len, off);
1316 if (len > UINT_MAX/2)
1317 return -E2BIG;
1318 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1319 object_t oid(o);
1320 bufferlist bl;
1321 bl.append(buf, len);
1322 int retval = ctx->write(oid, bl, len, off);
1323 tracepoint(librados, rados_write_exit, retval);
1324 return retval;
1325 }
1326 LIBRADOS_C_API_BASE_DEFAULT(rados_write);
1327
1328 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_append)(
1329 rados_ioctx_t io,
1330 const char *o,
1331 const char *buf,
1332 size_t len)
1333 {
1334 tracepoint(librados, rados_append_enter, io, o, buf, len);
1335 if (len > UINT_MAX/2)
1336 return -E2BIG;
1337 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1338 object_t oid(o);
1339 bufferlist bl;
1340 bl.append(buf, len);
1341 int retval = ctx->append(oid, bl, len);
1342 tracepoint(librados, rados_append_exit, retval);
1343 return retval;
1344 }
1345 LIBRADOS_C_API_BASE_DEFAULT(rados_append);
1346
1347 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_write_full)(
1348 rados_ioctx_t io,
1349 const char *o,
1350 const char *buf,
1351 size_t len)
1352 {
1353 tracepoint(librados, rados_write_full_enter, io, o, buf, len);
1354 if (len > UINT_MAX/2)
1355 return -E2BIG;
1356 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1357 object_t oid(o);
1358 bufferlist bl;
1359 bl.append(buf, len);
1360 int retval = ctx->write_full(oid, bl);
1361 tracepoint(librados, rados_write_full_exit, retval);
1362 return retval;
1363 }
1364 LIBRADOS_C_API_BASE_DEFAULT(rados_write_full);
1365
1366 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_writesame)(
1367 rados_ioctx_t io,
1368 const char *o,
1369 const char *buf,
1370 size_t data_len,
1371 size_t write_len,
1372 uint64_t off)
1373 {
1374 tracepoint(librados, rados_writesame_enter, io, o, buf, data_len, write_len, off);
1375 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1376 object_t oid(o);
1377 bufferlist bl;
1378 bl.append(buf, data_len);
1379 int retval = ctx->writesame(oid, bl, write_len, off);
1380 tracepoint(librados, rados_writesame_exit, retval);
1381 return retval;
1382 }
1383 LIBRADOS_C_API_BASE_DEFAULT(rados_writesame);
1384
1385 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_trunc)(
1386 rados_ioctx_t io,
1387 const char *o,
1388 uint64_t size)
1389 {
1390 tracepoint(librados, rados_trunc_enter, io, o, size);
1391 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1392 object_t oid(o);
1393 int retval = ctx->trunc(oid, size);
1394 tracepoint(librados, rados_trunc_exit, retval);
1395 return retval;
1396 }
1397 LIBRADOS_C_API_BASE_DEFAULT(rados_trunc);
1398
1399 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_remove)(
1400 rados_ioctx_t io,
1401 const char *o)
1402 {
1403 tracepoint(librados, rados_remove_enter, io, o);
1404 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1405 object_t oid(o);
1406 int retval = ctx->remove(oid);
1407 tracepoint(librados, rados_remove_exit, retval);
1408 return retval;
1409 }
1410 LIBRADOS_C_API_BASE_DEFAULT(rados_remove);
1411
1412 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_read)(
1413 rados_ioctx_t io,
1414 const char *o,
1415 char *buf,
1416 size_t len,
1417 uint64_t off)
1418 {
1419 tracepoint(librados, rados_read_enter, io, o, buf, len, off);
1420 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1421 int ret;
1422 object_t oid(o);
1423
1424 bufferlist bl;
1425 bufferptr bp = buffer::create_static(len, buf);
1426 bl.push_back(bp);
1427
1428 ret = ctx->read(oid, bl, len, off);
1429 if (ret >= 0) {
1430 if (bl.length() > len) {
1431 tracepoint(librados, rados_read_exit, -ERANGE, NULL);
1432 return -ERANGE;
1433 }
1434 if (!bl.is_provided_buffer(buf))
1435 bl.begin().copy(bl.length(), buf);
1436 ret = bl.length(); // hrm :/
1437 }
1438
1439 tracepoint(librados, rados_read_exit, ret, buf);
1440 return ret;
1441 }
1442 LIBRADOS_C_API_BASE_DEFAULT(rados_read);
1443
1444 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_checksum)(
1445 rados_ioctx_t io, const char *o,
1446 rados_checksum_type_t type,
1447 const char *init_value, size_t init_value_len,
1448 size_t len, uint64_t off, size_t chunk_size,
1449 char *pchecksum, size_t checksum_len)
1450 {
1451 tracepoint(librados, rados_checksum_enter, io, o, type, init_value,
1452 init_value_len, len, off, chunk_size);
1453 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1454 object_t oid(o);
1455
1456 bufferlist init_value_bl;
1457 init_value_bl.append(init_value, init_value_len);
1458
1459 bufferlist checksum_bl;
1460
1461 int retval = ctx->checksum(oid, get_checksum_op_type(type), init_value_bl,
1462 len, off, chunk_size, &checksum_bl);
1463 if (retval >= 0) {
1464 if (checksum_bl.length() > checksum_len) {
1465 tracepoint(librados, rados_checksum_exit, -ERANGE, NULL, 0);
1466 return -ERANGE;
1467 }
1468
1469 checksum_bl.begin().copy(checksum_bl.length(), pchecksum);
1470 }
1471 tracepoint(librados, rados_checksum_exit, retval, pchecksum, checksum_len);
1472 return retval;
1473 }
1474 LIBRADOS_C_API_BASE_DEFAULT(rados_checksum);
1475
1476 extern "C" uint64_t LIBRADOS_C_API_DEFAULT_F(rados_get_last_version)(
1477 rados_ioctx_t io)
1478 {
1479 tracepoint(librados, rados_get_last_version_enter, io);
1480 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1481 uint64_t retval = ctx->last_version();
1482 tracepoint(librados, rados_get_last_version_exit, retval);
1483 return retval;
1484 }
1485 LIBRADOS_C_API_BASE_DEFAULT(rados_get_last_version);
1486
1487 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_create)(
1488 rados_t cluster,
1489 const char *name)
1490 {
1491 tracepoint(librados, rados_pool_create_enter, cluster, name);
1492 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
1493 string sname(name);
1494 int retval = radosp->pool_create(sname);
1495 tracepoint(librados, rados_pool_create_exit, retval);
1496 return retval;
1497 }
1498 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_create);
1499
1500 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_create_with_auid)(
1501 rados_t cluster,
1502 const char *name,
1503 uint64_t auid)
1504 {
1505 tracepoint(librados, rados_pool_create_with_auid_enter, cluster, name, auid);
1506 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
1507 string sname(name);
1508 int retval = 0;
1509 if (auid != CEPH_AUTH_UID_DEFAULT) {
1510 retval = -EINVAL;
1511 } else {
1512 retval = radosp->pool_create(sname);
1513 }
1514 tracepoint(librados, rados_pool_create_with_auid_exit, retval);
1515 return retval;
1516 }
1517 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_create_with_auid);
1518
1519 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_create_with_crush_rule)(
1520 rados_t cluster,
1521 const char *name,
1522 __u8 crush_rule_num)
1523 {
1524 tracepoint(librados, rados_pool_create_with_crush_rule_enter, cluster, name, crush_rule_num);
1525 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
1526 string sname(name);
1527 int retval = radosp->pool_create(sname, crush_rule_num);
1528 tracepoint(librados, rados_pool_create_with_crush_rule_exit, retval);
1529 return retval;
1530 }
1531 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_create_with_crush_rule);
1532
1533 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_create_with_all)(
1534 rados_t cluster,
1535 const char *name,
1536 uint64_t auid,
1537 __u8 crush_rule_num)
1538 {
1539 tracepoint(librados, rados_pool_create_with_all_enter, cluster, name, auid, crush_rule_num);
1540 librados::RadosClient *radosp = (librados::RadosClient *)cluster;
1541 string sname(name);
1542 int retval = 0;
1543 if (auid != CEPH_AUTH_UID_DEFAULT) {
1544 retval = -EINVAL;
1545 } else {
1546 retval = radosp->pool_create(sname, crush_rule_num);
1547 }
1548 tracepoint(librados, rados_pool_create_with_all_exit, retval);
1549 return retval;
1550 }
1551 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_create_with_all);
1552
1553 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_get_base_tier)(
1554 rados_t cluster,
1555 int64_t pool_id,
1556 int64_t* base_tier)
1557 {
1558 tracepoint(librados, rados_pool_get_base_tier_enter, cluster, pool_id);
1559 librados::RadosClient *client = (librados::RadosClient *)cluster;
1560 int retval = client->pool_get_base_tier(pool_id, base_tier);
1561 tracepoint(librados, rados_pool_get_base_tier_exit, retval, *base_tier);
1562 return retval;
1563 }
1564 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_get_base_tier);
1565
1566 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_pool_delete)(
1567 rados_t cluster,
1568 const char *pool_name)
1569 {
1570 tracepoint(librados, rados_pool_delete_enter, cluster, pool_name);
1571 librados::RadosClient *client = (librados::RadosClient *)cluster;
1572 int retval = client->pool_delete(pool_name);
1573 tracepoint(librados, rados_pool_delete_exit, retval);
1574 return retval;
1575 }
1576 LIBRADOS_C_API_BASE_DEFAULT(rados_pool_delete);
1577
1578 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_set_auid)(
1579 rados_ioctx_t io,
1580 uint64_t auid)
1581 {
1582 tracepoint(librados, rados_ioctx_pool_set_auid_enter, io, auid);
1583 int retval = -EOPNOTSUPP;
1584 tracepoint(librados, rados_ioctx_pool_set_auid_exit, retval);
1585 return retval;
1586 }
1587 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_set_auid);
1588
1589 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_get_auid)(
1590 rados_ioctx_t io,
1591 uint64_t *auid)
1592 {
1593 tracepoint(librados, rados_ioctx_pool_get_auid_enter, io);
1594 int retval = -EOPNOTSUPP;
1595 tracepoint(librados, rados_ioctx_pool_get_auid_exit, retval, *auid);
1596 return retval;
1597 }
1598 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_get_auid);
1599
1600 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_requires_alignment)(
1601 rados_ioctx_t io)
1602 {
1603 tracepoint(librados, rados_ioctx_pool_requires_alignment_enter, io);
1604 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1605 int retval = ctx->client->pool_requires_alignment(ctx->get_id());
1606 tracepoint(librados, rados_ioctx_pool_requires_alignment_exit, retval);
1607 return retval;
1608 }
1609 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_requires_alignment);
1610
1611 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_requires_alignment2)(
1612 rados_ioctx_t io,
1613 int *req)
1614 {
1615 tracepoint(librados, rados_ioctx_pool_requires_alignment_enter2, io);
1616 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1617 bool requires_alignment;
1618 int retval = ctx->client->pool_requires_alignment2(ctx->get_id(),
1619 &requires_alignment);
1620 tracepoint(librados, rados_ioctx_pool_requires_alignment_exit2, retval,
1621 requires_alignment);
1622 if (req)
1623 *req = requires_alignment;
1624 return retval;
1625 }
1626 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_requires_alignment2);
1627
1628 extern "C" uint64_t LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_required_alignment)(
1629 rados_ioctx_t io)
1630 {
1631 tracepoint(librados, rados_ioctx_pool_required_alignment_enter, io);
1632 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1633 uint64_t retval = ctx->client->pool_required_alignment(ctx->get_id());
1634 tracepoint(librados, rados_ioctx_pool_required_alignment_exit, retval);
1635 return retval;
1636 }
1637 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_required_alignment);
1638
1639 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_pool_required_alignment2)(
1640 rados_ioctx_t io,
1641 uint64_t *alignment)
1642 {
1643 tracepoint(librados, rados_ioctx_pool_required_alignment_enter2, io);
1644 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1645 int retval = ctx->client->pool_required_alignment2(ctx->get_id(),
1646 alignment);
1647 tracepoint(librados, rados_ioctx_pool_required_alignment_exit2, retval,
1648 *alignment);
1649 return retval;
1650 }
1651 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_pool_required_alignment2);
1652
1653 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_ioctx_locator_set_key)(
1654 rados_ioctx_t io,
1655 const char *key)
1656 {
1657 tracepoint(librados, rados_ioctx_locator_set_key_enter, io, key);
1658 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1659 if (key)
1660 ctx->oloc.key = key;
1661 else
1662 ctx->oloc.key = "";
1663 tracepoint(librados, rados_ioctx_locator_set_key_exit);
1664 }
1665 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_locator_set_key);
1666
1667 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_ioctx_set_namespace)(
1668 rados_ioctx_t io,
1669 const char *nspace)
1670 {
1671 tracepoint(librados, rados_ioctx_set_namespace_enter, io, nspace);
1672 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1673 if (nspace)
1674 ctx->oloc.nspace = nspace;
1675 else
1676 ctx->oloc.nspace = "";
1677 tracepoint(librados, rados_ioctx_set_namespace_exit);
1678 }
1679 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_set_namespace);
1680
1681 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_get_namespace)(
1682 rados_ioctx_t io,
1683 char *s,
1684 unsigned maxlen)
1685 {
1686 tracepoint(librados, rados_ioctx_get_namespace_enter, io, maxlen);
1687 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1688 auto length = ctx->oloc.nspace.length();
1689 if (length >= maxlen) {
1690 tracepoint(librados, rados_ioctx_get_namespace_exit, -ERANGE, "");
1691 return -ERANGE;
1692 }
1693 strcpy(s, ctx->oloc.nspace.c_str());
1694 int retval = (int)length;
1695 tracepoint(librados, rados_ioctx_get_namespace_exit, retval, s);
1696 return retval;
1697 }
1698 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_get_namespace);
1699
1700 extern "C" rados_t LIBRADOS_C_API_DEFAULT_F(rados_ioctx_get_cluster)(
1701 rados_ioctx_t io)
1702 {
1703 tracepoint(librados, rados_ioctx_get_cluster_enter, io);
1704 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1705 rados_t retval = (rados_t)ctx->client;
1706 tracepoint(librados, rados_ioctx_get_cluster_exit, retval);
1707 return retval;
1708 }
1709 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_get_cluster);
1710
1711 extern "C" int64_t LIBRADOS_C_API_DEFAULT_F(rados_ioctx_get_id)(
1712 rados_ioctx_t io)
1713 {
1714 tracepoint(librados, rados_ioctx_get_id_enter, io);
1715 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1716 int64_t retval = ctx->get_id();
1717 tracepoint(librados, rados_ioctx_get_id_exit, retval);
1718 return retval;
1719 }
1720 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_get_id);
1721
1722 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_get_pool_name)(
1723 rados_ioctx_t io,
1724 char *s,
1725 unsigned maxlen)
1726 {
1727 tracepoint(librados, rados_ioctx_get_pool_name_enter, io, maxlen);
1728 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1729 std::string pool_name;
1730
1731 int err = ctx->client->pool_get_name(ctx->get_id(), &pool_name);
1732 if (err) {
1733 tracepoint(librados, rados_ioctx_get_pool_name_exit, err, "");
1734 return err;
1735 }
1736 if (pool_name.length() >= maxlen) {
1737 tracepoint(librados, rados_ioctx_get_pool_name_exit, -ERANGE, "");
1738 return -ERANGE;
1739 }
1740 strcpy(s, pool_name.c_str());
1741 int retval = pool_name.length();
1742 tracepoint(librados, rados_ioctx_get_pool_name_exit, retval, s);
1743 return retval;
1744 }
1745 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_get_pool_name);
1746
1747 // snaps
1748
1749 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_create)(
1750 rados_ioctx_t io,
1751 const char *snapname)
1752 {
1753 tracepoint(librados, rados_ioctx_snap_create_enter, io, snapname);
1754 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1755 int retval = ctx->snap_create(snapname);
1756 tracepoint(librados, rados_ioctx_snap_create_exit, retval);
1757 return retval;
1758 }
1759 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_create);
1760
1761 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_remove)(
1762 rados_ioctx_t io,
1763 const char *snapname)
1764 {
1765 tracepoint(librados, rados_ioctx_snap_remove_enter, io, snapname);
1766 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1767 int retval = ctx->snap_remove(snapname);
1768 tracepoint(librados, rados_ioctx_snap_remove_exit, retval);
1769 return retval;
1770 }
1771 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_remove);
1772
1773 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_rollback)(
1774 rados_ioctx_t io,
1775 const char *oid,
1776 const char *snapname)
1777 {
1778 tracepoint(librados, rados_ioctx_snap_rollback_enter, io, oid, snapname);
1779 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1780 int retval = ctx->rollback(oid, snapname);
1781 tracepoint(librados, rados_ioctx_snap_rollback_exit, retval);
1782 return retval;
1783 }
1784 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_rollback);
1785
1786 // Deprecated name kept for backward compatibility
1787 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_rollback)(
1788 rados_ioctx_t io,
1789 const char *oid,
1790 const char *snapname)
1791 {
1792 return LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_rollback)(io, oid, snapname);
1793 }
1794 LIBRADOS_C_API_BASE_DEFAULT(rados_rollback);
1795
1796 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_selfmanaged_snap_create)(
1797 rados_ioctx_t io,
1798 uint64_t *snapid)
1799 {
1800 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_enter, io);
1801 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1802 int retval = ctx->selfmanaged_snap_create(snapid);
1803 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_exit, retval, *snapid);
1804 return retval;
1805 }
1806 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_selfmanaged_snap_create);
1807
1808 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_aio_ioctx_selfmanaged_snap_create)(
1809 rados_ioctx_t io,
1810 rados_snap_t *snapid,
1811 rados_completion_t completion)
1812 {
1813 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_enter, io);
1814 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1815 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
1816 ctx->aio_selfmanaged_snap_create(snapid, c);
1817 tracepoint(librados, rados_ioctx_selfmanaged_snap_create_exit, 0, 0);
1818 }
1819 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_ioctx_selfmanaged_snap_create);
1820
1821 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_selfmanaged_snap_remove)(
1822 rados_ioctx_t io,
1823 uint64_t snapid)
1824 {
1825 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_enter, io, snapid);
1826 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1827 int retval = ctx->selfmanaged_snap_remove(snapid);
1828 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_exit, retval);
1829 return retval;
1830 }
1831 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_selfmanaged_snap_remove);
1832
1833 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_aio_ioctx_selfmanaged_snap_remove)(
1834 rados_ioctx_t io,
1835 rados_snap_t snapid,
1836 rados_completion_t completion)
1837 {
1838 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_enter, io, snapid);
1839 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1840 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
1841 ctx->aio_selfmanaged_snap_remove(snapid, c);
1842 tracepoint(librados, rados_ioctx_selfmanaged_snap_remove_exit, 0);
1843 }
1844 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_ioctx_selfmanaged_snap_remove);
1845
1846 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_selfmanaged_snap_rollback)(
1847 rados_ioctx_t io,
1848 const char *oid,
1849 uint64_t snapid)
1850 {
1851 tracepoint(librados, rados_ioctx_selfmanaged_snap_rollback_enter, io, oid, snapid);
1852 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1853 int retval = ctx->selfmanaged_snap_rollback_object(oid, ctx->snapc, snapid);
1854 tracepoint(librados, rados_ioctx_selfmanaged_snap_rollback_exit, retval);
1855 return retval;
1856 }
1857 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_selfmanaged_snap_rollback);
1858
1859 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_list)(
1860 rados_ioctx_t io,
1861 rados_snap_t *snaps,
1862 int maxlen)
1863 {
1864 tracepoint(librados, rados_ioctx_snap_list_enter, io, maxlen);
1865 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1866 vector<uint64_t> snapvec;
1867 int r = ctx->snap_list(&snapvec);
1868 if (r < 0) {
1869 tracepoint(librados, rados_ioctx_snap_list_exit, r, snaps, 0);
1870 return r;
1871 }
1872 if ((int)snapvec.size() <= maxlen) {
1873 for (unsigned i=0; i<snapvec.size(); i++) {
1874 snaps[i] = snapvec[i];
1875 }
1876 int retval = snapvec.size();
1877 tracepoint(librados, rados_ioctx_snap_list_exit, retval, snaps, retval);
1878 return retval;
1879 }
1880 int retval = -ERANGE;
1881 tracepoint(librados, rados_ioctx_snap_list_exit, retval, snaps, 0);
1882 return retval;
1883 }
1884 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_list);
1885
1886 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_lookup)(
1887 rados_ioctx_t io,
1888 const char *name,
1889 rados_snap_t *id)
1890 {
1891 tracepoint(librados, rados_ioctx_snap_lookup_enter, io, name);
1892 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1893 int retval = ctx->snap_lookup(name, (uint64_t *)id);
1894 tracepoint(librados, rados_ioctx_snap_lookup_exit, retval, *id);
1895 return retval;
1896 }
1897 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_lookup);
1898
1899 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_get_name)(
1900 rados_ioctx_t io,
1901 rados_snap_t id,
1902 char *name,
1903 int maxlen)
1904 {
1905 tracepoint(librados, rados_ioctx_snap_get_name_enter, io, id, maxlen);
1906 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1907 std::string sname;
1908 int r = ctx->snap_get_name(id, &sname);
1909 if (r < 0) {
1910 tracepoint(librados, rados_ioctx_snap_get_name_exit, r, "");
1911 return r;
1912 }
1913 if ((int)sname.length() >= maxlen) {
1914 int retval = -ERANGE;
1915 tracepoint(librados, rados_ioctx_snap_get_name_exit, retval, "");
1916 return retval;
1917 }
1918 strncpy(name, sname.c_str(), maxlen);
1919 tracepoint(librados, rados_ioctx_snap_get_name_exit, 0, name);
1920 return 0;
1921 }
1922 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_get_name);
1923
1924 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_ioctx_snap_get_stamp)(
1925 rados_ioctx_t io,
1926 rados_snap_t id,
1927 time_t *t)
1928 {
1929 tracepoint(librados, rados_ioctx_snap_get_stamp_enter, io, id);
1930 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1931 int retval = ctx->snap_get_stamp(id, t);
1932 tracepoint(librados, rados_ioctx_snap_get_stamp_exit, retval, *t);
1933 return retval;
1934 }
1935 LIBRADOS_C_API_BASE_DEFAULT(rados_ioctx_snap_get_stamp);
1936
1937 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_cmpext)(
1938 rados_ioctx_t io,
1939 const char *o,
1940 const char *cmp_buf,
1941 size_t cmp_len,
1942 uint64_t off)
1943 {
1944 tracepoint(librados, rados_cmpext_enter, io, o, cmp_buf, cmp_len, off);
1945 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1946 int ret;
1947 object_t oid(o);
1948
1949 bufferlist cmp_bl;
1950 cmp_bl.append(cmp_buf, cmp_len);
1951
1952 ret = ctx->cmpext(oid, off, cmp_bl);
1953 tracepoint(librados, rados_cmpext_exit, ret);
1954
1955 return ret;
1956 }
1957 LIBRADOS_C_API_BASE_DEFAULT(rados_cmpext);
1958
1959 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_getxattr)(
1960 rados_ioctx_t io,
1961 const char *o,
1962 const char *name,
1963 char *buf,
1964 size_t len)
1965 {
1966 tracepoint(librados, rados_getxattr_enter, io, o, name, len);
1967 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
1968 int ret;
1969 object_t oid(o);
1970 bufferlist bl;
1971 bl.push_back(buffer::create_static(len, buf));
1972 ret = ctx->getxattr(oid, name, bl);
1973 if (ret >= 0) {
1974 if (bl.length() > len) {
1975 tracepoint(librados, rados_getxattr_exit, -ERANGE, buf, 0);
1976 return -ERANGE;
1977 }
1978 if (!bl.is_provided_buffer(buf))
1979 bl.begin().copy(bl.length(), buf);
1980 ret = bl.length();
1981 }
1982
1983 tracepoint(librados, rados_getxattr_exit, ret, buf, ret);
1984 return ret;
1985 }
1986 LIBRADOS_C_API_BASE_DEFAULT(rados_getxattr);
1987
1988 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_getxattrs)(
1989 rados_ioctx_t io,
1990 const char *oid,
1991 rados_xattrs_iter_t *iter)
1992 {
1993 tracepoint(librados, rados_getxattrs_enter, io, oid);
1994 librados::RadosXattrsIter *it = new librados::RadosXattrsIter();
1995 if (!it) {
1996 tracepoint(librados, rados_getxattrs_exit, -ENOMEM, NULL);
1997 return -ENOMEM;
1998 }
1999 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2000 object_t obj(oid);
2001 int ret = ctx->getxattrs(obj, it->attrset);
2002 if (ret) {
2003 delete it;
2004 tracepoint(librados, rados_getxattrs_exit, ret, NULL);
2005 return ret;
2006 }
2007 it->i = it->attrset.begin();
2008
2009 *iter = it;
2010 tracepoint(librados, rados_getxattrs_exit, 0, *iter);
2011 return 0;
2012 }
2013 LIBRADOS_C_API_BASE_DEFAULT(rados_getxattrs);
2014
2015 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_getxattrs_next)(
2016 rados_xattrs_iter_t iter,
2017 const char **name,
2018 const char **val,
2019 size_t *len)
2020 {
2021 tracepoint(librados, rados_getxattrs_next_enter, iter);
2022 librados::RadosXattrsIter *it = static_cast<librados::RadosXattrsIter*>(iter);
2023 if (it->val) {
2024 free(it->val);
2025 it->val = NULL;
2026 }
2027 if (it->i == it->attrset.end()) {
2028 *name = NULL;
2029 *val = NULL;
2030 *len = 0;
2031 tracepoint(librados, rados_getxattrs_next_exit, 0, NULL, NULL, 0);
2032 return 0;
2033 }
2034 const std::string &s(it->i->first);
2035 *name = s.c_str();
2036 bufferlist &bl(it->i->second);
2037 size_t bl_len = bl.length();
2038 if (!bl_len) {
2039 // malloc(0) is not guaranteed to return a valid pointer
2040 *val = (char *)NULL;
2041 } else {
2042 it->val = (char*)malloc(bl_len);
2043 if (!it->val) {
2044 tracepoint(librados, rados_getxattrs_next_exit, -ENOMEM, *name, NULL, 0);
2045 return -ENOMEM;
2046 }
2047 memcpy(it->val, bl.c_str(), bl_len);
2048 *val = it->val;
2049 }
2050 *len = bl_len;
2051 ++it->i;
2052 tracepoint(librados, rados_getxattrs_next_exit, 0, *name, *val, *len);
2053 return 0;
2054 }
2055 LIBRADOS_C_API_BASE_DEFAULT(rados_getxattrs_next);
2056
2057 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_getxattrs_end)(
2058 rados_xattrs_iter_t iter)
2059 {
2060 tracepoint(librados, rados_getxattrs_end_enter, iter);
2061 librados::RadosXattrsIter *it = static_cast<librados::RadosXattrsIter*>(iter);
2062 delete it;
2063 tracepoint(librados, rados_getxattrs_end_exit);
2064 }
2065 LIBRADOS_C_API_BASE_DEFAULT(rados_getxattrs_end);
2066
2067 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_setxattr)(
2068 rados_ioctx_t io,
2069 const char *o,
2070 const char *name,
2071 const char *buf,
2072 size_t len)
2073 {
2074 tracepoint(librados, rados_setxattr_enter, io, o, name, buf, len);
2075 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2076 object_t oid(o);
2077 bufferlist bl;
2078 bl.append(buf, len);
2079 int retval = ctx->setxattr(oid, name, bl);
2080 tracepoint(librados, rados_setxattr_exit, retval);
2081 return retval;
2082 }
2083 LIBRADOS_C_API_BASE_DEFAULT(rados_setxattr);
2084
2085 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_rmxattr)(
2086 rados_ioctx_t io,
2087 const char *o,
2088 const char *name)
2089 {
2090 tracepoint(librados, rados_rmxattr_enter, io, o, name);
2091 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2092 object_t oid(o);
2093 int retval = ctx->rmxattr(oid, name);
2094 tracepoint(librados, rados_rmxattr_exit, retval);
2095 return retval;
2096 }
2097 LIBRADOS_C_API_BASE_DEFAULT(rados_rmxattr);
2098
2099 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_stat)(
2100 rados_ioctx_t io,
2101 const char *o,
2102 uint64_t *psize,
2103 time_t *pmtime)
2104 {
2105 tracepoint(librados, rados_stat_enter, io, o);
2106 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2107 object_t oid(o);
2108 int retval = ctx->stat(oid, psize, pmtime);
2109 tracepoint(librados, rados_stat_exit, retval, psize, pmtime);
2110 return retval;
2111 }
2112 LIBRADOS_C_API_BASE_DEFAULT(rados_stat);
2113
2114 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_stat2)(
2115 rados_ioctx_t io,
2116 const char *o,
2117 uint64_t *psize,
2118 struct timespec *pmtime)
2119 {
2120 tracepoint(librados, rados_stat2_enter, io, o);
2121 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2122 object_t oid(o);
2123 int retval = ctx->stat2(oid, psize, pmtime);
2124 tracepoint(librados, rados_stat2_exit, retval, psize, pmtime);
2125 return retval;
2126 }
2127 LIBRADOS_C_API_BASE_DEFAULT(rados_stat2);
2128
2129 extern "C" int LIBRADOS_C_API_BASE_F(rados_tmap_update)(
2130 rados_ioctx_t io,
2131 const char *o,
2132 const char *cmdbuf,
2133 size_t cmdbuflen)
2134 {
2135 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2136 object_t oid(o);
2137 bufferlist cmdbl;
2138 cmdbl.append(cmdbuf, cmdbuflen);
2139 return ctx->tmap_update(oid, cmdbl);
2140 }
2141 LIBRADOS_C_API_BASE(rados_tmap_update);
2142
2143 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_tmap_update)(
2144 rados_ioctx_t io,
2145 const char *o,
2146 const char *cmdbuf,
2147 size_t cmdbuflen)
2148 {
2149 return -ENOTSUP;
2150 }
2151 LIBRADOS_C_API_DEFAULT(rados_tmap_update, 14.2.0);
2152
2153 extern "C" int LIBRADOS_C_API_BASE_F(rados_tmap_put)(
2154 rados_ioctx_t io,
2155 const char *o,
2156 const char *buf,
2157 size_t buflen)
2158 {
2159 bufferlist bl;
2160 bl.append(buf, buflen);
2161
2162 bufferlist header;
2163 std::map<std::string, bufferlist> m;
2164 bufferlist::const_iterator bl_it = bl.begin();
2165 decode(header, bl_it);
2166 decode(m, bl_it);
2167
2168 bufferlist out_bl;
2169 encode(header, out_bl);
2170 encode(m, out_bl);
2171
2172 return LIBRADOS_C_API_DEFAULT_F(rados_write_full)(
2173 io, o, out_bl.c_str(), out_bl.length());
2174 }
2175 LIBRADOS_C_API_BASE(rados_tmap_put);
2176
2177 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_tmap_put)(
2178 rados_ioctx_t io,
2179 const char *o,
2180 const char *buf,
2181 size_t buflen)
2182 {
2183 return -EOPNOTSUPP;
2184 }
2185 LIBRADOS_C_API_DEFAULT(rados_tmap_put, 14.2.0);
2186
2187 extern "C" int LIBRADOS_C_API_BASE_F(rados_tmap_get)(
2188 rados_ioctx_t io,
2189 const char *o,
2190 char *buf,
2191 size_t buflen)
2192 {
2193 return LIBRADOS_C_API_DEFAULT_F(rados_read)(io, o, buf, buflen, 0);
2194 }
2195 LIBRADOS_C_API_BASE(rados_tmap_get);
2196
2197 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_tmap_get)(
2198 rados_ioctx_t io,
2199 const char *o,
2200 char *buf,
2201 size_t buflen)
2202 {
2203 return -EOPNOTSUPP;
2204 }
2205 LIBRADOS_C_API_DEFAULT(rados_tmap_get, 14.2.0);
2206
2207 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_exec)(
2208 rados_ioctx_t io,
2209 const char *o,
2210 const char *cls,
2211 const char *method,
2212 const char *inbuf,
2213 size_t in_len,
2214 char *buf,
2215 size_t out_len)
2216 {
2217 tracepoint(librados, rados_exec_enter, io, o, cls, method, inbuf, in_len, out_len);
2218 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2219 object_t oid(o);
2220 bufferlist inbl, outbl;
2221 int ret;
2222 inbl.append(inbuf, in_len);
2223 ret = ctx->exec(oid, cls, method, inbl, outbl);
2224 if (ret >= 0) {
2225 if (outbl.length()) {
2226 if (outbl.length() > out_len) {
2227 tracepoint(librados, rados_exec_exit, -ERANGE, buf, 0);
2228 return -ERANGE;
2229 }
2230 outbl.begin().copy(outbl.length(), buf);
2231 ret = outbl.length(); // hrm :/
2232 }
2233 }
2234 tracepoint(librados, rados_exec_exit, ret, buf, ret);
2235 return ret;
2236 }
2237 LIBRADOS_C_API_BASE_DEFAULT(rados_exec);
2238
2239 extern "C" rados_object_list_cursor LIBRADOS_C_API_DEFAULT_F(rados_object_list_begin)(
2240 rados_ioctx_t io)
2241 {
2242 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2243
2244 hobject_t *result = new hobject_t(ctx->objecter->enumerate_objects_begin());
2245 return (rados_object_list_cursor)result;
2246 }
2247 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_begin);
2248
2249 extern "C" rados_object_list_cursor LIBRADOS_C_API_DEFAULT_F(rados_object_list_end)(
2250 rados_ioctx_t io)
2251 {
2252 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2253
2254 hobject_t *result = new hobject_t(ctx->objecter->enumerate_objects_end());
2255 return (rados_object_list_cursor)result;
2256 }
2257 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_end);
2258
2259 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_object_list_is_end)(
2260 rados_ioctx_t io,
2261 rados_object_list_cursor cur)
2262 {
2263 hobject_t *hobj = (hobject_t*)cur;
2264 return hobj->is_max();
2265 }
2266 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_is_end);
2267
2268 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_object_list_cursor_free)(
2269 rados_ioctx_t io,
2270 rados_object_list_cursor cur)
2271 {
2272 hobject_t *hobj = (hobject_t*)cur;
2273 delete hobj;
2274 }
2275 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_cursor_free);
2276
2277 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_object_list_cursor_cmp)(
2278 rados_ioctx_t io,
2279 rados_object_list_cursor lhs_cur,
2280 rados_object_list_cursor rhs_cur)
2281 {
2282 hobject_t *lhs = (hobject_t*)lhs_cur;
2283 hobject_t *rhs = (hobject_t*)rhs_cur;
2284 return cmp(*lhs, *rhs);
2285 }
2286 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_cursor_cmp);
2287
2288 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_object_list)(rados_ioctx_t io,
2289 const rados_object_list_cursor start,
2290 const rados_object_list_cursor finish,
2291 const size_t result_item_count,
2292 const char *filter_buf,
2293 const size_t filter_buf_len,
2294 rados_object_list_item *result_items,
2295 rados_object_list_cursor *next)
2296 {
2297 ceph_assert(next);
2298
2299 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2300
2301 // Zero out items so that they will be safe to free later
2302 // FIPS zeroization audit 20191116: this memset is not security related.
2303 memset(result_items, 0, sizeof(rados_object_list_item) * result_item_count);
2304
2305 bufferlist filter_bl;
2306 if (filter_buf != nullptr) {
2307 filter_bl.append(filter_buf, filter_buf_len);
2308 }
2309
2310 ceph::async::waiter<boost::system::error_code,
2311 std::vector<librados::ListObjectImpl>,
2312 hobject_t> w;
2313 ctx->objecter->enumerate_objects<librados::ListObjectImpl>(
2314 ctx->poolid,
2315 ctx->oloc.nspace,
2316 *((hobject_t*)start),
2317 *((hobject_t*)finish),
2318 result_item_count,
2319 filter_bl,
2320 w);
2321
2322 hobject_t *next_hobj = (hobject_t*)(*next);
2323 ceph_assert(next_hobj);
2324
2325 auto [ec, result, next_hash] = w.wait();
2326
2327 if (ec) {
2328 *next_hobj = hobject_t::get_max();
2329 return ceph::from_error_code(ec);
2330 }
2331
2332 ceph_assert(result.size() <= result_item_count); // Don't overflow!
2333
2334 int k = 0;
2335 for (auto i = result.begin(); i != result.end(); ++i) {
2336 rados_object_list_item &item = result_items[k++];
2337 do_out_buffer(i->oid, &item.oid, &item.oid_length);
2338 do_out_buffer(i->nspace, &item.nspace, &item.nspace_length);
2339 do_out_buffer(i->locator, &item.locator, &item.locator_length);
2340 }
2341
2342 *next_hobj = next_hash;
2343
2344 return result.size();
2345 }
2346 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list);
2347
2348 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_object_list_free)(
2349 const size_t result_size,
2350 rados_object_list_item *results)
2351 {
2352 ceph_assert(results);
2353
2354 for (unsigned int i = 0; i < result_size; ++i) {
2355 LIBRADOS_C_API_DEFAULT_F(rados_buffer_free)(results[i].oid);
2356 LIBRADOS_C_API_DEFAULT_F(rados_buffer_free)(results[i].locator);
2357 LIBRADOS_C_API_DEFAULT_F(rados_buffer_free)(results[i].nspace);
2358 }
2359 }
2360 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_free);
2361
2362 /* list objects */
2363
2364 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_open)(
2365 rados_ioctx_t io,
2366 rados_list_ctx_t *listh)
2367 {
2368 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2369
2370 tracepoint(librados, rados_nobjects_list_open_enter, io);
2371
2372 Objecter::NListContext *h = new Objecter::NListContext;
2373 h->pool_id = ctx->poolid;
2374 h->pool_snap_seq = ctx->snap_seq;
2375 h->nspace = ctx->oloc.nspace; // After dropping compatibility need nspace
2376 *listh = (void *)new librados::ObjListCtx(ctx, h);
2377 tracepoint(librados, rados_nobjects_list_open_exit, 0, *listh);
2378 return 0;
2379 }
2380 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_open);
2381
2382 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_close)(
2383 rados_list_ctx_t h)
2384 {
2385 tracepoint(librados, rados_nobjects_list_close_enter, h);
2386 librados::ObjListCtx *lh = (librados::ObjListCtx *)h;
2387 delete lh;
2388 tracepoint(librados, rados_nobjects_list_close_exit);
2389 }
2390 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_close);
2391
2392 extern "C" uint32_t LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_seek)(
2393 rados_list_ctx_t listctx,
2394 uint32_t pos)
2395 {
2396 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
2397 tracepoint(librados, rados_nobjects_list_seek_enter, listctx, pos);
2398 uint32_t r = lh->ctx->nlist_seek(lh->nlc, pos);
2399 tracepoint(librados, rados_nobjects_list_seek_exit, r);
2400 return r;
2401 }
2402 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_seek);
2403
2404 extern "C" uint32_t LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_seek_cursor)(
2405 rados_list_ctx_t listctx,
2406 rados_object_list_cursor cursor)
2407 {
2408 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
2409
2410 tracepoint(librados, rados_nobjects_list_seek_cursor_enter, listctx);
2411 uint32_t r = lh->ctx->nlist_seek(lh->nlc, cursor);
2412 tracepoint(librados, rados_nobjects_list_seek_cursor_exit, r);
2413 return r;
2414 }
2415 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_seek_cursor);
2416
2417 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_get_cursor)(
2418 rados_list_ctx_t listctx,
2419 rados_object_list_cursor *cursor)
2420 {
2421 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
2422
2423 tracepoint(librados, rados_nobjects_list_get_cursor_enter, listctx);
2424 *cursor = lh->ctx->nlist_get_cursor(lh->nlc);
2425 tracepoint(librados, rados_nobjects_list_get_cursor_exit, 0);
2426 return 0;
2427 }
2428 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_get_cursor);
2429
2430 extern "C" uint32_t LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_get_pg_hash_position)(
2431 rados_list_ctx_t listctx)
2432 {
2433 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
2434 tracepoint(librados, rados_nobjects_list_get_pg_hash_position_enter, listctx);
2435 uint32_t retval = lh->nlc->get_pg_hash_position();
2436 tracepoint(librados, rados_nobjects_list_get_pg_hash_position_exit, retval);
2437 return retval;
2438 }
2439 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_get_pg_hash_position);
2440
2441 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_next)(
2442 rados_list_ctx_t listctx,
2443 const char **entry,
2444 const char **key,
2445 const char **nspace)
2446 {
2447 tracepoint(librados, rados_nobjects_list_next_enter, listctx);
2448 uint32_t retval = rados_nobjects_list_next2(listctx, entry, key, nspace, NULL, NULL, NULL);
2449 tracepoint(librados, rados_nobjects_list_next_exit, 0, *entry, key, nspace);
2450 return retval;
2451 }
2452 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_next);
2453
2454 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_nobjects_list_next2)(
2455 rados_list_ctx_t listctx,
2456 const char **entry,
2457 const char **key,
2458 const char **nspace,
2459 size_t *entry_size,
2460 size_t *key_size,
2461 size_t *nspace_size)
2462 {
2463 tracepoint(librados, rados_nobjects_list_next2_enter, listctx);
2464 librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
2465 Objecter::NListContext *h = lh->nlc;
2466
2467 // if the list is non-empty, this method has been called before
2468 if (!h->list.empty())
2469 // so let's kill the previously-returned object
2470 h->list.pop_front();
2471
2472 if (h->list.empty()) {
2473 int ret = lh->ctx->nlist(lh->nlc, RADOS_LIST_MAX_ENTRIES);
2474 if (ret < 0) {
2475 tracepoint(librados, rados_nobjects_list_next2_exit, ret, NULL, NULL, NULL, NULL, NULL, NULL);
2476 return ret;
2477 }
2478 if (h->list.empty()) {
2479 tracepoint(librados, rados_nobjects_list_next2_exit, -ENOENT, NULL, NULL, NULL, NULL, NULL, NULL);
2480 return -ENOENT;
2481 }
2482 }
2483
2484 *entry = h->list.front().oid.c_str();
2485
2486 if (key) {
2487 if (h->list.front().locator.size())
2488 *key = h->list.front().locator.c_str();
2489 else
2490 *key = NULL;
2491 }
2492 if (nspace)
2493 *nspace = h->list.front().nspace.c_str();
2494
2495 if (entry_size)
2496 *entry_size = h->list.front().oid.size();
2497 if (key_size)
2498 *key_size = h->list.front().locator.size();
2499 if (nspace_size)
2500 *nspace_size = h->list.front().nspace.size();
2501
2502 tracepoint(librados, rados_nobjects_list_next2_exit, 0, entry, key, nspace,
2503 entry_size, key_size, nspace_size);
2504 return 0;
2505 }
2506 LIBRADOS_C_API_BASE_DEFAULT(rados_nobjects_list_next2);
2507
2508
2509 /*
2510 * removed legacy v2 list objects stubs
2511 *
2512 * thse return -ENOTSUP where possible.
2513 */
2514 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_objects_list_open)(
2515 rados_ioctx_t io,
2516 rados_list_ctx_t *ctx)
2517 {
2518 return -ENOTSUP;
2519 }
2520 LIBRADOS_C_API_BASE_DEFAULT(rados_objects_list_open);
2521
2522 extern "C" uint32_t LIBRADOS_C_API_DEFAULT_F(rados_objects_list_get_pg_hash_position)(
2523 rados_list_ctx_t ctx)
2524 {
2525 return 0;
2526 }
2527 LIBRADOS_C_API_BASE_DEFAULT(rados_objects_list_get_pg_hash_position);
2528
2529 extern "C" uint32_t LIBRADOS_C_API_DEFAULT_F(rados_objects_list_seek)(
2530 rados_list_ctx_t ctx,
2531 uint32_t pos)
2532 {
2533 return 0;
2534 }
2535 LIBRADOS_C_API_BASE_DEFAULT(rados_objects_list_seek);
2536
2537 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_objects_list_next)(
2538 rados_list_ctx_t ctx,
2539 const char **entry,
2540 const char **key)
2541 {
2542 return -ENOTSUP;
2543 }
2544 LIBRADOS_C_API_BASE_DEFAULT(rados_objects_list_next);
2545
2546 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_objects_list_close)(
2547 rados_list_ctx_t ctx)
2548 {
2549 }
2550 LIBRADOS_C_API_BASE_DEFAULT(rados_objects_list_close);
2551
2552
2553 // -------------------------
2554 // aio
2555
2556 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_create_completion)(
2557 void *cb_arg,
2558 rados_callback_t cb_complete,
2559 rados_callback_t cb_safe,
2560 rados_completion_t *pc)
2561 {
2562 tracepoint(librados, rados_aio_create_completion_enter, cb_arg, cb_complete, cb_safe);
2563 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
2564 if (cb_complete)
2565 c->set_complete_callback(cb_arg, cb_complete);
2566 if (cb_safe)
2567 c->set_safe_callback(cb_arg, cb_safe);
2568 *pc = c;
2569 tracepoint(librados, rados_aio_create_completion_exit, 0, *pc);
2570 return 0;
2571 }
2572 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_create_completion);
2573
2574 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_create_completion2)(
2575 void *cb_arg,
2576 rados_callback_t cb_complete,
2577 rados_completion_t *pc)
2578 {
2579 tracepoint(librados, rados_aio_create_completion2_enter, cb_arg, cb_complete);
2580 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
2581 if (cb_complete)
2582 c->set_complete_callback(cb_arg, cb_complete);
2583 *pc = c;
2584 tracepoint(librados, rados_aio_create_completion2_exit, 0, *pc);
2585 return 0;
2586 }
2587 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_create_completion2);
2588
2589 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_wait_for_complete)(
2590 rados_completion_t c)
2591 {
2592 tracepoint(librados, rados_aio_wait_for_complete_enter, c);
2593 int retval = ((librados::AioCompletionImpl*)c)->wait_for_complete();
2594 tracepoint(librados, rados_aio_wait_for_complete_exit, retval);
2595 return retval;
2596 }
2597 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_wait_for_complete);
2598
2599 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_wait_for_safe)(
2600 rados_completion_t c)
2601 {
2602 tracepoint(librados, rados_aio_wait_for_safe_enter, c);
2603 int retval = ((librados::AioCompletionImpl*)c)->wait_for_complete();
2604 tracepoint(librados, rados_aio_wait_for_safe_exit, retval);
2605 return retval;
2606 }
2607 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_wait_for_safe);
2608
2609 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_is_complete)(
2610 rados_completion_t c)
2611 {
2612 tracepoint(librados, rados_aio_is_complete_enter, c);
2613 int retval = ((librados::AioCompletionImpl*)c)->is_complete();
2614 tracepoint(librados, rados_aio_is_complete_exit, retval);
2615 return retval;
2616 }
2617 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_is_complete);
2618
2619 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_is_safe)(
2620 rados_completion_t c)
2621 {
2622 tracepoint(librados, rados_aio_is_safe_enter, c);
2623 int retval = ((librados::AioCompletionImpl*)c)->is_safe();
2624 tracepoint(librados, rados_aio_is_safe_exit, retval);
2625 return retval;
2626 }
2627 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_is_safe);
2628
2629 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_wait_for_complete_and_cb)(
2630 rados_completion_t c)
2631 {
2632 tracepoint(librados, rados_aio_wait_for_complete_and_cb_enter, c);
2633 int retval = ((librados::AioCompletionImpl*)c)->wait_for_complete_and_cb();
2634 tracepoint(librados, rados_aio_wait_for_complete_and_cb_exit, retval);
2635 return retval;
2636 }
2637 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_wait_for_complete_and_cb);
2638
2639 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_wait_for_safe_and_cb)(
2640 rados_completion_t c)
2641 {
2642 tracepoint(librados, rados_aio_wait_for_safe_and_cb_enter, c);
2643 int retval = ((librados::AioCompletionImpl*)c)->wait_for_safe_and_cb();
2644 tracepoint(librados, rados_aio_wait_for_safe_and_cb_exit, retval);
2645 return retval;
2646 }
2647 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_wait_for_safe_and_cb);
2648
2649 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_is_complete_and_cb)(
2650 rados_completion_t c)
2651 {
2652 tracepoint(librados, rados_aio_is_complete_and_cb_enter, c);
2653 int retval = ((librados::AioCompletionImpl*)c)->is_complete_and_cb();
2654 tracepoint(librados, rados_aio_is_complete_and_cb_exit, retval);
2655 return retval;
2656 }
2657 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_is_complete_and_cb);
2658
2659 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_is_safe_and_cb)(
2660 rados_completion_t c)
2661 {
2662 tracepoint(librados, rados_aio_is_safe_and_cb_enter, c);
2663 int retval = ((librados::AioCompletionImpl*)c)->is_safe_and_cb();
2664 tracepoint(librados, rados_aio_is_safe_and_cb_exit, retval);
2665 return retval;
2666 }
2667 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_is_safe_and_cb);
2668
2669 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_get_return_value)(
2670 rados_completion_t c)
2671 {
2672 tracepoint(librados, rados_aio_get_return_value_enter, c);
2673 int retval = ((librados::AioCompletionImpl*)c)->get_return_value();
2674 tracepoint(librados, rados_aio_get_return_value_exit, retval);
2675 return retval;
2676 }
2677 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_get_return_value);
2678
2679 extern "C" uint64_t LIBRADOS_C_API_DEFAULT_F(rados_aio_get_version)(
2680 rados_completion_t c)
2681 {
2682 tracepoint(librados, rados_aio_get_version_enter, c);
2683 uint64_t retval = ((librados::AioCompletionImpl*)c)->get_version();
2684 tracepoint(librados, rados_aio_get_version_exit, retval);
2685 return retval;
2686 }
2687 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_get_version);
2688
2689 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_aio_release)(
2690 rados_completion_t c)
2691 {
2692 tracepoint(librados, rados_aio_release_enter, c);
2693 ((librados::AioCompletionImpl*)c)->put();
2694 tracepoint(librados, rados_aio_release_exit);
2695 }
2696 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_release);
2697
2698 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_read)(
2699 rados_ioctx_t io, const char *o,
2700 rados_completion_t completion,
2701 char *buf, size_t len, uint64_t off)
2702 {
2703 tracepoint(librados, rados_aio_read_enter, io, o, completion, len, off);
2704 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2705 object_t oid(o);
2706 int retval = ctx->aio_read(oid, (librados::AioCompletionImpl*)completion,
2707 buf, len, off, ctx->snap_seq);
2708 tracepoint(librados, rados_aio_read_exit, retval);
2709 return retval;
2710 }
2711 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_read);
2712
2713 #ifdef WITH_BLKIN
2714 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_read_traced)(
2715 rados_ioctx_t io, const char *o,
2716 rados_completion_t completion,
2717 char *buf, size_t len, uint64_t off,
2718 struct blkin_trace_info *info)
2719 {
2720 tracepoint(librados, rados_aio_read_enter, io, o, completion, len, off);
2721 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2722 object_t oid(o);
2723 int retval = ctx->aio_read(oid, (librados::AioCompletionImpl*)completion,
2724 buf, len, off, ctx->snap_seq, info);
2725 tracepoint(librados, rados_aio_read_exit, retval);
2726 return retval;
2727 }
2728 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_read_traced);
2729 #endif
2730
2731 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_write)(
2732 rados_ioctx_t io, const char *o,
2733 rados_completion_t completion,
2734 const char *buf, size_t len, uint64_t off)
2735 {
2736 tracepoint(librados, rados_aio_write_enter, io, o, completion, buf, len, off);
2737 if (len > UINT_MAX/2)
2738 return -E2BIG;
2739 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2740 object_t oid(o);
2741 bufferlist bl;
2742 bl.append(buf, len);
2743 int retval = ctx->aio_write(oid, (librados::AioCompletionImpl*)completion,
2744 bl, len, off);
2745 tracepoint(librados, rados_aio_write_exit, retval);
2746 return retval;
2747 }
2748 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_write);
2749
2750 #ifdef WITH_BLKIN
2751 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_write_traced)(
2752 rados_ioctx_t io, const char *o,
2753 rados_completion_t completion,
2754 const char *buf, size_t len, uint64_t off,
2755 struct blkin_trace_info *info)
2756 {
2757 tracepoint(librados, rados_aio_write_enter, io, o, completion, buf, len, off);
2758 if (len > UINT_MAX/2)
2759 return -E2BIG;
2760 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2761 object_t oid(o);
2762 bufferlist bl;
2763 bl.append(buf, len);
2764 int retval = ctx->aio_write(oid, (librados::AioCompletionImpl*)completion,
2765 bl, len, off, info);
2766 tracepoint(librados, rados_aio_write_exit, retval);
2767 return retval;
2768 }
2769 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_write_traced);
2770 #endif
2771
2772 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_append)(
2773 rados_ioctx_t io, const char *o,
2774 rados_completion_t completion,
2775 const char *buf, size_t len)
2776 {
2777 tracepoint(librados, rados_aio_append_enter, io, o, completion, buf, len);
2778 if (len > UINT_MAX/2)
2779 return -E2BIG;
2780 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2781 object_t oid(o);
2782 bufferlist bl;
2783 bl.append(buf, len);
2784 int retval = ctx->aio_append(oid, (librados::AioCompletionImpl*)completion,
2785 bl, len);
2786 tracepoint(librados, rados_aio_append_exit, retval);
2787 return retval;
2788 }
2789 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_append);
2790
2791 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_write_full)(
2792 rados_ioctx_t io, const char *o,
2793 rados_completion_t completion,
2794 const char *buf, size_t len)
2795 {
2796 tracepoint(librados, rados_aio_write_full_enter, io, o, completion, buf, len);
2797 if (len > UINT_MAX/2)
2798 return -E2BIG;
2799 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2800 object_t oid(o);
2801 bufferlist bl;
2802 bl.append(buf, len);
2803 int retval = ctx->aio_write_full(oid, (librados::AioCompletionImpl*)completion, bl);
2804 tracepoint(librados, rados_aio_write_full_exit, retval);
2805 return retval;
2806 }
2807 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_write_full);
2808
2809 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_writesame)(
2810 rados_ioctx_t io, const char *o,
2811 rados_completion_t completion,
2812 const char *buf, size_t data_len,
2813 size_t write_len, uint64_t off)
2814 {
2815 tracepoint(librados, rados_aio_writesame_enter, io, o, completion, buf,
2816 data_len, write_len, off);
2817 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2818 object_t oid(o);
2819 bufferlist bl;
2820 bl.append(buf, data_len);
2821 int retval = ctx->aio_writesame(o, (librados::AioCompletionImpl*)completion,
2822 bl, write_len, off);
2823 tracepoint(librados, rados_aio_writesame_exit, retval);
2824 return retval;
2825 }
2826 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_writesame);
2827
2828 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_remove)(
2829 rados_ioctx_t io, const char *o,
2830 rados_completion_t completion)
2831 {
2832 tracepoint(librados, rados_aio_remove_enter, io, o, completion);
2833 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2834 object_t oid(o);
2835 int retval = ctx->aio_remove(oid, (librados::AioCompletionImpl*)completion);
2836 tracepoint(librados, rados_aio_remove_exit, retval);
2837 return retval;
2838 }
2839 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_remove);
2840
2841 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_flush_async)(
2842 rados_ioctx_t io,
2843 rados_completion_t completion)
2844 {
2845 tracepoint(librados, rados_aio_flush_async_enter, io, completion);
2846 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2847 ctx->flush_aio_writes_async((librados::AioCompletionImpl*)completion);
2848 tracepoint(librados, rados_aio_flush_async_exit, 0);
2849 return 0;
2850 }
2851 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_flush_async);
2852
2853 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_flush)(rados_ioctx_t io)
2854 {
2855 tracepoint(librados, rados_aio_flush_enter, io);
2856 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2857 ctx->flush_aio_writes();
2858 tracepoint(librados, rados_aio_flush_exit, 0);
2859 return 0;
2860 }
2861 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_flush);
2862
2863 struct AioGetxattrData {
2864 AioGetxattrData(char* buf, rados_completion_t c, size_t l) :
2865 user_buf(buf), len(l), user_completion((librados::AioCompletionImpl*)c) {}
2866 bufferlist bl;
2867 char* user_buf;
2868 size_t len;
2869 struct librados::CB_AioCompleteAndSafe user_completion;
2870 };
2871
2872 static void rados_aio_getxattr_complete(rados_completion_t c, void *arg) {
2873 AioGetxattrData *cdata = reinterpret_cast<AioGetxattrData*>(arg);
2874 int rc = LIBRADOS_C_API_DEFAULT_F(rados_aio_get_return_value)(c);
2875 if (rc >= 0) {
2876 if (cdata->bl.length() > cdata->len) {
2877 rc = -ERANGE;
2878 } else {
2879 if (!cdata->bl.is_provided_buffer(cdata->user_buf))
2880 cdata->bl.begin().copy(cdata->bl.length(), cdata->user_buf);
2881 rc = cdata->bl.length();
2882 }
2883 }
2884 cdata->user_completion(rc);
2885 reinterpret_cast<librados::AioCompletionImpl*>(c)->put();
2886 delete cdata;
2887 }
2888
2889 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_getxattr)(
2890 rados_ioctx_t io, const char *o,
2891 rados_completion_t completion,
2892 const char *name, char *buf, size_t len)
2893 {
2894 tracepoint(librados, rados_aio_getxattr_enter, io, o, completion, name, len);
2895 // create data object to be passed to async callback
2896 AioGetxattrData *cdata = new AioGetxattrData(buf, completion, len);
2897 if (!cdata) {
2898 tracepoint(librados, rados_aio_getxattr_exit, -ENOMEM, NULL, 0);
2899 return -ENOMEM;
2900 }
2901 cdata->bl.push_back(buffer::create_static(len, buf));
2902 // create completion callback
2903 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
2904 c->set_complete_callback(cdata, rados_aio_getxattr_complete);
2905 // call async getxattr of IoCtx
2906 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2907 object_t oid(o);
2908 int ret = ctx->aio_getxattr(oid, c, name, cdata->bl);
2909 tracepoint(librados, rados_aio_getxattr_exit, ret, buf, ret);
2910 return ret;
2911 }
2912 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_getxattr);
2913
2914 namespace {
2915 struct AioGetxattrsData {
2916 AioGetxattrsData(rados_completion_t c, rados_xattrs_iter_t *_iter) :
2917 iter(_iter), user_completion((librados::AioCompletionImpl*)c) {
2918 it = new librados::RadosXattrsIter();
2919 }
2920 ~AioGetxattrsData() {
2921 if (it) delete it;
2922 }
2923 librados::RadosXattrsIter *it;
2924 rados_xattrs_iter_t *iter;
2925 struct librados::CB_AioCompleteAndSafe user_completion;
2926 };
2927 }
2928
2929 static void rados_aio_getxattrs_complete(rados_completion_t c, void *arg) {
2930 AioGetxattrsData *cdata = reinterpret_cast<AioGetxattrsData*>(arg);
2931 int rc = LIBRADOS_C_API_DEFAULT_F(rados_aio_get_return_value)(c);
2932 if (rc) {
2933 cdata->user_completion(rc);
2934 } else {
2935 cdata->it->i = cdata->it->attrset.begin();
2936 *cdata->iter = cdata->it;
2937 cdata->it = 0;
2938 cdata->user_completion(0);
2939 }
2940 reinterpret_cast<librados::AioCompletionImpl*>(c)->put();
2941 delete cdata;
2942 }
2943
2944 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_getxattrs)(
2945 rados_ioctx_t io, const char *oid,
2946 rados_completion_t completion,
2947 rados_xattrs_iter_t *iter)
2948 {
2949 tracepoint(librados, rados_aio_getxattrs_enter, io, oid, completion);
2950 // create data object to be passed to async callback
2951 AioGetxattrsData *cdata = new AioGetxattrsData(completion, iter);
2952 if (!cdata) {
2953 tracepoint(librados, rados_getxattrs_exit, -ENOMEM, NULL);
2954 return -ENOMEM;
2955 }
2956 // create completion callback
2957 librados::AioCompletionImpl *c = new librados::AioCompletionImpl;
2958 c->set_complete_callback(cdata, rados_aio_getxattrs_complete);
2959 // call async getxattrs of IoCtx
2960 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2961 object_t obj(oid);
2962 int ret = ctx->aio_getxattrs(obj, c, cdata->it->attrset);
2963 tracepoint(librados, rados_aio_getxattrs_exit, ret, cdata->it);
2964 return ret;
2965 }
2966 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_getxattrs);
2967
2968 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_setxattr)(
2969 rados_ioctx_t io, const char *o,
2970 rados_completion_t completion,
2971 const char *name, const char *buf, size_t len)
2972 {
2973 tracepoint(librados, rados_aio_setxattr_enter, io, o, completion, name, buf, len);
2974 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2975 object_t oid(o);
2976 bufferlist bl;
2977 bl.append(buf, len);
2978 int retval = ctx->aio_setxattr(oid, (librados::AioCompletionImpl*)completion, name, bl);
2979 tracepoint(librados, rados_aio_setxattr_exit, retval);
2980 return retval;
2981 }
2982 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_setxattr);
2983
2984 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_rmxattr)(
2985 rados_ioctx_t io, const char *o,
2986 rados_completion_t completion,
2987 const char *name)
2988 {
2989 tracepoint(librados, rados_aio_rmxattr_enter, io, o, completion, name);
2990 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
2991 object_t oid(o);
2992 int retval = ctx->aio_rmxattr(oid, (librados::AioCompletionImpl*)completion, name);
2993 tracepoint(librados, rados_aio_rmxattr_exit, retval);
2994 return retval;
2995 }
2996 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_rmxattr);
2997
2998 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_stat)(
2999 rados_ioctx_t io, const char *o,
3000 rados_completion_t completion,
3001 uint64_t *psize, time_t *pmtime)
3002 {
3003 tracepoint(librados, rados_aio_stat_enter, io, o, completion);
3004 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3005 object_t oid(o);
3006 int retval = ctx->aio_stat(oid, (librados::AioCompletionImpl*)completion,
3007 psize, pmtime);
3008 tracepoint(librados, rados_aio_stat_exit, retval);
3009 return retval;
3010 }
3011 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_stat);
3012
3013 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_stat2)(
3014 rados_ioctx_t io, const char *o,
3015 rados_completion_t completion,
3016 uint64_t *psize, struct timespec *pmtime)
3017 {
3018 tracepoint(librados, rados_aio_stat2_enter, io, o, completion);
3019 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3020 object_t oid(o);
3021 int retval = ctx->aio_stat2(oid, (librados::AioCompletionImpl*)completion,
3022 psize, pmtime);
3023 tracepoint(librados, rados_aio_stat2_exit, retval);
3024 return retval;
3025 }
3026 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_stat2);
3027
3028 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_cmpext)(
3029 rados_ioctx_t io, const char *o,
3030 rados_completion_t completion, const char *cmp_buf,
3031 size_t cmp_len, uint64_t off)
3032 {
3033 tracepoint(librados, rados_aio_cmpext_enter, io, o, completion, cmp_buf,
3034 cmp_len, off);
3035 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3036 object_t oid(o);
3037 int retval = ctx->aio_cmpext(oid, (librados::AioCompletionImpl*)completion,
3038 cmp_buf, cmp_len, off);
3039 tracepoint(librados, rados_aio_cmpext_exit, retval);
3040 return retval;
3041 }
3042 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_cmpext);
3043
3044 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_cancel)(
3045 rados_ioctx_t io,
3046 rados_completion_t completion)
3047 {
3048 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3049 return ctx->aio_cancel((librados::AioCompletionImpl*)completion);
3050 }
3051 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_cancel);
3052
3053 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_exec)(
3054 rados_ioctx_t io, const char *o,
3055 rados_completion_t completion,
3056 const char *cls, const char *method,
3057 const char *inbuf, size_t in_len,
3058 char *buf, size_t out_len)
3059 {
3060 tracepoint(librados, rados_aio_exec_enter, io, o, completion);
3061 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3062 object_t oid(o);
3063 bufferlist inbl;
3064 inbl.append(inbuf, in_len);
3065 int retval = ctx->aio_exec(oid, (librados::AioCompletionImpl*)completion,
3066 cls, method, inbl, buf, out_len);
3067 tracepoint(librados, rados_aio_exec_exit, retval);
3068 return retval;
3069 }
3070 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_exec);
3071
3072 struct C_WatchCB : public librados::WatchCtx {
3073 rados_watchcb_t wcb;
3074 void *arg;
3075 C_WatchCB(rados_watchcb_t _wcb, void *_arg) : wcb(_wcb), arg(_arg) {}
3076 void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override {
3077 wcb(opcode, ver, arg);
3078 }
3079 };
3080
3081 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_watch)(
3082 rados_ioctx_t io, const char *o, uint64_t ver,
3083 uint64_t *handle,
3084 rados_watchcb_t watchcb, void *arg)
3085 {
3086 tracepoint(librados, rados_watch_enter, io, o, ver, watchcb, arg);
3087 uint64_t *cookie = handle;
3088 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3089 object_t oid(o);
3090 C_WatchCB *wc = new C_WatchCB(watchcb, arg);
3091 int retval = ctx->watch(oid, cookie, wc, NULL, true);
3092 tracepoint(librados, rados_watch_exit, retval, *handle);
3093 return retval;
3094 }
3095 LIBRADOS_C_API_BASE_DEFAULT(rados_watch);
3096
3097 struct C_WatchCB2 : public librados::WatchCtx2 {
3098 rados_watchcb2_t wcb;
3099 rados_watcherrcb_t errcb;
3100 void *arg;
3101 C_WatchCB2(rados_watchcb2_t _wcb,
3102 rados_watcherrcb_t _errcb,
3103 void *_arg) : wcb(_wcb), errcb(_errcb), arg(_arg) {}
3104 void handle_notify(uint64_t notify_id,
3105 uint64_t cookie,
3106 uint64_t notifier_gid,
3107 bufferlist& bl) override {
3108 wcb(arg, notify_id, cookie, notifier_gid, bl.c_str(), bl.length());
3109 }
3110 void handle_error(uint64_t cookie, int err) override {
3111 if (errcb)
3112 errcb(arg, cookie, err);
3113 }
3114 };
3115
3116 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_watch3)(
3117 rados_ioctx_t io, const char *o, uint64_t *handle,
3118 rados_watchcb2_t watchcb,
3119 rados_watcherrcb_t watcherrcb,
3120 uint32_t timeout,
3121 void *arg)
3122 {
3123 tracepoint(librados, rados_watch3_enter, io, o, handle, watchcb, timeout, arg);
3124 int ret;
3125 if (!watchcb || !o || !handle) {
3126 ret = -EINVAL;
3127 } else {
3128 uint64_t *cookie = handle;
3129 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3130 object_t oid(o);
3131 C_WatchCB2 *wc = new C_WatchCB2(watchcb, watcherrcb, arg);
3132 ret = ctx->watch(oid, cookie, NULL, wc, timeout, true);
3133 }
3134 tracepoint(librados, rados_watch3_exit, ret, handle ? *handle : 0);
3135 return ret;
3136 }
3137 LIBRADOS_C_API_BASE_DEFAULT(rados_watch3);
3138
3139 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_watch2)(
3140 rados_ioctx_t io, const char *o, uint64_t *handle,
3141 rados_watchcb2_t watchcb,
3142 rados_watcherrcb_t watcherrcb,
3143 void *arg)
3144 {
3145 return LIBRADOS_C_API_DEFAULT_F(rados_watch3)(
3146 io, o, handle, watchcb, watcherrcb, 0, arg);
3147 }
3148 LIBRADOS_C_API_BASE_DEFAULT(rados_watch2);
3149
3150 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_watch2)(
3151 rados_ioctx_t io, const char *o,
3152 rados_completion_t completion,
3153 uint64_t *handle,
3154 rados_watchcb2_t watchcb,
3155 rados_watcherrcb_t watcherrcb,
3156 uint32_t timeout, void *arg)
3157 {
3158 tracepoint(librados, rados_aio_watch2_enter, io, o, completion, handle, watchcb, timeout, arg);
3159 int ret;
3160 if (!completion || !watchcb || !o || !handle) {
3161 ret = -EINVAL;
3162 } else {
3163 uint64_t *cookie = handle;
3164 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3165 object_t oid(o);
3166 librados::AioCompletionImpl *c =
3167 reinterpret_cast<librados::AioCompletionImpl*>(completion);
3168 C_WatchCB2 *wc = new C_WatchCB2(watchcb, watcherrcb, arg);
3169 ret = ctx->aio_watch(oid, c, cookie, NULL, wc, timeout, true);
3170 }
3171 tracepoint(librados, rados_aio_watch2_exit, ret, handle ? *handle : 0);
3172 return ret;
3173 }
3174 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_watch2);
3175
3176 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_watch)(
3177 rados_ioctx_t io, const char *o,
3178 rados_completion_t completion,
3179 uint64_t *handle,
3180 rados_watchcb2_t watchcb,
3181 rados_watcherrcb_t watcherrcb, void *arg)
3182 {
3183 return LIBRADOS_C_API_DEFAULT_F(rados_aio_watch2)(
3184 io, o, completion, handle, watchcb, watcherrcb, 0, arg);
3185 }
3186 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_watch);
3187
3188 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_unwatch)(
3189 rados_ioctx_t io,
3190 const char *o,
3191 uint64_t handle)
3192 {
3193 tracepoint(librados, rados_unwatch_enter, io, o, handle);
3194 uint64_t cookie = handle;
3195 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3196 int retval = ctx->unwatch(cookie);
3197 tracepoint(librados, rados_unwatch_exit, retval);
3198 return retval;
3199 }
3200 LIBRADOS_C_API_BASE_DEFAULT(rados_unwatch);
3201
3202 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_unwatch2)(
3203 rados_ioctx_t io,
3204 uint64_t handle)
3205 {
3206 tracepoint(librados, rados_unwatch2_enter, io, handle);
3207 uint64_t cookie = handle;
3208 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3209 int retval = ctx->unwatch(cookie);
3210 tracepoint(librados, rados_unwatch2_exit, retval);
3211 return retval;
3212 }
3213 LIBRADOS_C_API_BASE_DEFAULT(rados_unwatch2);
3214
3215 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_unwatch)(
3216 rados_ioctx_t io, uint64_t handle,
3217 rados_completion_t completion)
3218 {
3219 tracepoint(librados, rados_aio_unwatch_enter, io, handle, completion);
3220 uint64_t cookie = handle;
3221 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3222 librados::AioCompletionImpl *c =
3223 reinterpret_cast<librados::AioCompletionImpl*>(completion);
3224 int retval = ctx->aio_unwatch(cookie, c);
3225 tracepoint(librados, rados_aio_unwatch_exit, retval);
3226 return retval;
3227 }
3228 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_unwatch);
3229
3230 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_watch_check)(
3231 rados_ioctx_t io,
3232 uint64_t handle)
3233 {
3234 tracepoint(librados, rados_watch_check_enter, io, handle);
3235 uint64_t cookie = handle;
3236 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3237 int retval = ctx->watch_check(cookie);
3238 tracepoint(librados, rados_watch_check_exit, retval);
3239 return retval;
3240 }
3241 LIBRADOS_C_API_BASE_DEFAULT(rados_watch_check);
3242
3243 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_notify)(
3244 rados_ioctx_t io, const char *o,
3245 uint64_t ver, const char *buf, int buf_len)
3246 {
3247 tracepoint(librados, rados_notify_enter, io, o, ver, buf, buf_len);
3248 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3249 object_t oid(o);
3250 bufferlist bl;
3251 if (buf) {
3252 bufferptr p = buffer::create(buf_len);
3253 memcpy(p.c_str(), buf, buf_len);
3254 bl.push_back(p);
3255 }
3256 int retval = ctx->notify(oid, bl, 0, NULL, NULL, NULL);
3257 tracepoint(librados, rados_notify_exit, retval);
3258 return retval;
3259 }
3260 LIBRADOS_C_API_BASE_DEFAULT(rados_notify);
3261
3262 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_notify2)(
3263 rados_ioctx_t io, const char *o,
3264 const char *buf, int buf_len,
3265 uint64_t timeout_ms,
3266 char **reply_buffer,
3267 size_t *reply_buffer_len)
3268 {
3269 tracepoint(librados, rados_notify2_enter, io, o, buf, buf_len, timeout_ms);
3270 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3271 object_t oid(o);
3272 bufferlist bl;
3273 if (buf) {
3274 bufferptr p = buffer::create(buf_len);
3275 memcpy(p.c_str(), buf, buf_len);
3276 bl.push_back(p);
3277 }
3278 int ret = ctx->notify(oid, bl, timeout_ms, NULL, reply_buffer, reply_buffer_len);
3279 tracepoint(librados, rados_notify2_exit, ret);
3280 return ret;
3281 }
3282 LIBRADOS_C_API_BASE_DEFAULT(rados_notify2);
3283
3284 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_decode_notify_response)(
3285 char *reply_buffer, size_t reply_buffer_len,
3286 struct notify_ack_t **acks, size_t *nr_acks,
3287 struct notify_timeout_t **timeouts, size_t *nr_timeouts)
3288 {
3289 if (!reply_buffer || !reply_buffer_len) {
3290 return -EINVAL;
3291 }
3292
3293 bufferlist bl;
3294 bl.append(reply_buffer, reply_buffer_len);
3295
3296 map<pair<uint64_t,uint64_t>,bufferlist> acked;
3297 set<pair<uint64_t,uint64_t>> missed;
3298 auto iter = bl.cbegin();
3299 decode(acked, iter);
3300 decode(missed, iter);
3301
3302 *acks = nullptr;
3303 *nr_acks = acked.size();
3304 if (*nr_acks) {
3305 *acks = new notify_ack_t[*nr_acks];
3306 struct notify_ack_t *ack = *acks;
3307 for (auto &[who, payload] : acked) {
3308 ack->notifier_id = who.first;
3309 ack->cookie = who.second;
3310 ack->payload = nullptr;
3311 ack->payload_len = payload.length();
3312 if (ack->payload_len) {
3313 ack->payload = (char *)malloc(ack->payload_len);
3314 memcpy(ack->payload, payload.c_str(), ack->payload_len);
3315 }
3316
3317 ack++;
3318 }
3319 }
3320
3321 *timeouts = nullptr;
3322 *nr_timeouts = missed.size();
3323 if (*nr_timeouts) {
3324 *timeouts = new notify_timeout_t[*nr_timeouts];
3325 struct notify_timeout_t *timeout = *timeouts;
3326 for (auto &[notifier_id, cookie] : missed) {
3327 timeout->notifier_id = notifier_id;
3328 timeout->cookie = cookie;
3329 timeout++;
3330 }
3331 }
3332
3333 return 0;
3334 }
3335 LIBRADOS_C_API_BASE_DEFAULT(rados_decode_notify_response);
3336
3337
3338 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_free_notify_response)(
3339 struct notify_ack_t *acks, size_t nr_acks,
3340 struct notify_timeout_t *timeouts)
3341 {
3342 for (uint64_t n = 0; n < nr_acks; ++n) {
3343 assert(acks);
3344 if (acks[n].payload) {
3345 free(acks[n].payload);
3346 }
3347 }
3348 if (acks) {
3349 delete[] acks;
3350 }
3351 if (timeouts) {
3352 delete[] timeouts;
3353 }
3354 }
3355 LIBRADOS_C_API_BASE_DEFAULT(rados_free_notify_response);
3356
3357 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_notify)(
3358 rados_ioctx_t io, const char *o,
3359 rados_completion_t completion,
3360 const char *buf, int buf_len,
3361 uint64_t timeout_ms, char **reply_buffer,
3362 size_t *reply_buffer_len)
3363 {
3364 tracepoint(librados, rados_aio_notify_enter, io, o, completion, buf, buf_len,
3365 timeout_ms);
3366 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3367 object_t oid(o);
3368 bufferlist bl;
3369 if (buf) {
3370 bl.push_back(buffer::copy(buf, buf_len));
3371 }
3372 librados::AioCompletionImpl *c =
3373 reinterpret_cast<librados::AioCompletionImpl*>(completion);
3374 int ret = ctx->aio_notify(oid, c, bl, timeout_ms, NULL, reply_buffer,
3375 reply_buffer_len);
3376 tracepoint(librados, rados_aio_notify_exit, ret);
3377 return ret;
3378 }
3379 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_notify);
3380
3381 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_notify_ack)(
3382 rados_ioctx_t io, const char *o,
3383 uint64_t notify_id, uint64_t handle,
3384 const char *buf, int buf_len)
3385 {
3386 tracepoint(librados, rados_notify_ack_enter, io, o, notify_id, handle, buf, buf_len);
3387 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3388 object_t oid(o);
3389 bufferlist bl;
3390 if (buf) {
3391 bufferptr p = buffer::create(buf_len);
3392 memcpy(p.c_str(), buf, buf_len);
3393 bl.push_back(p);
3394 }
3395 ctx->notify_ack(oid, notify_id, handle, bl);
3396 tracepoint(librados, rados_notify_ack_exit, 0);
3397 return 0;
3398 }
3399 LIBRADOS_C_API_BASE_DEFAULT(rados_notify_ack);
3400
3401 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_watch_flush)(rados_t cluster)
3402 {
3403 tracepoint(librados, rados_watch_flush_enter, cluster);
3404 librados::RadosClient *client = (librados::RadosClient *)cluster;
3405 int retval = client->watch_flush();
3406 tracepoint(librados, rados_watch_flush_exit, retval);
3407 return retval;
3408 }
3409 LIBRADOS_C_API_BASE_DEFAULT(rados_watch_flush);
3410
3411 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_watch_flush)(
3412 rados_t cluster,
3413 rados_completion_t completion)
3414 {
3415 tracepoint(librados, rados_aio_watch_flush_enter, cluster, completion);
3416 librados::RadosClient *client = (librados::RadosClient *)cluster;
3417 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
3418 int retval = client->async_watch_flush(c);
3419 tracepoint(librados, rados_aio_watch_flush_exit, retval);
3420 return retval;
3421 }
3422 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_watch_flush);
3423
3424 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_set_alloc_hint)(
3425 rados_ioctx_t io, const char *o,
3426 uint64_t expected_object_size,
3427 uint64_t expected_write_size)
3428 {
3429 tracepoint(librados, rados_set_alloc_hint_enter, io, o, expected_object_size, expected_write_size);
3430 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3431 object_t oid(o);
3432 int retval = ctx->set_alloc_hint(oid, expected_object_size,
3433 expected_write_size, 0);
3434 tracepoint(librados, rados_set_alloc_hint_exit, retval);
3435 return retval;
3436 }
3437 LIBRADOS_C_API_BASE_DEFAULT(rados_set_alloc_hint);
3438
3439 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_set_alloc_hint2)(
3440 rados_ioctx_t io, const char *o,
3441 uint64_t expected_object_size,
3442 uint64_t expected_write_size,
3443 uint32_t flags)
3444 {
3445 tracepoint(librados, rados_set_alloc_hint2_enter, io, o, expected_object_size, expected_write_size, flags);
3446 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
3447 object_t oid(o);
3448 int retval = ctx->set_alloc_hint(oid, expected_object_size,
3449 expected_write_size, flags);
3450 tracepoint(librados, rados_set_alloc_hint2_exit, retval);
3451 return retval;
3452 }
3453 LIBRADOS_C_API_BASE_DEFAULT(rados_set_alloc_hint2);
3454
3455 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_lock_exclusive)(
3456 rados_ioctx_t io, const char * o,
3457 const char * name, const char * cookie,
3458 const char * desc,
3459 struct timeval * duration, uint8_t flags)
3460 {
3461 tracepoint(librados, rados_lock_exclusive_enter, io, o, name, cookie, desc, duration, flags);
3462 librados::IoCtx ctx;
3463 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3464
3465 int retval = ctx.lock_exclusive(o, name, cookie, desc, duration, flags);
3466 tracepoint(librados, rados_lock_exclusive_exit, retval);
3467 return retval;
3468 }
3469 LIBRADOS_C_API_BASE_DEFAULT(rados_lock_exclusive);
3470
3471 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_lock_shared)(
3472 rados_ioctx_t io, const char * o,
3473 const char * name, const char * cookie,
3474 const char * tag, const char * desc,
3475 struct timeval * duration, uint8_t flags)
3476 {
3477 tracepoint(librados, rados_lock_shared_enter, io, o, name, cookie, tag, desc, duration, flags);
3478 librados::IoCtx ctx;
3479 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3480
3481 int retval = ctx.lock_shared(o, name, cookie, tag, desc, duration, flags);
3482 tracepoint(librados, rados_lock_shared_exit, retval);
3483 return retval;
3484 }
3485 LIBRADOS_C_API_BASE_DEFAULT(rados_lock_shared);
3486
3487 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_unlock)(
3488 rados_ioctx_t io, const char *o, const char *name,
3489 const char *cookie)
3490 {
3491 tracepoint(librados, rados_unlock_enter, io, o, name, cookie);
3492 librados::IoCtx ctx;
3493 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3494
3495 int retval = ctx.unlock(o, name, cookie);
3496 tracepoint(librados, rados_unlock_exit, retval);
3497 return retval;
3498 }
3499 LIBRADOS_C_API_BASE_DEFAULT(rados_unlock);
3500
3501 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_unlock)(
3502 rados_ioctx_t io, const char *o, const char *name,
3503 const char *cookie, rados_completion_t completion)
3504 {
3505 tracepoint(librados, rados_aio_unlock_enter, io, o, name, cookie, completion);
3506 librados::IoCtx ctx;
3507 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3508 librados::AioCompletionImpl *comp = (librados::AioCompletionImpl*)completion;
3509 comp->get();
3510 librados::AioCompletion c(comp);
3511 int retval = ctx.aio_unlock(o, name, cookie, &c);
3512 tracepoint(librados, rados_aio_unlock_exit, retval);
3513 return retval;
3514 }
3515 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_unlock);
3516
3517 extern "C" ssize_t LIBRADOS_C_API_DEFAULT_F(rados_list_lockers)(
3518 rados_ioctx_t io, const char *o,
3519 const char *name, int *exclusive,
3520 char *tag, size_t *tag_len,
3521 char *clients, size_t *clients_len,
3522 char *cookies, size_t *cookies_len,
3523 char *addrs, size_t *addrs_len)
3524 {
3525 tracepoint(librados, rados_list_lockers_enter, io, o, name, *tag_len, *clients_len, *cookies_len, *addrs_len);
3526 librados::IoCtx ctx;
3527 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3528 std::string name_str = name;
3529 std::string oid = o;
3530 std::string tag_str;
3531 int tmp_exclusive;
3532 std::list<librados::locker_t> lockers;
3533 int r = ctx.list_lockers(oid, name_str, &tmp_exclusive, &tag_str, &lockers);
3534 if (r < 0) {
3535 tracepoint(librados, rados_list_lockers_exit, r, *exclusive, "", *tag_len, *clients_len, *cookies_len, *addrs_len);
3536 return r;
3537 }
3538
3539 size_t clients_total = 0;
3540 size_t cookies_total = 0;
3541 size_t addrs_total = 0;
3542 list<librados::locker_t>::const_iterator it;
3543 for (it = lockers.begin(); it != lockers.end(); ++it) {
3544 clients_total += it->client.length() + 1;
3545 cookies_total += it->cookie.length() + 1;
3546 addrs_total += it->address.length() + 1;
3547 }
3548
3549 bool too_short = ((clients_total > *clients_len) ||
3550 (cookies_total > *cookies_len) ||
3551 (addrs_total > *addrs_len) ||
3552 (tag_str.length() + 1 > *tag_len));
3553 *clients_len = clients_total;
3554 *cookies_len = cookies_total;
3555 *addrs_len = addrs_total;
3556 *tag_len = tag_str.length() + 1;
3557 if (too_short) {
3558 tracepoint(librados, rados_list_lockers_exit, -ERANGE, *exclusive, "", *tag_len, *clients_len, *cookies_len, *addrs_len);
3559 return -ERANGE;
3560 }
3561
3562 strcpy(tag, tag_str.c_str());
3563 char *clients_p = clients;
3564 char *cookies_p = cookies;
3565 char *addrs_p = addrs;
3566 for (it = lockers.begin(); it != lockers.end(); ++it) {
3567 strcpy(clients_p, it->client.c_str());
3568 strcpy(cookies_p, it->cookie.c_str());
3569 strcpy(addrs_p, it->address.c_str());
3570 tracepoint(librados, rados_list_lockers_locker, clients_p, cookies_p, addrs_p);
3571 clients_p += it->client.length() + 1;
3572 cookies_p += it->cookie.length() + 1;
3573 addrs_p += it->address.length() + 1;
3574 }
3575 if (tmp_exclusive)
3576 *exclusive = 1;
3577 else
3578 *exclusive = 0;
3579
3580 int retval = lockers.size();
3581 tracepoint(librados, rados_list_lockers_exit, retval, *exclusive, tag, *tag_len, *clients_len, *cookies_len, *addrs_len);
3582 return retval;
3583 }
3584 LIBRADOS_C_API_BASE_DEFAULT(rados_list_lockers);
3585
3586 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_break_lock)(
3587 rados_ioctx_t io, const char *o,
3588 const char *name, const char *client,
3589 const char *cookie)
3590 {
3591 tracepoint(librados, rados_break_lock_enter, io, o, name, client, cookie);
3592 librados::IoCtx ctx;
3593 librados::IoCtx::from_rados_ioctx_t(io, ctx);
3594
3595 int retval = ctx.break_lock(o, name, client, cookie);
3596 tracepoint(librados, rados_break_lock_exit, retval);
3597 return retval;
3598 }
3599 LIBRADOS_C_API_BASE_DEFAULT(rados_break_lock);
3600
3601 extern "C" rados_write_op_t LIBRADOS_C_API_DEFAULT_F(rados_create_write_op)()
3602 {
3603 tracepoint(librados, rados_create_write_op_enter);
3604 rados_write_op_t retval = new (std::nothrow) librados::ObjectOperationImpl;
3605 tracepoint(librados, rados_create_write_op_exit, retval);
3606 return retval;
3607 }
3608 LIBRADOS_C_API_BASE_DEFAULT(rados_create_write_op);
3609
3610 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_release_write_op)(
3611 rados_write_op_t write_op)
3612 {
3613 tracepoint(librados, rados_release_write_op_enter, write_op);
3614 delete static_cast<librados::ObjectOperationImpl*>(write_op);
3615 tracepoint(librados, rados_release_write_op_exit);
3616 }
3617 LIBRADOS_C_API_BASE_DEFAULT(rados_release_write_op);
3618
3619 static ::ObjectOperation* to_object_operation(rados_write_op_t write_op)
3620 {
3621 return &static_cast<librados::ObjectOperationImpl*>(write_op)->o;
3622 }
3623
3624 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_set_flags)(
3625 rados_write_op_t write_op,
3626 int flags)
3627 {
3628 tracepoint(librados, rados_write_op_set_flags_enter, write_op, flags);
3629 to_object_operation(write_op)->set_last_op_flags(get_op_flags(flags));
3630 tracepoint(librados, rados_write_op_set_flags_exit);
3631 }
3632 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_set_flags);
3633
3634 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_assert_version)(
3635 rados_write_op_t write_op,
3636 uint64_t ver)
3637 {
3638 tracepoint(librados, rados_write_op_assert_version_enter, write_op, ver);
3639 to_object_operation(write_op)->assert_version(ver);
3640 tracepoint(librados, rados_write_op_assert_version_exit);
3641 }
3642 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_assert_version);
3643
3644 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_assert_exists)(
3645 rados_write_op_t write_op)
3646 {
3647 tracepoint(librados, rados_write_op_assert_exists_enter, write_op);
3648 to_object_operation(write_op)->stat(nullptr, nullptr, nullptr);
3649 tracepoint(librados, rados_write_op_assert_exists_exit);
3650 }
3651 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_assert_exists);
3652
3653 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_cmpext)(
3654 rados_write_op_t write_op,
3655 const char *cmp_buf,
3656 size_t cmp_len,
3657 uint64_t off,
3658 int *prval)
3659 {
3660 tracepoint(librados, rados_write_op_cmpext_enter, write_op, cmp_buf,
3661 cmp_len, off, prval);
3662 to_object_operation(write_op)->cmpext(off, cmp_len, cmp_buf, prval);
3663 tracepoint(librados, rados_write_op_cmpext_exit);
3664 }
3665 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_cmpext);
3666
3667 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_cmpxattr)(
3668 rados_write_op_t write_op,
3669 const char *name,
3670 uint8_t comparison_operator,
3671 const char *value,
3672 size_t value_len)
3673 {
3674 tracepoint(librados, rados_write_op_cmpxattr_enter, write_op, name, comparison_operator, value, value_len);
3675 bufferlist bl;
3676 bl.append(value, value_len);
3677 to_object_operation(write_op)->cmpxattr(name,
3678 comparison_operator,
3679 CEPH_OSD_CMPXATTR_MODE_STRING,
3680 bl);
3681 tracepoint(librados, rados_write_op_cmpxattr_exit);
3682 }
3683 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_cmpxattr);
3684
3685 static void rados_c_omap_cmp(ObjectOperation *op,
3686 const char *key,
3687 uint8_t comparison_operator,
3688 const char *val,
3689 size_t key_len,
3690 size_t val_len,
3691 int *prval)
3692 {
3693 bufferlist bl;
3694 bl.append(val, val_len);
3695 std::map<std::string, pair<bufferlist, int> > assertions;
3696 string lkey = string(key, key_len);
3697
3698 assertions[lkey] = std::make_pair(bl, comparison_operator);
3699 op->omap_cmp(assertions, prval);
3700 }
3701
3702 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_cmp)(
3703 rados_write_op_t write_op,
3704 const char *key,
3705 uint8_t comparison_operator,
3706 const char *val,
3707 size_t val_len,
3708 int *prval)
3709 {
3710 tracepoint(librados, rados_write_op_omap_cmp_enter, write_op, key, comparison_operator, val, val_len, prval);
3711 rados_c_omap_cmp(to_object_operation(write_op), key, comparison_operator,
3712 val, strlen(key), val_len, prval);
3713 tracepoint(librados, rados_write_op_omap_cmp_exit);
3714 }
3715 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_cmp);
3716
3717 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_cmp2)(
3718 rados_write_op_t write_op,
3719 const char *key,
3720 uint8_t comparison_operator,
3721 const char *val,
3722 size_t key_len,
3723 size_t val_len,
3724 int *prval)
3725 {
3726 tracepoint(librados, rados_write_op_omap_cmp_enter, write_op, key, comparison_operator, val, val_len, prval);
3727 rados_c_omap_cmp(to_object_operation(write_op), key, comparison_operator,
3728 val, key_len, val_len, prval);
3729 tracepoint(librados, rados_write_op_omap_cmp_exit);
3730 }
3731 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_cmp2);
3732
3733 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_setxattr)(
3734 rados_write_op_t write_op,
3735 const char *name,
3736 const char *value,
3737 size_t value_len)
3738 {
3739 tracepoint(librados, rados_write_op_setxattr_enter, write_op, name, value, value_len);
3740 bufferlist bl;
3741 bl.append(value, value_len);
3742 to_object_operation(write_op)->setxattr(name, bl);
3743 tracepoint(librados, rados_write_op_setxattr_exit);
3744 }
3745 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_setxattr);
3746
3747 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_rmxattr)(
3748 rados_write_op_t write_op,
3749 const char *name)
3750 {
3751 tracepoint(librados, rados_write_op_rmxattr_enter, write_op, name);
3752 to_object_operation(write_op)->rmxattr(name);
3753 tracepoint(librados, rados_write_op_rmxattr_exit);
3754 }
3755 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_rmxattr);
3756
3757 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_create)(
3758 rados_write_op_t write_op,
3759 int exclusive,
3760 const char* category) // unused
3761 {
3762 tracepoint(librados, rados_write_op_create_enter, write_op, exclusive);
3763 to_object_operation(write_op)->create(!!exclusive);
3764 tracepoint(librados, rados_write_op_create_exit);
3765 }
3766 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_create);
3767
3768 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_write)(
3769 rados_write_op_t write_op,
3770 const char *buffer,
3771 size_t len,
3772 uint64_t offset)
3773 {
3774 tracepoint(librados, rados_write_op_write_enter, write_op, buffer, len, offset);
3775 bufferlist bl;
3776 bl.append(buffer,len);
3777 to_object_operation(write_op)->write(offset, bl);
3778 tracepoint(librados, rados_write_op_write_exit);
3779 }
3780 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_write);
3781
3782 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_write_full)(
3783 rados_write_op_t write_op,
3784 const char *buffer,
3785 size_t len)
3786 {
3787 tracepoint(librados, rados_write_op_write_full_enter, write_op, buffer, len);
3788 bufferlist bl;
3789 bl.append(buffer,len);
3790 to_object_operation(write_op)->write_full(bl);
3791 tracepoint(librados, rados_write_op_write_full_exit);
3792 }
3793 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_write_full);
3794
3795 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_writesame)(
3796 rados_write_op_t write_op,
3797 const char *buffer,
3798 size_t data_len,
3799 size_t write_len,
3800 uint64_t offset)
3801 {
3802 tracepoint(librados, rados_write_op_writesame_enter, write_op, buffer, data_len, write_len, offset);
3803 bufferlist bl;
3804 bl.append(buffer, data_len);
3805 to_object_operation(write_op)->writesame(offset, write_len, bl);
3806 tracepoint(librados, rados_write_op_writesame_exit);
3807 }
3808 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_writesame);
3809
3810 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_append)(
3811 rados_write_op_t write_op,
3812 const char *buffer,
3813 size_t len)
3814 {
3815 tracepoint(librados, rados_write_op_append_enter, write_op, buffer, len);
3816 bufferlist bl;
3817 bl.append(buffer,len);
3818 to_object_operation(write_op)->append(bl);
3819 tracepoint(librados, rados_write_op_append_exit);
3820 }
3821 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_append);
3822
3823 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_remove)(
3824 rados_write_op_t write_op)
3825 {
3826 tracepoint(librados, rados_write_op_remove_enter, write_op);
3827 to_object_operation(write_op)->remove();
3828 tracepoint(librados, rados_write_op_remove_exit);
3829 }
3830 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_remove);
3831
3832 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_truncate)(
3833 rados_write_op_t write_op,
3834 uint64_t offset)
3835 {
3836 tracepoint(librados, rados_write_op_truncate_enter, write_op, offset);
3837 to_object_operation(write_op)->truncate(offset);
3838 tracepoint(librados, rados_write_op_truncate_exit);
3839 }
3840 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_truncate);
3841
3842 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_zero)(
3843 rados_write_op_t write_op,
3844 uint64_t offset,
3845 uint64_t len)
3846 {
3847 tracepoint(librados, rados_write_op_zero_enter, write_op, offset, len);
3848 to_object_operation(write_op)->zero(offset, len);
3849 tracepoint(librados, rados_write_op_zero_exit);
3850 }
3851 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_zero);
3852
3853 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_exec)(
3854 rados_write_op_t write_op,
3855 const char *cls,
3856 const char *method,
3857 const char *in_buf,
3858 size_t in_len,
3859 int *prval)
3860 {
3861 tracepoint(librados, rados_write_op_exec_enter, write_op, cls, method, in_buf, in_len, prval);
3862 bufferlist inbl;
3863 inbl.append(in_buf, in_len);
3864 to_object_operation(write_op)->call(cls, method, inbl, NULL, NULL, prval);
3865 tracepoint(librados, rados_write_op_exec_exit);
3866 }
3867 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_exec);
3868
3869 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_set)(
3870 rados_write_op_t write_op,
3871 char const* const* keys,
3872 char const* const* vals,
3873 const size_t *lens,
3874 size_t num)
3875 {
3876 tracepoint(librados, rados_write_op_omap_set_enter, write_op, num);
3877 std::map<std::string, bufferlist> entries;
3878 for (size_t i = 0; i < num; ++i) {
3879 tracepoint(librados, rados_write_op_omap_set_entry, keys[i], vals[i], lens[i]);
3880 bufferlist bl(lens[i]);
3881 bl.append(vals[i], lens[i]);
3882 entries[keys[i]] = bl;
3883 }
3884 to_object_operation(write_op)->omap_set(entries);
3885 tracepoint(librados, rados_write_op_omap_set_exit);
3886 }
3887 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_set);
3888
3889 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_set2)(
3890 rados_write_op_t write_op,
3891 char const* const* keys,
3892 char const* const* vals,
3893 const size_t *key_lens,
3894 const size_t *val_lens,
3895 size_t num)
3896 {
3897 tracepoint(librados, rados_write_op_omap_set_enter, write_op, num);
3898 std::map<std::string, bufferlist> entries;
3899 for (size_t i = 0; i < num; ++i) {
3900 bufferlist bl(val_lens[i]);
3901 bl.append(vals[i], val_lens[i]);
3902 string key(keys[i], key_lens[i]);
3903 entries[key] = bl;
3904 }
3905 to_object_operation(write_op)->omap_set(entries);
3906 tracepoint(librados, rados_write_op_omap_set_exit);
3907 }
3908 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_set2);
3909
3910 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_rm_keys)(
3911 rados_write_op_t write_op,
3912 char const* const* keys,
3913 size_t keys_len)
3914 {
3915 tracepoint(librados, rados_write_op_omap_rm_keys_enter, write_op, keys_len);
3916 for(size_t i = 0; i < keys_len; i++) {
3917 tracepoint(librados, rados_write_op_omap_rm_keys_entry, keys[i]);
3918 }
3919 std::set<std::string> to_remove(keys, keys + keys_len);
3920 to_object_operation(write_op)->omap_rm_keys(to_remove);
3921 tracepoint(librados, rados_write_op_omap_rm_keys_exit);
3922 }
3923 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_rm_keys);
3924
3925 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_rm_keys2)(
3926 rados_write_op_t write_op,
3927 char const* const* keys,
3928 const size_t* key_lens,
3929 size_t keys_len)
3930 {
3931 tracepoint(librados, rados_write_op_omap_rm_keys_enter, write_op, keys_len);
3932 std::set<std::string> to_remove;
3933 for(size_t i = 0; i < keys_len; i++) {
3934 to_remove.emplace(keys[i], key_lens[i]);
3935 }
3936 to_object_operation(write_op)->omap_rm_keys(to_remove);
3937 tracepoint(librados, rados_write_op_omap_rm_keys_exit);
3938 }
3939 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_rm_keys2);
3940
3941 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_rm_range2)(
3942 rados_write_op_t write_op,
3943 const char *key_begin,
3944 size_t key_begin_len,
3945 const char *key_end,
3946 size_t key_end_len)
3947 {
3948 tracepoint(librados, rados_write_op_omap_rm_range_enter,
3949 write_op, key_begin, key_end);
3950 to_object_operation(write_op)->omap_rm_range({key_begin, key_begin_len},
3951 {key_end, key_end_len});
3952 tracepoint(librados, rados_write_op_omap_rm_range_exit);
3953 }
3954 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_rm_range2);
3955
3956 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_omap_clear)(
3957 rados_write_op_t write_op)
3958 {
3959 tracepoint(librados, rados_write_op_omap_clear_enter, write_op);
3960 to_object_operation(write_op)->omap_clear();
3961 tracepoint(librados, rados_write_op_omap_clear_exit);
3962 }
3963 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_omap_clear);
3964
3965 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_set_alloc_hint)(
3966 rados_write_op_t write_op,
3967 uint64_t expected_object_size,
3968 uint64_t expected_write_size)
3969 {
3970 tracepoint(librados, rados_write_op_set_alloc_hint_enter, write_op, expected_object_size, expected_write_size);
3971 to_object_operation(write_op)->set_alloc_hint(expected_object_size,
3972 expected_write_size, 0);
3973 tracepoint(librados, rados_write_op_set_alloc_hint_exit);
3974 }
3975 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_set_alloc_hint);
3976
3977 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_write_op_set_alloc_hint2)(
3978 rados_write_op_t write_op,
3979 uint64_t expected_object_size,
3980 uint64_t expected_write_size,
3981 uint32_t flags)
3982 {
3983 tracepoint(librados, rados_write_op_set_alloc_hint2_enter, write_op, expected_object_size, expected_write_size, flags);
3984 to_object_operation(write_op)->set_alloc_hint(expected_object_size,
3985 expected_write_size,
3986 flags);
3987 tracepoint(librados, rados_write_op_set_alloc_hint2_exit);
3988 }
3989 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_set_alloc_hint2);
3990
3991 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_write_op_operate)(
3992 rados_write_op_t write_op,
3993 rados_ioctx_t io,
3994 const char *oid,
3995 time_t *mtime,
3996 int flags)
3997 {
3998 tracepoint(librados, rados_write_op_operate_enter, write_op, io, oid, mtime, flags);
3999 object_t obj(oid);
4000 auto oimpl = static_cast<librados::ObjectOperationImpl*>(write_op);
4001 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4002
4003 if (mtime) {
4004 oimpl->rt = ceph::real_clock::from_time_t(*mtime);
4005 oimpl->prt = &oimpl->rt;
4006 }
4007
4008 int retval = ctx->operate(obj, &oimpl->o, oimpl->prt, translate_flags(flags));
4009 tracepoint(librados, rados_write_op_operate_exit, retval);
4010 return retval;
4011 }
4012 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_operate);
4013
4014 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_write_op_operate2)(
4015 rados_write_op_t write_op,
4016 rados_ioctx_t io,
4017 const char *oid,
4018 struct timespec *ts,
4019 int flags)
4020 {
4021 tracepoint(librados, rados_write_op_operate2_enter, write_op, io, oid, ts, flags);
4022 object_t obj(oid);
4023 auto oimpl = static_cast<librados::ObjectOperationImpl*>(write_op);
4024 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4025
4026 if (ts) {
4027 oimpl->rt = ceph::real_clock::from_timespec(*ts);
4028 oimpl->prt = &oimpl->rt;
4029 }
4030
4031 int retval = ctx->operate(obj, &oimpl->o, oimpl->prt, translate_flags(flags));
4032 tracepoint(librados, rados_write_op_operate_exit, retval);
4033 return retval;
4034 }
4035 LIBRADOS_C_API_BASE_DEFAULT(rados_write_op_operate2);
4036
4037 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_write_op_operate)(
4038 rados_write_op_t write_op,
4039 rados_ioctx_t io,
4040 rados_completion_t completion,
4041 const char *oid,
4042 time_t *mtime,
4043 int flags)
4044 {
4045 tracepoint(librados, rados_aio_write_op_operate_enter, write_op, io, completion, oid, mtime, flags);
4046 object_t obj(oid);
4047 auto oimpl = static_cast<librados::ObjectOperationImpl*>(write_op);
4048 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4049 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
4050
4051 if (mtime) {
4052 oimpl->rt = ceph::real_clock::from_time_t(*mtime);
4053 oimpl->prt = &oimpl->rt;
4054 }
4055
4056 int retval = ctx->aio_operate(obj, &oimpl->o, c, ctx->snapc, oimpl->prt, translate_flags(flags));
4057 tracepoint(librados, rados_aio_write_op_operate_exit, retval);
4058 return retval;
4059 }
4060 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_write_op_operate);
4061
4062 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_write_op_operate2)(
4063 rados_write_op_t write_op,
4064 rados_ioctx_t io,
4065 rados_completion_t completion,
4066 const char *oid,
4067 struct timespec *mtime,
4068 int flags)
4069 {
4070 tracepoint(librados, rados_aio_write_op_operate2_enter, write_op, io, completion, oid, mtime, flags);
4071 object_t obj(oid);
4072 auto oimpl = static_cast<librados::ObjectOperationImpl*>(write_op);
4073 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4074 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
4075
4076 if (mtime) {
4077 oimpl->rt = ceph::real_clock::from_timespec(*mtime);
4078 oimpl->prt = &oimpl->rt;
4079 }
4080
4081 int retval = ctx->aio_operate(obj, &oimpl->o, c, ctx->snapc, oimpl->prt, translate_flags(flags));
4082 tracepoint(librados, rados_aio_write_op_operate_exit, retval);
4083 return retval;
4084 }
4085 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_write_op_operate2);
4086
4087 extern "C" rados_read_op_t LIBRADOS_C_API_DEFAULT_F(rados_create_read_op)()
4088 {
4089 tracepoint(librados, rados_create_read_op_enter);
4090 rados_read_op_t retval = new (std::nothrow)::ObjectOperation;
4091 tracepoint(librados, rados_create_read_op_exit, retval);
4092 return retval;
4093 }
4094 LIBRADOS_C_API_BASE_DEFAULT(rados_create_read_op);
4095
4096 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_release_read_op)(
4097 rados_read_op_t read_op)
4098 {
4099 tracepoint(librados, rados_release_read_op_enter, read_op);
4100 delete (::ObjectOperation *)read_op;
4101 tracepoint(librados, rados_release_read_op_exit);
4102 }
4103 LIBRADOS_C_API_BASE_DEFAULT(rados_release_read_op);
4104
4105 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_set_flags)(
4106 rados_read_op_t read_op,
4107 int flags)
4108 {
4109 tracepoint(librados, rados_read_op_set_flags_enter, read_op, flags);
4110 ((::ObjectOperation *)read_op)->set_last_op_flags(get_op_flags(flags));
4111 tracepoint(librados, rados_read_op_set_flags_exit);
4112 }
4113 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_set_flags);
4114
4115 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_assert_version)(
4116 rados_read_op_t read_op,
4117 uint64_t ver)
4118 {
4119 tracepoint(librados, rados_read_op_assert_version_enter, read_op, ver);
4120 ((::ObjectOperation *)read_op)->assert_version(ver);
4121 tracepoint(librados, rados_read_op_assert_version_exit);
4122 }
4123 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_assert_version);
4124
4125 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_assert_exists)(
4126 rados_read_op_t read_op)
4127 {
4128 tracepoint(librados, rados_read_op_assert_exists_enter, read_op);
4129 ((::ObjectOperation *)read_op)->stat(nullptr, nullptr, nullptr);
4130 tracepoint(librados, rados_read_op_assert_exists_exit);
4131 }
4132 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_assert_exists);
4133
4134 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_cmpext)(
4135 rados_read_op_t read_op,
4136 const char *cmp_buf,
4137 size_t cmp_len,
4138 uint64_t off,
4139 int *prval)
4140 {
4141 tracepoint(librados, rados_read_op_cmpext_enter, read_op, cmp_buf,
4142 cmp_len, off, prval);
4143 ((::ObjectOperation *)read_op)->cmpext(off, cmp_len, cmp_buf, prval);
4144 tracepoint(librados, rados_read_op_cmpext_exit);
4145 }
4146 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_cmpext);
4147
4148 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_cmpxattr)(
4149 rados_read_op_t read_op,
4150 const char *name,
4151 uint8_t comparison_operator,
4152 const char *value,
4153 size_t value_len)
4154 {
4155 tracepoint(librados, rados_read_op_cmpxattr_enter, read_op, name, comparison_operator, value, value_len);
4156 bufferlist bl;
4157 bl.append(value, value_len);
4158 ((::ObjectOperation *)read_op)->cmpxattr(name,
4159 comparison_operator,
4160 CEPH_OSD_CMPXATTR_MODE_STRING,
4161 bl);
4162 tracepoint(librados, rados_read_op_cmpxattr_exit);
4163 }
4164 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_cmpxattr);
4165
4166 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_cmp)(
4167 rados_read_op_t read_op,
4168 const char *key,
4169 uint8_t comparison_operator,
4170 const char *val,
4171 size_t val_len,
4172 int *prval)
4173 {
4174 tracepoint(librados, rados_read_op_omap_cmp_enter, read_op, key, comparison_operator, val, val_len, prval);
4175 rados_c_omap_cmp((::ObjectOperation *)read_op, key, comparison_operator,
4176 val, strlen(key), val_len, prval);
4177 tracepoint(librados, rados_read_op_omap_cmp_exit);
4178 }
4179 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_cmp);
4180
4181 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_cmp2)(
4182 rados_read_op_t read_op,
4183 const char *key,
4184 uint8_t comparison_operator,
4185 const char *val,
4186 size_t key_len,
4187 size_t val_len,
4188 int *prval)
4189 {
4190 tracepoint(librados, rados_read_op_omap_cmp_enter, read_op, key, comparison_operator, val, val_len, prval);
4191 rados_c_omap_cmp((::ObjectOperation *)read_op, key, comparison_operator,
4192 val, key_len, val_len, prval);
4193 tracepoint(librados, rados_read_op_omap_cmp_exit);
4194 }
4195 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_cmp2);
4196
4197 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_stat)(
4198 rados_read_op_t read_op,
4199 uint64_t *psize,
4200 time_t *pmtime,
4201 int *prval)
4202 {
4203 tracepoint(librados, rados_read_op_stat_enter, read_op, psize, pmtime, prval);
4204 ((::ObjectOperation *)read_op)->stat(psize, pmtime, prval);
4205 tracepoint(librados, rados_read_op_stat_exit);
4206 }
4207 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_stat);
4208
4209 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_stat2)(
4210 rados_read_op_t read_op,
4211 uint64_t *psize,
4212 struct timespec *pmtime,
4213 int *prval)
4214 {
4215 tracepoint(librados, rados_read_op_stat2_enter, read_op, psize, pmtime, prval);
4216 ((::ObjectOperation *)read_op)->stat(psize, pmtime, prval);
4217 tracepoint(librados, rados_read_op_stat2_exit);
4218 }
4219 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_stat2);
4220
4221 class C_bl_to_buf : public Context {
4222 char *out_buf;
4223 size_t out_len;
4224 size_t *bytes_read;
4225 int *prval;
4226 public:
4227 bufferlist out_bl;
4228 C_bl_to_buf(char *out_buf,
4229 size_t out_len,
4230 size_t *bytes_read,
4231 int *prval) : out_buf(out_buf), out_len(out_len),
4232 bytes_read(bytes_read), prval(prval) {}
4233 void finish(int r) override {
4234 if (out_bl.length() > out_len) {
4235 if (prval)
4236 *prval = -ERANGE;
4237 if (bytes_read)
4238 *bytes_read = 0;
4239 return;
4240 }
4241 if (bytes_read)
4242 *bytes_read = out_bl.length();
4243 if (out_buf && !out_bl.is_provided_buffer(out_buf))
4244 out_bl.begin().copy(out_bl.length(), out_buf);
4245 }
4246 };
4247
4248 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_read)(
4249 rados_read_op_t read_op,
4250 uint64_t offset,
4251 size_t len,
4252 char *buf,
4253 size_t *bytes_read,
4254 int *prval)
4255 {
4256 tracepoint(librados, rados_read_op_read_enter, read_op, offset, len, buf, bytes_read, prval);
4257 C_bl_to_buf *ctx = new C_bl_to_buf(buf, len, bytes_read, prval);
4258 ctx->out_bl.push_back(buffer::create_static(len, buf));
4259 ((::ObjectOperation *)read_op)->read(offset, len, &ctx->out_bl, prval, ctx);
4260 tracepoint(librados, rados_read_op_read_exit);
4261 }
4262 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_read);
4263
4264 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_checksum)(
4265 rados_read_op_t read_op,
4266 rados_checksum_type_t type,
4267 const char *init_value,
4268 size_t init_value_len,
4269 uint64_t offset, size_t len,
4270 size_t chunk_size, char *pchecksum,
4271 size_t checksum_len, int *prval)
4272 {
4273 tracepoint(librados, rados_read_op_checksum_enter, read_op, type, init_value,
4274 init_value_len, offset, len, chunk_size);
4275 bufferlist init_value_bl;
4276 init_value_bl.append(init_value, init_value_len);
4277
4278 C_bl_to_buf *ctx = nullptr;
4279 if (pchecksum != nullptr) {
4280 ctx = new C_bl_to_buf(pchecksum, checksum_len, nullptr, prval);
4281 }
4282 ((::ObjectOperation *)read_op)->checksum(get_checksum_op_type(type),
4283 init_value_bl, offset, len,
4284 chunk_size,
4285 (ctx ? &ctx->out_bl : nullptr),
4286 prval, ctx);
4287 tracepoint(librados, rados_read_op_checksum_exit);
4288 }
4289 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_checksum);
4290
4291 class C_out_buffer : public Context {
4292 char **out_buf;
4293 size_t *out_len;
4294 public:
4295 bufferlist out_bl;
4296 C_out_buffer(char **out_buf, size_t *out_len) : out_buf(out_buf),
4297 out_len(out_len) {}
4298 void finish(int r) override {
4299 // ignore r since we don't know the meaning of return values
4300 // from custom class methods
4301 do_out_buffer(out_bl, out_buf, out_len);
4302 }
4303 };
4304
4305 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_exec)(
4306 rados_read_op_t read_op,
4307 const char *cls,
4308 const char *method,
4309 const char *in_buf,
4310 size_t in_len,
4311 char **out_buf,
4312 size_t *out_len,
4313 int *prval)
4314 {
4315 tracepoint(librados, rados_read_op_exec_enter, read_op, cls, method, in_buf, in_len, out_buf, out_len, prval);
4316 bufferlist inbl;
4317 inbl.append(in_buf, in_len);
4318 C_out_buffer *ctx = new C_out_buffer(out_buf, out_len);
4319 ((::ObjectOperation *)read_op)->call(cls, method, inbl, &ctx->out_bl, ctx,
4320 prval);
4321 tracepoint(librados, rados_read_op_exec_exit);
4322 }
4323 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_exec);
4324
4325 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_exec_user_buf)(
4326 rados_read_op_t read_op,
4327 const char *cls,
4328 const char *method,
4329 const char *in_buf,
4330 size_t in_len,
4331 char *out_buf,
4332 size_t out_len,
4333 size_t *used_len,
4334 int *prval)
4335 {
4336 tracepoint(librados, rados_read_op_exec_user_buf_enter, read_op, cls, method, in_buf, in_len, out_buf, out_len, used_len, prval);
4337 C_bl_to_buf *ctx = new C_bl_to_buf(out_buf, out_len, used_len, prval);
4338 bufferlist inbl;
4339 inbl.append(in_buf, in_len);
4340 ((::ObjectOperation *)read_op)->call(cls, method, inbl, &ctx->out_bl, ctx,
4341 prval);
4342 tracepoint(librados, rados_read_op_exec_user_buf_exit);
4343 }
4344 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_exec_user_buf);
4345
4346 struct RadosOmapIter {
4347 std::map<std::string, bufferlist> values;
4348 std::map<std::string, bufferlist>::iterator i;
4349 };
4350
4351 class C_OmapIter : public Context {
4352 RadosOmapIter *iter;
4353 public:
4354 explicit C_OmapIter(RadosOmapIter *iter) : iter(iter) {}
4355 void finish(int r) override {
4356 iter->i = iter->values.begin();
4357 }
4358 };
4359
4360 class C_XattrsIter : public Context {
4361 librados::RadosXattrsIter *iter;
4362 public:
4363 explicit C_XattrsIter(librados::RadosXattrsIter *iter) : iter(iter) {}
4364 void finish(int r) override {
4365 iter->i = iter->attrset.begin();
4366 }
4367 };
4368
4369 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_getxattrs)(
4370 rados_read_op_t read_op,
4371 rados_xattrs_iter_t *iter,
4372 int *prval)
4373 {
4374 tracepoint(librados, rados_read_op_getxattrs_enter, read_op, prval);
4375 librados::RadosXattrsIter *xattrs_iter = new librados::RadosXattrsIter;
4376 ((::ObjectOperation *)read_op)->getxattrs(&xattrs_iter->attrset, prval);
4377 ((::ObjectOperation *)read_op)->set_handler(new C_XattrsIter(xattrs_iter));
4378 *iter = xattrs_iter;
4379 tracepoint(librados, rados_read_op_getxattrs_exit, *iter);
4380 }
4381 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_getxattrs);
4382
4383 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_vals)(
4384 rados_read_op_t read_op,
4385 const char *start_after,
4386 const char *filter_prefix,
4387 uint64_t max_return,
4388 rados_omap_iter_t *iter,
4389 int *prval)
4390 {
4391 tracepoint(librados, rados_read_op_omap_get_vals_enter, read_op, start_after, filter_prefix, max_return, prval);
4392 RadosOmapIter *omap_iter = new RadosOmapIter;
4393 const char *start = start_after ? start_after : "";
4394 const char *filter = filter_prefix ? filter_prefix : "";
4395 ((::ObjectOperation *)read_op)->omap_get_vals(
4396 start,
4397 filter,
4398 max_return,
4399 &omap_iter->values,
4400 nullptr,
4401 prval);
4402 ((::ObjectOperation *)read_op)->set_handler(new C_OmapIter(omap_iter));
4403 *iter = omap_iter;
4404 tracepoint(librados, rados_read_op_omap_get_vals_exit, *iter);
4405 }
4406 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_vals);
4407
4408 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_vals2)(
4409 rados_read_op_t read_op,
4410 const char *start_after,
4411 const char *filter_prefix,
4412 uint64_t max_return,
4413 rados_omap_iter_t *iter,
4414 unsigned char *pmore,
4415 int *prval)
4416 {
4417 tracepoint(librados, rados_read_op_omap_get_vals_enter, read_op, start_after, filter_prefix, max_return, prval);
4418 RadosOmapIter *omap_iter = new RadosOmapIter;
4419 const char *start = start_after ? start_after : "";
4420 const char *filter = filter_prefix ? filter_prefix : "";
4421 ((::ObjectOperation *)read_op)->omap_get_vals(
4422 start,
4423 filter,
4424 max_return,
4425 &omap_iter->values,
4426 (bool*)pmore,
4427 prval);
4428 ((::ObjectOperation *)read_op)->set_handler(new C_OmapIter(omap_iter));
4429 *iter = omap_iter;
4430 tracepoint(librados, rados_read_op_omap_get_vals_exit, *iter);
4431 }
4432 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_vals2);
4433
4434 struct C_OmapKeysIter : public Context {
4435 RadosOmapIter *iter;
4436 std::set<std::string> keys;
4437 explicit C_OmapKeysIter(RadosOmapIter *iter) : iter(iter) {}
4438 void finish(int r) override {
4439 // map each key to an empty bl
4440 for (std::set<std::string>::const_iterator i = keys.begin();
4441 i != keys.end(); ++i) {
4442 iter->values[*i];
4443 }
4444 iter->i = iter->values.begin();
4445 }
4446 };
4447
4448 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_keys)(
4449 rados_read_op_t read_op,
4450 const char *start_after,
4451 uint64_t max_return,
4452 rados_omap_iter_t *iter,
4453 int *prval)
4454 {
4455 tracepoint(librados, rados_read_op_omap_get_keys_enter, read_op, start_after, max_return, prval);
4456 RadosOmapIter *omap_iter = new RadosOmapIter;
4457 C_OmapKeysIter *ctx = new C_OmapKeysIter(omap_iter);
4458 ((::ObjectOperation *)read_op)->omap_get_keys(
4459 start_after ? start_after : "",
4460 max_return, &ctx->keys, nullptr, prval);
4461 ((::ObjectOperation *)read_op)->set_handler(ctx);
4462 *iter = omap_iter;
4463 tracepoint(librados, rados_read_op_omap_get_keys_exit, *iter);
4464 }
4465 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_keys);
4466
4467 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_keys2)(
4468 rados_read_op_t read_op,
4469 const char *start_after,
4470 uint64_t max_return,
4471 rados_omap_iter_t *iter,
4472 unsigned char *pmore,
4473 int *prval)
4474 {
4475 tracepoint(librados, rados_read_op_omap_get_keys_enter, read_op, start_after, max_return, prval);
4476 RadosOmapIter *omap_iter = new RadosOmapIter;
4477 C_OmapKeysIter *ctx = new C_OmapKeysIter(omap_iter);
4478 ((::ObjectOperation *)read_op)->omap_get_keys(
4479 start_after ? start_after : "",
4480 max_return, &ctx->keys,
4481 (bool*)pmore, prval);
4482 ((::ObjectOperation *)read_op)->set_handler(ctx);
4483 *iter = omap_iter;
4484 tracepoint(librados, rados_read_op_omap_get_keys_exit, *iter);
4485 }
4486 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_keys2);
4487
4488 static void internal_rados_read_op_omap_get_vals_by_keys(rados_read_op_t read_op,
4489 set<string>& to_get,
4490 rados_omap_iter_t *iter,
4491 int *prval)
4492 {
4493 RadosOmapIter *omap_iter = new RadosOmapIter;
4494 ((::ObjectOperation *)read_op)->omap_get_vals_by_keys(to_get,
4495 &omap_iter->values,
4496 prval);
4497 ((::ObjectOperation *)read_op)->set_handler(new C_OmapIter(omap_iter));
4498 *iter = omap_iter;
4499 }
4500
4501 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_vals_by_keys)(
4502 rados_read_op_t read_op,
4503 char const* const* keys,
4504 size_t keys_len,
4505 rados_omap_iter_t *iter,
4506 int *prval)
4507 {
4508 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_enter, read_op, keys, keys_len, iter, prval);
4509 std::set<std::string> to_get(keys, keys + keys_len);
4510 internal_rados_read_op_omap_get_vals_by_keys(read_op, to_get, iter, prval);
4511 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_exit, *iter);
4512 }
4513 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_vals_by_keys);
4514
4515 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_read_op_omap_get_vals_by_keys2)(
4516 rados_read_op_t read_op,
4517 char const* const* keys,
4518 size_t num_keys,
4519 const size_t* key_lens,
4520 rados_omap_iter_t *iter,
4521 int *prval)
4522 {
4523 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_enter, read_op, keys, num_keys, iter, prval);
4524 std::set<std::string> to_get;
4525 for (size_t i = 0; i < num_keys; i++) {
4526 to_get.emplace(keys[i], key_lens[i]);
4527 }
4528 internal_rados_read_op_omap_get_vals_by_keys(read_op, to_get, iter, prval);
4529 tracepoint(librados, rados_read_op_omap_get_vals_by_keys_exit, *iter);
4530 }
4531 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_omap_get_vals_by_keys2);
4532
4533 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_omap_get_next2)(
4534 rados_omap_iter_t iter,
4535 char **key,
4536 char **val,
4537 size_t *key_len,
4538 size_t *val_len)
4539 {
4540 tracepoint(librados, rados_omap_get_next_enter, iter);
4541 RadosOmapIter *it = static_cast<RadosOmapIter *>(iter);
4542 if (it->i == it->values.end()) {
4543 if (key)
4544 *key = NULL;
4545 if (val)
4546 *val = NULL;
4547 if (key_len)
4548 *key_len = 0;
4549 if (val_len)
4550 *val_len = 0;
4551 tracepoint(librados, rados_omap_get_next_exit, 0, key, val, val_len);
4552 return 0;
4553 }
4554 if (key)
4555 *key = (char*)it->i->first.c_str();
4556 if (val)
4557 *val = it->i->second.c_str();
4558 if (key_len)
4559 *key_len = it->i->first.length();
4560 if (val_len)
4561 *val_len = it->i->second.length();
4562 ++it->i;
4563 tracepoint(librados, rados_omap_get_next_exit, 0, key, val, val_len);
4564 return 0;
4565 }
4566 LIBRADOS_C_API_BASE_DEFAULT(rados_omap_get_next2);
4567
4568 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_omap_get_next)(
4569 rados_omap_iter_t iter,
4570 char **key,
4571 char **val,
4572 size_t *len)
4573 {
4574 return LIBRADOS_C_API_DEFAULT_F(rados_omap_get_next2)(iter, key, val, nullptr, len);
4575 }
4576 LIBRADOS_C_API_BASE_DEFAULT(rados_omap_get_next);
4577
4578 extern "C" unsigned int LIBRADOS_C_API_DEFAULT_F(rados_omap_iter_size)(
4579 rados_omap_iter_t iter)
4580 {
4581 RadosOmapIter *it = static_cast<RadosOmapIter *>(iter);
4582 return it->values.size();
4583 }
4584 LIBRADOS_C_API_BASE_DEFAULT(rados_omap_iter_size);
4585
4586 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_omap_get_end)(
4587 rados_omap_iter_t iter)
4588 {
4589 tracepoint(librados, rados_omap_get_end_enter, iter);
4590 RadosOmapIter *it = static_cast<RadosOmapIter *>(iter);
4591 delete it;
4592 tracepoint(librados, rados_omap_get_end_exit);
4593 }
4594 LIBRADOS_C_API_BASE_DEFAULT(rados_omap_get_end);
4595
4596 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_read_op_operate)(
4597 rados_read_op_t read_op,
4598 rados_ioctx_t io,
4599 const char *oid,
4600 int flags)
4601 {
4602 tracepoint(librados, rados_read_op_operate_enter, read_op, io, oid, flags);
4603 object_t obj(oid);
4604 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4605 int retval = ctx->operate_read(obj, (::ObjectOperation *)read_op, NULL,
4606 translate_flags(flags));
4607 tracepoint(librados, rados_read_op_operate_exit, retval);
4608 return retval;
4609 }
4610 LIBRADOS_C_API_BASE_DEFAULT(rados_read_op_operate);
4611
4612 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_aio_read_op_operate)(
4613 rados_read_op_t read_op,
4614 rados_ioctx_t io,
4615 rados_completion_t completion,
4616 const char *oid,
4617 int flags)
4618 {
4619 tracepoint(librados, rados_aio_read_op_operate_enter, read_op, io, completion, oid, flags);
4620 object_t obj(oid);
4621 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4622 librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
4623 int retval = ctx->aio_operate_read(obj, (::ObjectOperation *)read_op,
4624 c, translate_flags(flags), NULL);
4625 tracepoint(librados, rados_aio_read_op_operate_exit, retval);
4626 return retval;
4627 }
4628 LIBRADOS_C_API_BASE_DEFAULT(rados_aio_read_op_operate);
4629
4630 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_cache_pin)(
4631 rados_ioctx_t io,
4632 const char *o)
4633 {
4634 tracepoint(librados, rados_cache_pin_enter, io, o);
4635 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4636 object_t oid(o);
4637 int retval = ctx->cache_pin(oid);
4638 tracepoint(librados, rados_cache_pin_exit, retval);
4639 return retval;
4640 }
4641 LIBRADOS_C_API_BASE_DEFAULT(rados_cache_pin);
4642
4643 extern "C" int LIBRADOS_C_API_DEFAULT_F(rados_cache_unpin)(
4644 rados_ioctx_t io,
4645 const char *o)
4646 {
4647 tracepoint(librados, rados_cache_unpin_enter, io, o);
4648 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4649 object_t oid(o);
4650 int retval = ctx->cache_unpin(oid);
4651 tracepoint(librados, rados_cache_unpin_exit, retval);
4652 return retval;
4653 }
4654 LIBRADOS_C_API_BASE_DEFAULT(rados_cache_unpin);
4655
4656 extern "C" void LIBRADOS_C_API_DEFAULT_F(rados_object_list_slice)(
4657 rados_ioctx_t io,
4658 const rados_object_list_cursor start,
4659 const rados_object_list_cursor finish,
4660 const size_t n,
4661 const size_t m,
4662 rados_object_list_cursor *split_start,
4663 rados_object_list_cursor *split_finish)
4664 {
4665 librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
4666
4667 ceph_assert(split_start);
4668 ceph_assert(split_finish);
4669 hobject_t *split_start_hobj = (hobject_t*)(*split_start);
4670 hobject_t *split_finish_hobj = (hobject_t*)(*split_finish);
4671 ceph_assert(split_start_hobj);
4672 ceph_assert(split_finish_hobj);
4673 hobject_t *start_hobj = (hobject_t*)(start);
4674 hobject_t *finish_hobj = (hobject_t*)(finish);
4675
4676 ctx->object_list_slice(
4677 *start_hobj,
4678 *finish_hobj,
4679 n,
4680 m,
4681 split_start_hobj,
4682 split_finish_hobj);
4683 }
4684 LIBRADOS_C_API_BASE_DEFAULT(rados_object_list_slice);