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