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