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