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