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