]> git.proxmox.com Git - ceph.git/blame - ceph/src/libcephfs.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / libcephfs.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2009-2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include <fcntl.h>
16#include <iostream>
17#include <string.h>
18#include <string>
19
20#include "auth/Crypto.h"
21#include "client/Client.h"
22#include "librados/RadosClient.h"
f67539c2 23#include "common/async/context_pool.h"
7c673cae
FG
24#include "common/ceph_argparse.h"
25#include "common/common_init.h"
26#include "common/config.h"
27#include "common/version.h"
28#include "mon/MonClient.h"
29#include "include/str_list.h"
b3b6e05e 30#include "include/stringify.h"
7c673cae
FG
31#include "messages/MMonMap.h"
32#include "msg/Messenger.h"
11fdf7f2 33#include "include/ceph_assert.h"
b32b8144 34#include "mds/MDSMap.h"
7c673cae
FG
35
36#include "include/cephfs/libcephfs.h"
37
11fdf7f2
TL
38#define DEFAULT_UMASK 002
39
20effc67
TL
40using namespace std;
41
11fdf7f2 42static mode_t umask_cb(void *);
f67539c2
TL
43namespace {
44// Set things up this way so we don't start up threads until mount and
45// kill them off when the last mount goes away, but are tolerant to
46// multiple mounts of overlapping duration.
47std::shared_ptr<ceph::async::io_context_pool> get_icp(CephContext* cct)
48{
49 static std::mutex m;
50 static std::weak_ptr<ceph::async::io_context_pool> icwp;
51
52
53 std::unique_lock l(m);
54
55 auto icp = icwp.lock();
56 if (icp)
57 return icp;
58
59 icp = std::make_shared<ceph::async::io_context_pool>();
60 icwp = icp;
61 icp->start(cct->_conf.get_val<std::uint64_t>("client_asio_thread_count"));
62 return icp;
63}
64}
7c673cae
FG
65
66struct ceph_mount_info
67{
11fdf7f2 68 mode_t umask = DEFAULT_UMASK;
f67539c2 69 std::shared_ptr<ceph::async::io_context_pool> icp;
7c673cae
FG
70public:
71 explicit ceph_mount_info(CephContext *cct_)
72 : default_perms(),
73 mounted(false),
74 inited(false),
11fdf7f2
TL
75 client(nullptr),
76 monclient(nullptr),
77 messenger(nullptr),
7c673cae
FG
78 cct(cct_)
79 {
11fdf7f2 80 if (cct_) {
7c673cae
FG
81 cct->get();
82 }
83 }
84
85 ~ceph_mount_info()
86 {
87 try {
88 shutdown();
89 if (cct) {
90 cct->put();
11fdf7f2 91 cct = nullptr;
7c673cae
FG
92 }
93 }
94 catch (const std::exception& e) {
95 // we shouldn't get here, but if we do, we want to know about it.
96 lderr(cct) << "ceph_mount_info::~ceph_mount_info: caught exception: "
97 << e.what() << dendl;
98 }
99 catch (...) {
100 // ignore
101 }
102 }
103
104 int init()
105 {
7c673cae
FG
106 int ret;
107
f67539c2 108 if (!cct->_log->is_started()) {
11fdf7f2
TL
109 cct->_log->start();
110 }
f67539c2 111 icp = get_icp(cct);
11fdf7f2
TL
112
113 {
f67539c2 114 MonClient mc_bootstrap(cct, icp->get_io_context());
11fdf7f2
TL
115 ret = mc_bootstrap.get_monmap_and_config();
116 if (ret < 0)
117 return ret;
118 }
119
120 common_init_finish(cct);
121
7c673cae 122 //monmap
f67539c2 123 monclient = new MonClient(cct, icp->get_io_context());
7c673cae
FG
124 ret = -CEPHFS_ERROR_MON_MAP_BUILD; //defined in libcephfs.h;
125 if (monclient->build_initial_monmap() < 0)
126 goto fail;
127
128 //network connection
129 messenger = Messenger::create_client_messenger(cct, "client");
130
131 //at last the client
132 ret = -CEPHFS_ERROR_NEW_CLIENT; //defined in libcephfs.h;
f67539c2 133 client = new StandaloneClient(messenger, monclient, icp->get_io_context());
7c673cae
FG
134 if (!client)
135 goto fail;
136
137 ret = -CEPHFS_ERROR_MESSENGER_START; //defined in libcephfs.h;
138 if (messenger->start() != 0)
139 goto fail;
140
141 ret = client->init();
142 if (ret)
143 goto fail;
144
11fdf7f2 145 {
e306af50 146 ceph_client_callback_args args = {};
11fdf7f2
TL
147 args.handle = this;
148 args.umask_cb = umask_cb;
149 client->ll_register_callbacks(&args);
150 }
151
7c673cae
FG
152 default_perms = Client::pick_my_perms(cct);
153 inited = true;
154 return 0;
155
156 fail:
157 shutdown();
158 return ret;
159 }
160
11fdf7f2
TL
161 int select_filesystem(const std::string &fs_name_)
162 {
163 if (mounted) {
1e59de90 164 return -CEPHFS_EISCONN;
11fdf7f2
TL
165 }
166
167 fs_name = fs_name_;
168 return 0;
169 }
170
171 const std::string& get_filesystem(void)
172 {
173 return fs_name;
174 }
175
7c673cae
FG
176 int mount(const std::string &mount_root, const UserPerm& perms)
177 {
178 int ret;
179
180 if (mounted)
1e59de90 181 return -CEPHFS_EISCONN;
7c673cae
FG
182
183 if (!inited) {
184 ret = init();
185 if (ret != 0) {
186 return ret;
187 }
188 }
189
11fdf7f2 190 ret = client->mount(mount_root, perms, false, fs_name);
7c673cae
FG
191 if (ret) {
192 shutdown();
193 return ret;
194 } else {
195 mounted = true;
196 return 0;
197 }
198 }
199
200 int unmount()
201 {
202 if (!mounted)
1e59de90 203 return -CEPHFS_ENOTCONN;
7c673cae
FG
204 shutdown();
205 return 0;
206 }
11fdf7f2
TL
207 int abort_conn()
208 {
209 if (mounted) {
210 client->abort_conn();
211 mounted = false;
212 }
213 return 0;
214 }
7c673cae
FG
215
216 void shutdown()
217 {
218 if (mounted) {
219 client->unmount();
220 mounted = false;
221 }
222 if (inited) {
223 client->shutdown();
224 inited = false;
225 }
226 if (messenger) {
227 messenger->shutdown();
228 messenger->wait();
229 delete messenger;
11fdf7f2 230 messenger = nullptr;
7c673cae 231 }
f67539c2 232 icp.reset();
7c673cae
FG
233 if (monclient) {
234 delete monclient;
11fdf7f2 235 monclient = nullptr;
7c673cae
FG
236 }
237 if (client) {
238 delete client;
11fdf7f2 239 client = nullptr;
7c673cae
FG
240 }
241 }
242
243 bool is_initialized() const
244 {
245 return inited;
246 }
247
248 bool is_mounted()
249 {
250 return mounted;
251 }
252
11fdf7f2
TL
253 mode_t set_umask(mode_t umask)
254 {
255 this->umask = umask;
256 return umask;
257 }
258
9f95a23c
TL
259 std::string getaddrs()
260 {
261 CachedStackStringStream cos;
262 *cos << messenger->get_myaddrs();
263 return std::string(cos->strv());
264 }
265
7c673cae
FG
266 int conf_read_file(const char *path_list)
267 {
11fdf7f2 268 int ret = cct->_conf.parse_config_files(path_list, nullptr, 0);
7c673cae
FG
269 if (ret)
270 return ret;
11fdf7f2 271 cct->_conf.apply_changes(nullptr);
9f95a23c 272 cct->_conf.complain_about_parse_error(cct);
7c673cae
FG
273 return 0;
274 }
275
276 int conf_parse_argv(int argc, const char **argv)
277 {
20effc67
TL
278 auto args = argv_to_vec(argc, argv);
279 int ret = cct->_conf.parse_argv(args);
7c673cae
FG
280 if (ret)
281 return ret;
11fdf7f2 282 cct->_conf.apply_changes(nullptr);
7c673cae
FG
283 return 0;
284 }
285
286 int conf_parse_env(const char *name)
287 {
11fdf7f2
TL
288 auto& conf = cct->_conf;
289 conf.parse_env(cct->get_module_type(), name);
290 conf.apply_changes(nullptr);
7c673cae
FG
291 return 0;
292 }
293
294 int conf_set(const char *option, const char *value)
295 {
11fdf7f2 296 int ret = cct->_conf.set_val(option, value);
7c673cae
FG
297 if (ret)
298 return ret;
11fdf7f2 299 cct->_conf.apply_changes(nullptr);
7c673cae
FG
300 return 0;
301 }
302
303 int conf_get(const char *option, char *buf, size_t len)
304 {
305 char *tmp = buf;
11fdf7f2 306 return cct->_conf.get_val(option, &tmp, len);
7c673cae
FG
307 }
308
309 Client *get_client()
310 {
311 return client;
312 }
313
314 const char *get_cwd(const UserPerm& perms)
315 {
316 client->getcwd(cwd, perms);
317 return cwd.c_str();
318 }
319
320 int chdir(const char *to, const UserPerm& perms)
321 {
322 return client->chdir(to, cwd, perms);
323 }
324
325 CephContext *get_ceph_context() const {
326 return cct;
327 }
328
329 UserPerm default_perms;
330private:
331 bool mounted;
332 bool inited;
333 StandaloneClient *client;
334 MonClient *monclient;
335 Messenger *messenger;
336 CephContext *cct;
337 std::string cwd;
11fdf7f2 338 std::string fs_name;
7c673cae
FG
339};
340
11fdf7f2
TL
341static mode_t umask_cb(void *handle)
342{
343 return ((struct ceph_mount_info *)handle)->umask;
344}
345
7c673cae
FG
346static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
347{
348 if (outbuf) {
349 if (outbl.length() > 0) {
350 *outbuf = (char *)malloc(outbl.length());
351 memcpy(*outbuf, outbl.c_str(), outbl.length());
352 } else {
11fdf7f2 353 *outbuf = nullptr;
7c673cae
FG
354 }
355 }
356 if (outbuflen)
357 *outbuflen = outbl.length();
358}
359
360static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
361{
362 if (outbuf) {
363 if (outbl.length() > 0) {
364 *outbuf = (char *)malloc(outbl.length());
365 memcpy(*outbuf, outbl.c_str(), outbl.length());
366 } else {
11fdf7f2 367 *outbuf = nullptr;
7c673cae
FG
368 }
369 }
370 if (outbuflen)
371 *outbuflen = outbl.length();
372}
373
374extern "C" UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids,
375 gid_t *gidlist)
376{
377 return new (std::nothrow) UserPerm(uid, gid, ngids, gidlist);
378}
379
380extern "C" void ceph_userperm_destroy(UserPerm *perm)
381{
382 delete perm;
383}
384
385extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch)
386{
387 int major, minor, patch;
388 const char *v = ceph_version_to_str();
389
390 int n = sscanf(v, "%d.%d.%d", &major, &minor, &patch);
391 if (pmajor)
392 *pmajor = (n >= 1) ? major : 0;
393 if (pminor)
394 *pminor = (n >= 2) ? minor : 0;
395 if (ppatch)
396 *ppatch = (n >= 3) ? patch : 0;
9f95a23c 397 return PROJECT_VERSION;
7c673cae
FG
398}
399
400extern "C" int ceph_create_with_context(struct ceph_mount_info **cmount, CephContext *cct)
401{
402 *cmount = new struct ceph_mount_info(cct);
403 return 0;
404}
405
406extern "C" int ceph_create_from_rados(struct ceph_mount_info **cmount,
407 rados_t cluster)
408{
409 auto rados = (librados::RadosClient *) cluster;
410 auto cct = rados->cct;
411 return ceph_create_with_context(cmount, cct);
412}
413
414extern "C" int ceph_create(struct ceph_mount_info **cmount, const char * const id)
415{
416 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
417 if (id) {
418 iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
419 }
420
421 CephContext *cct = common_preinit(iparams, CODE_ENVIRONMENT_LIBRARY, 0);
11fdf7f2
TL
422 cct->_conf.parse_env(cct->get_module_type()); // environment variables coverride
423 cct->_conf.apply_changes(nullptr);
7c673cae
FG
424 int ret = ceph_create_with_context(cmount, cct);
425 cct->put();
11fdf7f2 426 cct = nullptr;
7c673cae
FG
427 return ret;
428}
429
430extern "C" int ceph_unmount(struct ceph_mount_info *cmount)
431{
432 return cmount->unmount();
433}
434
11fdf7f2
TL
435extern "C" int ceph_abort_conn(struct ceph_mount_info *cmount)
436{
437 return cmount->abort_conn();
438}
439
7c673cae
FG
440extern "C" int ceph_release(struct ceph_mount_info *cmount)
441{
442 if (cmount->is_mounted())
1e59de90 443 return -CEPHFS_EISCONN;
7c673cae 444 delete cmount;
11fdf7f2 445 cmount = nullptr;
7c673cae
FG
446 return 0;
447}
448
449extern "C" void ceph_shutdown(struct ceph_mount_info *cmount)
450{
451 cmount->shutdown();
452 delete cmount;
11fdf7f2
TL
453 cmount = nullptr;
454}
455
456extern "C" uint64_t ceph_get_instance_id(struct ceph_mount_info *cmount)
457{
458 if (cmount->is_initialized())
459 return cmount->get_client()->get_nodeid().v;
460 return 0;
7c673cae
FG
461}
462
9f95a23c
TL
463extern "C" int ceph_getaddrs(struct ceph_mount_info *cmount, char** addrs)
464{
465 if (!cmount->is_initialized())
1e59de90 466 return -CEPHFS_ENOTCONN;
9f95a23c
TL
467 auto s = cmount->getaddrs();
468 *addrs = strdup(s.c_str());
469 return 0;
470}
471
7c673cae
FG
472extern "C" int ceph_conf_read_file(struct ceph_mount_info *cmount, const char *path)
473{
474 return cmount->conf_read_file(path);
475}
476
11fdf7f2
TL
477extern "C" mode_t ceph_umask(struct ceph_mount_info *cmount, mode_t mode)
478{
479 return cmount->set_umask(mode);
480}
481
7c673cae
FG
482extern "C" int ceph_conf_parse_argv(struct ceph_mount_info *cmount, int argc,
483 const char **argv)
484{
485 return cmount->conf_parse_argv(argc, argv);
486}
487
488extern "C" int ceph_conf_parse_env(struct ceph_mount_info *cmount, const char *name)
489{
490 return cmount->conf_parse_env(name);
491}
492
493extern "C" int ceph_conf_set(struct ceph_mount_info *cmount, const char *option,
494 const char *value)
495{
496 return cmount->conf_set(option, value);
497}
498
499extern "C" int ceph_conf_get(struct ceph_mount_info *cmount, const char *option,
500 char *buf, size_t len)
501{
11fdf7f2 502 if (!buf) {
1e59de90 503 return -CEPHFS_EINVAL;
7c673cae
FG
504 }
505 return cmount->conf_get(option, buf, len);
506}
507
b3b6e05e
TL
508extern "C" int ceph_set_mount_timeout(struct ceph_mount_info *cmount, uint32_t timeout) {
509 if (cmount->is_mounted()) {
1e59de90 510 return -CEPHFS_EINVAL;
b3b6e05e
TL
511 }
512
513 auto timeout_str = stringify(timeout);
514 return ceph_conf_set(cmount, "client_mount_timeout", timeout_str.c_str());
515}
516
7c673cae
FG
517extern "C" int ceph_mds_command(struct ceph_mount_info *cmount,
518 const char *mds_spec,
519 const char **cmd,
520 size_t cmdlen,
521 const char *inbuf, size_t inbuflen,
522 char **outbuf, size_t *outbuflen,
523 char **outsbuf, size_t *outsbuflen)
524{
525 bufferlist inbl;
526 bufferlist outbl;
527 std::vector<string> cmdv;
528 std::string outs;
529
530 if (!cmount->is_initialized()) {
1e59de90 531 return -CEPHFS_ENOTCONN;
7c673cae
FG
532 }
533
534 // Construct inputs
535 for (size_t i = 0; i < cmdlen; ++i) {
536 cmdv.push_back(cmd[i]);
537 }
538 inbl.append(inbuf, inbuflen);
539
540 // Issue remote command
541 C_SaferCond cond;
542 int r = cmount->get_client()->mds_command(
543 mds_spec,
544 cmdv, inbl,
545 &outbl, &outs,
546 &cond);
547
548 if (r != 0) {
549 goto out;
550 }
551
552 // Wait for completion
553 r = cond.wait();
554
555 // Construct outputs
556 do_out_buffer(outbl, outbuf, outbuflen);
557 do_out_buffer(outs, outsbuf, outsbuflen);
558
559out:
560 return r;
561}
562
563extern "C" int ceph_init(struct ceph_mount_info *cmount)
564{
565 return cmount->init();
566}
567
11fdf7f2
TL
568extern "C" int ceph_select_filesystem(struct ceph_mount_info *cmount,
569 const char *fs_name)
570{
571 if (fs_name == nullptr) {
1e59de90 572 return -CEPHFS_EINVAL;
11fdf7f2
TL
573 }
574
575 return cmount->select_filesystem(fs_name);
576}
577
7c673cae
FG
578extern "C" int ceph_mount(struct ceph_mount_info *cmount, const char *root)
579{
580 std::string mount_root;
581 if (root)
582 mount_root = root;
583 return cmount->mount(mount_root, cmount->default_perms);
584}
585
586extern "C" int ceph_is_mounted(struct ceph_mount_info *cmount)
587{
588 return cmount->is_mounted() ? 1 : 0;
589}
590
591extern "C" struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount)
592{
593 return &cmount->default_perms;
594}
595
11fdf7f2
TL
596extern "C" int64_t ceph_get_fs_cid(struct ceph_mount_info *cmount)
597{
598 if (!cmount->is_mounted())
1e59de90 599 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
600 return cmount->get_client()->get_fs_cid();
601}
602
603extern "C" int ceph_mount_perms_set(struct ceph_mount_info *cmount,
604 struct UserPerm *perms)
605{
606 if (cmount->is_mounted())
1e59de90 607 return -CEPHFS_EISCONN;
11fdf7f2
TL
608 cmount->default_perms = *perms;
609 return 0;
610}
611
7c673cae
FG
612extern "C" int ceph_statfs(struct ceph_mount_info *cmount, const char *path,
613 struct statvfs *stbuf)
614{
615 if (!cmount->is_mounted())
1e59de90 616 return -CEPHFS_ENOTCONN;
7c673cae
FG
617 return cmount->get_client()->statfs(path, stbuf, cmount->default_perms);
618}
619
620extern "C" int ceph_get_local_osd(struct ceph_mount_info *cmount)
621{
622 if (!cmount->is_mounted())
1e59de90 623 return -CEPHFS_ENOTCONN;
7c673cae
FG
624 return cmount->get_client()->get_local_osd();
625}
626
627extern "C" const char* ceph_getcwd(struct ceph_mount_info *cmount)
628{
629 return cmount->get_cwd(cmount->default_perms);
630}
631
632extern "C" int ceph_chdir (struct ceph_mount_info *cmount, const char *s)
633{
634 if (!cmount->is_mounted())
1e59de90 635 return -CEPHFS_ENOTCONN;
7c673cae
FG
636 return cmount->chdir(s, cmount->default_perms);
637}
638
639extern "C" int ceph_opendir(struct ceph_mount_info *cmount,
640 const char *name, struct ceph_dir_result **dirpp)
641{
642 if (!cmount->is_mounted())
1e59de90 643 return -CEPHFS_ENOTCONN;
7c673cae
FG
644 return cmount->get_client()->opendir(name, (dir_result_t **)dirpp, cmount->default_perms);
645}
646
b3b6e05e
TL
647extern "C" int ceph_fdopendir(struct ceph_mount_info *cmount, int dirfd,
648 struct ceph_dir_result **dirpp)
649{
650 if (!cmount->is_mounted())
1e59de90 651 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
652 return cmount->get_client()->fdopendir(dirfd, (dir_result_t **)dirpp, cmount->default_perms);
653}
654
7c673cae
FG
655extern "C" int ceph_closedir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
656{
657 if (!cmount->is_mounted())
1e59de90 658 return -CEPHFS_ENOTCONN;
7c673cae
FG
659 return cmount->get_client()->closedir(reinterpret_cast<dir_result_t*>(dirp));
660}
661
662extern "C" struct dirent * ceph_readdir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
663{
664 if (!cmount->is_mounted()) {
665 /* Client::readdir also sets errno to signal errors. */
1e59de90 666 errno = CEPHFS_ENOTCONN;
11fdf7f2 667 return nullptr;
7c673cae
FG
668 }
669 return cmount->get_client()->readdir(reinterpret_cast<dir_result_t*>(dirp));
670}
671
672extern "C" int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de)
673{
674 if (!cmount->is_mounted())
1e59de90 675 return -CEPHFS_ENOTCONN;
7c673cae
FG
676 return cmount->get_client()->readdir_r(reinterpret_cast<dir_result_t*>(dirp), de);
677}
678
679extern "C" int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
680 struct dirent *de, struct ceph_statx *stx, unsigned want,
681 unsigned flags, struct Inode **out)
682{
683 if (!cmount->is_mounted())
1e59de90 684 return -CEPHFS_ENOTCONN;
7c673cae 685 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 686 return -CEPHFS_EINVAL;
7c673cae
FG
687 return cmount->get_client()->readdirplus_r(reinterpret_cast<dir_result_t*>(dirp), de, stx, want, flags, out);
688}
689
690extern "C" int ceph_getdents(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
691 char *buf, int buflen)
692{
693 if (!cmount->is_mounted())
1e59de90 694 return -CEPHFS_ENOTCONN;
7c673cae
FG
695 return cmount->get_client()->getdents(reinterpret_cast<dir_result_t*>(dirp), buf, buflen);
696}
697
698extern "C" int ceph_getdnames(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
699 char *buf, int buflen)
700{
701 if (!cmount->is_mounted())
1e59de90 702 return -CEPHFS_ENOTCONN;
7c673cae
FG
703 return cmount->get_client()->getdnames(reinterpret_cast<dir_result_t*>(dirp), buf, buflen);
704}
705
706extern "C" void ceph_rewinddir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
707{
708 if (!cmount->is_mounted())
709 return;
710 cmount->get_client()->rewinddir(reinterpret_cast<dir_result_t*>(dirp));
711}
712
713extern "C" int64_t ceph_telldir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
714{
715 if (!cmount->is_mounted())
1e59de90 716 return -CEPHFS_ENOTCONN;
7c673cae
FG
717 return cmount->get_client()->telldir(reinterpret_cast<dir_result_t*>(dirp));
718}
719
720extern "C" void ceph_seekdir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, int64_t offset)
721{
722 if (!cmount->is_mounted())
723 return;
724 cmount->get_client()->seekdir(reinterpret_cast<dir_result_t*>(dirp), offset);
725}
726
f67539c2
TL
727extern "C" int ceph_may_delete(struct ceph_mount_info *cmount, const char *path)
728{
729 if (!cmount->is_mounted())
1e59de90 730 return -CEPHFS_ENOTCONN;
f67539c2
TL
731 return cmount->get_client()->may_delete(path, cmount->default_perms);
732}
733
7c673cae
FG
734extern "C" int ceph_link (struct ceph_mount_info *cmount, const char *existing,
735 const char *newname)
736{
737 if (!cmount->is_mounted())
1e59de90 738 return -CEPHFS_ENOTCONN;
7c673cae
FG
739 return cmount->get_client()->link(existing, newname, cmount->default_perms);
740}
741
742extern "C" int ceph_unlink(struct ceph_mount_info *cmount, const char *path)
743{
744 if (!cmount->is_mounted())
1e59de90 745 return -CEPHFS_ENOTCONN;
7c673cae
FG
746 return cmount->get_client()->unlink(path, cmount->default_perms);
747}
748
b3b6e05e
TL
749extern "C" int ceph_unlinkat(struct ceph_mount_info *cmount, int dirfd, const char *relpath, int flags)
750{
751 if (!cmount->is_mounted())
1e59de90 752 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
753 return cmount->get_client()->unlinkat(dirfd, relpath, flags, cmount->default_perms);
754}
755
7c673cae
FG
756extern "C" int ceph_rename(struct ceph_mount_info *cmount, const char *from,
757 const char *to)
758{
759 if (!cmount->is_mounted())
1e59de90 760 return -CEPHFS_ENOTCONN;
7c673cae
FG
761 return cmount->get_client()->rename(from, to, cmount->default_perms);
762}
763
764// dirs
765extern "C" int ceph_mkdir(struct ceph_mount_info *cmount, const char *path, mode_t mode)
766{
767 if (!cmount->is_mounted())
1e59de90 768 return -CEPHFS_ENOTCONN;
7c673cae
FG
769 return cmount->get_client()->mkdir(path, mode, cmount->default_perms);
770}
771
b3b6e05e
TL
772extern "C" int ceph_mkdirat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
773 mode_t mode)
774{
775 if (!cmount->is_mounted())
1e59de90 776 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
777 return cmount->get_client()->mkdirat(dirfd, relpath, mode, cmount->default_perms);
778}
779
f67539c2
TL
780extern "C" int ceph_mksnap(struct ceph_mount_info *cmount, const char *path, const char *name,
781 mode_t mode, struct snap_metadata *snap_metadata, size_t nr_snap_metadata)
782{
783 if (!cmount->is_mounted())
1e59de90 784 return -CEPHFS_ENOTCONN;
f67539c2
TL
785 size_t i = 0;
786 std::map<std::string, std::string> metadata;
787 while (i < nr_snap_metadata) {
788 metadata.emplace(snap_metadata[i].key, snap_metadata[i].value);
789 ++i;
790 }
791 return cmount->get_client()->mksnap(path, name, cmount->default_perms, mode, metadata);
792}
793
794extern "C" int ceph_rmsnap(struct ceph_mount_info *cmount, const char *path, const char *name)
795{
796 if (!cmount->is_mounted())
1e59de90 797 return -CEPHFS_ENOTCONN;
f67539c2
TL
798 return cmount->get_client()->rmsnap(path, name, cmount->default_perms, true);
799}
800
7c673cae
FG
801extern "C" int ceph_mkdirs(struct ceph_mount_info *cmount, const char *path, mode_t mode)
802{
803 if (!cmount->is_mounted())
1e59de90 804 return -CEPHFS_ENOTCONN;
7c673cae
FG
805 return cmount->get_client()->mkdirs(path, mode, cmount->default_perms);
806}
807
808extern "C" int ceph_rmdir(struct ceph_mount_info *cmount, const char *path)
809{
810 if (!cmount->is_mounted())
1e59de90 811 return -CEPHFS_ENOTCONN;
7c673cae
FG
812 return cmount->get_client()->rmdir(path, cmount->default_perms);
813}
814
815// symlinks
816extern "C" int ceph_readlink(struct ceph_mount_info *cmount, const char *path,
817 char *buf, int64_t size)
818{
819 if (!cmount->is_mounted())
1e59de90 820 return -CEPHFS_ENOTCONN;
7c673cae
FG
821 return cmount->get_client()->readlink(path, buf, size, cmount->default_perms);
822}
823
b3b6e05e
TL
824extern "C" int ceph_readlinkat(struct ceph_mount_info *cmount, int dirfd,
825 const char *relpath, char *buf, int64_t size)
826{
827 if (!cmount->is_mounted())
1e59de90 828 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
829 return cmount->get_client()->readlinkat(dirfd, relpath, buf, size, cmount->default_perms);
830}
831
7c673cae
FG
832extern "C" int ceph_symlink(struct ceph_mount_info *cmount, const char *existing,
833 const char *newname)
834{
835 if (!cmount->is_mounted())
1e59de90 836 return -CEPHFS_ENOTCONN;
7c673cae
FG
837 return cmount->get_client()->symlink(existing, newname, cmount->default_perms);
838}
839
b3b6e05e
TL
840extern "C" int ceph_symlinkat(struct ceph_mount_info *cmount, const char *existing, int dirfd,
841 const char *newname)
842{
843 if (!cmount->is_mounted())
1e59de90 844 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
845 return cmount->get_client()->symlinkat(existing, dirfd, newname, cmount->default_perms);
846}
847
7c673cae
FG
848extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx,
849 unsigned int want, unsigned int flags)
850{
851 if (!cmount->is_mounted())
1e59de90 852 return -CEPHFS_ENOTCONN;
7c673cae 853 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 854 return -CEPHFS_EINVAL;
7c673cae
FG
855 return cmount->get_client()->fstatx(fd, stx, cmount->default_perms,
856 want, flags);
857}
858
b3b6e05e
TL
859extern "C" int ceph_statxat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
860 struct ceph_statx *stx, unsigned int want, unsigned int flags)
861{
862 if (!cmount->is_mounted())
1e59de90 863 return -CEPHFS_ENOTCONN;
b3b6e05e 864 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 865 return -CEPHFS_EINVAL;
b3b6e05e
TL
866 return cmount->get_client()->statxat(dirfd, relpath, stx, cmount->default_perms,
867 want, flags);
868}
869
7c673cae
FG
870extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path,
871 struct ceph_statx *stx, unsigned int want, unsigned int flags)
872{
873 if (!cmount->is_mounted())
1e59de90 874 return -CEPHFS_ENOTCONN;
7c673cae 875 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 876 return -CEPHFS_EINVAL;
7c673cae
FG
877 return cmount->get_client()->statx(path, stx, cmount->default_perms,
878 want, flags);
879}
880
881extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd,
882 struct ceph_statx *stx, int mask)
883{
884 if (!cmount->is_mounted())
1e59de90 885 return -CEPHFS_ENOTCONN;
7c673cae
FG
886 return cmount->get_client()->fsetattrx(fd, stx, mask, cmount->default_perms);
887}
888
889extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath,
890 struct ceph_statx *stx, int mask, int flags)
891{
892 if (!cmount->is_mounted())
1e59de90 893 return -CEPHFS_ENOTCONN;
7c673cae 894 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 895 return -CEPHFS_EINVAL;
7c673cae
FG
896 return cmount->get_client()->setattrx(relpath, stx, mask,
897 cmount->default_perms, flags);
898}
899
900// *xattr() calls supporting samba/vfs
901extern "C" int ceph_getxattr(struct ceph_mount_info *cmount, const char *path, const char *name, void *value, size_t size)
902{
903 if (!cmount->is_mounted())
1e59de90 904 return -CEPHFS_ENOTCONN;
7c673cae
FG
905
906 return cmount->get_client()->getxattr(path, name, value, size, cmount->default_perms);
907}
908
909extern "C" int ceph_lgetxattr(struct ceph_mount_info *cmount, const char *path, const char *name, void *value, size_t size)
910{
911 if (!cmount->is_mounted())
1e59de90 912 return -CEPHFS_ENOTCONN;
7c673cae
FG
913 return cmount->get_client()->lgetxattr(path, name, value, size, cmount->default_perms);
914}
915
916extern "C" int ceph_fgetxattr(struct ceph_mount_info *cmount, int fd, const char *name, void *value, size_t size)
917{
918 if (!cmount->is_mounted())
1e59de90 919 return -CEPHFS_ENOTCONN;
7c673cae
FG
920 return cmount->get_client()->fgetxattr(fd, name, value, size, cmount->default_perms);
921}
922
923
924extern "C" int ceph_listxattr(struct ceph_mount_info *cmount, const char *path, char *list, size_t size)
925{
926 if (!cmount->is_mounted())
1e59de90 927 return -CEPHFS_ENOTCONN;
7c673cae
FG
928 return cmount->get_client()->listxattr(path, list, size, cmount->default_perms);
929}
930
931extern "C" int ceph_llistxattr(struct ceph_mount_info *cmount, const char *path, char *list, size_t size)
932{
933 if (!cmount->is_mounted())
1e59de90 934 return -CEPHFS_ENOTCONN;
7c673cae
FG
935 return cmount->get_client()->llistxattr(path, list, size, cmount->default_perms);
936}
937
938extern "C" int ceph_flistxattr(struct ceph_mount_info *cmount, int fd, char *list, size_t size)
939{
940 if (!cmount->is_mounted())
1e59de90 941 return -CEPHFS_ENOTCONN;
7c673cae
FG
942 return cmount->get_client()->flistxattr(fd, list, size, cmount->default_perms);
943}
944
945extern "C" int ceph_removexattr(struct ceph_mount_info *cmount, const char *path, const char *name)
946{
947 if (!cmount->is_mounted())
1e59de90 948 return -CEPHFS_ENOTCONN;
7c673cae
FG
949 return cmount->get_client()->removexattr(path, name, cmount->default_perms);
950}
951
952extern "C" int ceph_lremovexattr(struct ceph_mount_info *cmount, const char *path, const char *name)
953{
954 if (!cmount->is_mounted())
1e59de90 955 return -CEPHFS_ENOTCONN;
7c673cae
FG
956 return cmount->get_client()->lremovexattr(path, name, cmount->default_perms);
957}
958
959extern "C" int ceph_fremovexattr(struct ceph_mount_info *cmount, int fd, const char *name)
960{
961 if (!cmount->is_mounted())
1e59de90 962 return -CEPHFS_ENOTCONN;
7c673cae
FG
963 return cmount->get_client()->fremovexattr(fd, name, cmount->default_perms);
964}
965
966extern "C" int ceph_setxattr(struct ceph_mount_info *cmount, const char *path, const char *name, const void *value, size_t size, int flags)
967{
968 if (!cmount->is_mounted())
1e59de90 969 return -CEPHFS_ENOTCONN;
7c673cae
FG
970 return cmount->get_client()->setxattr(path, name, value, size, flags, cmount->default_perms);
971}
972
973extern "C" int ceph_lsetxattr(struct ceph_mount_info *cmount, const char *path, const char *name, const void *value, size_t size, int flags)
974{
975 if (!cmount->is_mounted())
1e59de90 976 return -CEPHFS_ENOTCONN;
7c673cae
FG
977 return cmount->get_client()->lsetxattr(path, name, value, size, flags, cmount->default_perms);
978}
979
980extern "C" int ceph_fsetxattr(struct ceph_mount_info *cmount, int fd, const char *name, const void *value, size_t size, int flags)
981{
982 if (!cmount->is_mounted())
1e59de90 983 return -CEPHFS_ENOTCONN;
7c673cae
FG
984 return cmount->get_client()->fsetxattr(fd, name, value, size, flags, cmount->default_perms);
985}
986/* end xattr support */
987
11fdf7f2
TL
988extern "C" int ceph_stat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf)
989{
990 if (!cmount->is_mounted())
1e59de90 991 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
992 return cmount->get_client()->stat(path, stbuf, cmount->default_perms);
993}
994
995extern "C" int ceph_fstat(struct ceph_mount_info *cmount, int fd, struct stat *stbuf)
996{
997 if (!cmount->is_mounted())
1e59de90 998 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
999 return cmount->get_client()->fstat(fd, stbuf, cmount->default_perms);
1000}
1001
1002extern int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf)
1003{
1004 if (!cmount->is_mounted())
1e59de90 1005 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1006 return cmount->get_client()->lstat(path, stbuf, cmount->default_perms);
1007}
1008
7c673cae
FG
1009extern "C" int ceph_chmod(struct ceph_mount_info *cmount, const char *path, mode_t mode)
1010{
1011 if (!cmount->is_mounted())
1e59de90 1012 return -CEPHFS_ENOTCONN;
7c673cae
FG
1013 return cmount->get_client()->chmod(path, mode, cmount->default_perms);
1014}
f67539c2
TL
1015extern "C" int ceph_lchmod(struct ceph_mount_info *cmount, const char *path, mode_t mode)
1016{
1017 if (!cmount->is_mounted())
1e59de90 1018 return -CEPHFS_ENOTCONN;
f67539c2
TL
1019 return cmount->get_client()->lchmod(path, mode, cmount->default_perms);
1020}
7c673cae
FG
1021extern "C" int ceph_fchmod(struct ceph_mount_info *cmount, int fd, mode_t mode)
1022{
1023 if (!cmount->is_mounted())
1e59de90 1024 return -CEPHFS_ENOTCONN;
7c673cae
FG
1025 return cmount->get_client()->fchmod(fd, mode, cmount->default_perms);
1026}
b3b6e05e
TL
1027
1028extern "C" int ceph_chmodat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
1029 mode_t mode, int flags) {
1030 if (!cmount->is_mounted())
1e59de90 1031 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
1032 return cmount->get_client()->chmodat(dirfd, relpath, mode, flags, cmount->default_perms);
1033}
1034
7c673cae
FG
1035extern "C" int ceph_chown(struct ceph_mount_info *cmount, const char *path,
1036 int uid, int gid)
1037{
1038 if (!cmount->is_mounted())
1e59de90 1039 return -CEPHFS_ENOTCONN;
7c673cae
FG
1040 return cmount->get_client()->chown(path, uid, gid, cmount->default_perms);
1041}
1042extern "C" int ceph_fchown(struct ceph_mount_info *cmount, int fd,
1043 int uid, int gid)
1044{
1045 if (!cmount->is_mounted())
1e59de90 1046 return -CEPHFS_ENOTCONN;
7c673cae
FG
1047 return cmount->get_client()->fchown(fd, uid, gid, cmount->default_perms);
1048}
1049extern "C" int ceph_lchown(struct ceph_mount_info *cmount, const char *path,
1050 int uid, int gid)
1051{
1052 if (!cmount->is_mounted())
1e59de90 1053 return -CEPHFS_ENOTCONN;
7c673cae
FG
1054 return cmount->get_client()->lchown(path, uid, gid, cmount->default_perms);
1055}
1056
b3b6e05e
TL
1057extern "C" int ceph_chownat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
1058 uid_t uid, gid_t gid, int flags) {
1059 if (!cmount->is_mounted())
1e59de90 1060 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
1061 return cmount->get_client()->chownat(dirfd, relpath, uid, gid, flags, cmount->default_perms);
1062}
7c673cae
FG
1063
1064extern "C" int ceph_utime(struct ceph_mount_info *cmount, const char *path,
1065 struct utimbuf *buf)
1066{
1067 if (!cmount->is_mounted())
1e59de90 1068 return -CEPHFS_ENOTCONN;
7c673cae
FG
1069 return cmount->get_client()->utime(path, buf, cmount->default_perms);
1070}
1071
11fdf7f2
TL
1072extern "C" int ceph_futime(struct ceph_mount_info *cmount, int fd,
1073 struct utimbuf *buf)
1074{
1075 if (!cmount->is_mounted())
1e59de90 1076 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1077 return cmount->get_client()->futime(fd, buf, cmount->default_perms);
1078}
1079
1080extern "C" int ceph_utimes(struct ceph_mount_info *cmount, const char *path,
1081 struct timeval times[2])
1082{
1083 if (!cmount->is_mounted())
1e59de90 1084 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1085 return cmount->get_client()->utimes(path, times, cmount->default_perms);
1086}
1087
1088extern "C" int ceph_lutimes(struct ceph_mount_info *cmount, const char *path,
1089 struct timeval times[2])
1090{
1091 if (!cmount->is_mounted())
1e59de90 1092 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1093 return cmount->get_client()->lutimes(path, times, cmount->default_perms);
1094}
1095
1096extern "C" int ceph_futimes(struct ceph_mount_info *cmount, int fd,
1097 struct timeval times[2])
1098{
1099 if (!cmount->is_mounted())
1e59de90 1100 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1101 return cmount->get_client()->futimes(fd, times, cmount->default_perms);
1102}
1103
1104extern "C" int ceph_futimens(struct ceph_mount_info *cmount, int fd,
1105 struct timespec times[2])
1106{
1107 if (!cmount->is_mounted())
1e59de90 1108 return -CEPHFS_ENOTCONN;
11fdf7f2
TL
1109 return cmount->get_client()->futimens(fd, times, cmount->default_perms);
1110}
1111
b3b6e05e
TL
1112extern "C" int ceph_utimensat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
1113 struct timespec times[2], int flags) {
1114 if (!cmount->is_mounted())
1e59de90 1115 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
1116 return cmount->get_client()->utimensat(dirfd, relpath, times, flags, cmount->default_perms);
1117}
1118
7c673cae
FG
1119extern "C" int ceph_flock(struct ceph_mount_info *cmount, int fd, int operation,
1120 uint64_t owner)
1121{
1122 if (!cmount->is_mounted())
1e59de90 1123 return -CEPHFS_ENOTCONN;
7c673cae
FG
1124 return cmount->get_client()->flock(fd, operation, owner);
1125}
1126
1127extern "C" int ceph_truncate(struct ceph_mount_info *cmount, const char *path,
1128 int64_t size)
1129{
1130 if (!cmount->is_mounted())
1e59de90 1131 return -CEPHFS_ENOTCONN;
7c673cae
FG
1132 return cmount->get_client()->truncate(path, size, cmount->default_perms);
1133}
1134
1135// file ops
1136extern "C" int ceph_mknod(struct ceph_mount_info *cmount, const char *path,
1137 mode_t mode, dev_t rdev)
1138{
1139 if (!cmount->is_mounted())
1e59de90 1140 return -CEPHFS_ENOTCONN;
7c673cae
FG
1141 return cmount->get_client()->mknod(path, mode, cmount->default_perms, rdev);
1142}
1143
1144extern "C" int ceph_open(struct ceph_mount_info *cmount, const char *path,
1145 int flags, mode_t mode)
1146{
1147 if (!cmount->is_mounted())
1e59de90 1148 return -CEPHFS_ENOTCONN;
7c673cae
FG
1149 return cmount->get_client()->open(path, flags, cmount->default_perms, mode);
1150}
1151
b3b6e05e
TL
1152extern "C" int ceph_openat(struct ceph_mount_info *cmount, int dirfd, const char *relpath,
1153 int flags, mode_t mode)
1154{
1155 if (!cmount->is_mounted())
1e59de90 1156 return -CEPHFS_ENOTCONN;
b3b6e05e
TL
1157 return cmount->get_client()->openat(dirfd, relpath, flags, cmount->default_perms, mode);
1158}
1159
7c673cae
FG
1160extern "C" int ceph_open_layout(struct ceph_mount_info *cmount, const char *path, int flags,
1161 mode_t mode, int stripe_unit, int stripe_count, int object_size, const char *data_pool)
1162{
1163 if (!cmount->is_mounted())
1e59de90 1164 return -CEPHFS_ENOTCONN;
7c673cae
FG
1165 return cmount->get_client()->open(path, flags, cmount->default_perms, mode,
1166 stripe_unit, stripe_count,
1167 object_size, data_pool);
1168}
1169
1170extern "C" int ceph_close(struct ceph_mount_info *cmount, int fd)
1171{
1172 if (!cmount->is_mounted())
1e59de90 1173 return -CEPHFS_ENOTCONN;
7c673cae
FG
1174 return cmount->get_client()->close(fd);
1175}
1176
1177extern "C" int64_t ceph_lseek(struct ceph_mount_info *cmount, int fd,
1178 int64_t offset, int whence)
1179{
1180 if (!cmount->is_mounted())
1e59de90 1181 return -CEPHFS_ENOTCONN;
7c673cae
FG
1182 return cmount->get_client()->lseek(fd, offset, whence);
1183}
1184
1185extern "C" int ceph_read(struct ceph_mount_info *cmount, int fd, char *buf,
1186 int64_t size, int64_t offset)
1187{
1188 if (!cmount->is_mounted())
1e59de90 1189 return -CEPHFS_ENOTCONN;
7c673cae
FG
1190 return cmount->get_client()->read(fd, buf, size, offset);
1191}
1192
1193extern "C" int ceph_preadv(struct ceph_mount_info *cmount, int fd,
1194 const struct iovec *iov, int iovcnt, int64_t offset)
1195{
1196 if (!cmount->is_mounted())
1e59de90 1197 return -CEPHFS_ENOTCONN;
7c673cae
FG
1198 return cmount->get_client()->preadv(fd, iov, iovcnt, offset);
1199}
1200
1201extern "C" int ceph_write(struct ceph_mount_info *cmount, int fd, const char *buf,
1202 int64_t size, int64_t offset)
1203{
1204 if (!cmount->is_mounted())
1e59de90 1205 return -CEPHFS_ENOTCONN;
7c673cae
FG
1206 return cmount->get_client()->write(fd, buf, size, offset);
1207}
1208
1209extern "C" int ceph_pwritev(struct ceph_mount_info *cmount, int fd,
1210 const struct iovec *iov, int iovcnt, int64_t offset)
1211{
1212 if (!cmount->is_mounted())
1e59de90 1213 return -CEPHFS_ENOTCONN;
7c673cae
FG
1214 return cmount->get_client()->pwritev(fd, iov, iovcnt, offset);
1215}
1216
1217extern "C" int ceph_ftruncate(struct ceph_mount_info *cmount, int fd, int64_t size)
1218{
1219 if (!cmount->is_mounted())
1e59de90 1220 return -CEPHFS_ENOTCONN;
7c673cae
FG
1221 return cmount->get_client()->ftruncate(fd, size, cmount->default_perms);
1222}
1223
1224extern "C" int ceph_fsync(struct ceph_mount_info *cmount, int fd, int syncdataonly)
1225{
1226 if (!cmount->is_mounted())
1e59de90 1227 return -CEPHFS_ENOTCONN;
7c673cae
FG
1228 return cmount->get_client()->fsync(fd, syncdataonly);
1229}
1230
1231extern "C" int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode,
1232 int64_t offset, int64_t length)
1233{
1234 if (!cmount->is_mounted())
1e59de90 1235 return -CEPHFS_ENOTCONN;
7c673cae
FG
1236 return cmount->get_client()->fallocate(fd, mode, offset, length);
1237}
1238
11fdf7f2
TL
1239extern "C" int ceph_lazyio(class ceph_mount_info *cmount,
1240 int fd, int enable)
1241{
1242 return (cmount->get_client()->lazyio(fd, enable));
1243}
1244
92f5a8d4
TL
1245extern "C" int ceph_lazyio_propagate(class ceph_mount_info *cmount,
1246 int fd, int64_t offset, size_t count)
1247{
1248 if (!cmount->is_mounted())
1e59de90 1249 return -CEPHFS_ENOTCONN;
92f5a8d4
TL
1250 return (cmount->get_client()->lazyio_propagate(fd, offset, count));
1251}
1252
1253extern "C" int ceph_lazyio_synchronize(class ceph_mount_info *cmount,
1254 int fd, int64_t offset, size_t count)
1255{
1256 if (!cmount->is_mounted())
1e59de90 1257 return -CEPHFS_ENOTCONN;
92f5a8d4
TL
1258 return (cmount->get_client()->lazyio_synchronize(fd, offset, count));
1259}
1260
1261
7c673cae
FG
1262extern "C" int ceph_sync_fs(struct ceph_mount_info *cmount)
1263{
1264 if (!cmount->is_mounted())
1e59de90 1265 return -CEPHFS_ENOTCONN;
7c673cae
FG
1266 return cmount->get_client()->sync_fs();
1267}
1268
7c673cae
FG
1269extern "C" int ceph_get_file_stripe_unit(struct ceph_mount_info *cmount, int fh)
1270{
1271 file_layout_t l;
1272 int r;
1273
1274 if (!cmount->is_mounted())
1e59de90 1275 return -CEPHFS_ENOTCONN;
7c673cae
FG
1276 r = cmount->get_client()->fdescribe_layout(fh, &l);
1277 if (r < 0)
1278 return r;
1279 return l.stripe_unit;
1280}
1281
1282extern "C" int ceph_get_path_stripe_unit(struct ceph_mount_info *cmount, const char *path)
1283{
1284 file_layout_t l;
1285 int r;
1286
1287 if (!cmount->is_mounted())
1e59de90 1288 return -CEPHFS_ENOTCONN;
7c673cae
FG
1289 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1290 if (r < 0)
1291 return r;
1292 return l.stripe_unit;
1293}
1294
1295extern "C" int ceph_get_file_stripe_count(struct ceph_mount_info *cmount, int fh)
1296{
1297 file_layout_t l;
1298 int r;
1299
1300 if (!cmount->is_mounted())
1e59de90 1301 return -CEPHFS_ENOTCONN;
7c673cae
FG
1302 r = cmount->get_client()->fdescribe_layout(fh, &l);
1303 if (r < 0)
1304 return r;
1305 return l.stripe_count;
1306}
1307
1308extern "C" int ceph_get_path_stripe_count(struct ceph_mount_info *cmount, const char *path)
1309{
1310 file_layout_t l;
1311 int r;
1312
1313 if (!cmount->is_mounted())
1e59de90 1314 return -CEPHFS_ENOTCONN;
7c673cae
FG
1315 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1316 if (r < 0)
1317 return r;
1318 return l.stripe_count;
1319}
1320
1321extern "C" int ceph_get_file_object_size(struct ceph_mount_info *cmount, int fh)
1322{
1323 file_layout_t l;
1324 int r;
1325
1326 if (!cmount->is_mounted())
1e59de90 1327 return -CEPHFS_ENOTCONN;
7c673cae
FG
1328 r = cmount->get_client()->fdescribe_layout(fh, &l);
1329 if (r < 0)
1330 return r;
1331 return l.object_size;
1332}
1333
1334extern "C" int ceph_get_path_object_size(struct ceph_mount_info *cmount, const char *path)
1335{
1336 file_layout_t l;
1337 int r;
1338
1339 if (!cmount->is_mounted())
1e59de90 1340 return -CEPHFS_ENOTCONN;
7c673cae
FG
1341 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1342 if (r < 0)
1343 return r;
1344 return l.object_size;
1345}
1346
1347extern "C" int ceph_get_file_pool(struct ceph_mount_info *cmount, int fh)
1348{
1349 file_layout_t l;
1350 int r;
1351
1352 if (!cmount->is_mounted())
1e59de90 1353 return -CEPHFS_ENOTCONN;
7c673cae
FG
1354 r = cmount->get_client()->fdescribe_layout(fh, &l);
1355 if (r < 0)
1356 return r;
1357 return l.pool_id;
1358}
1359
1360extern "C" int ceph_get_path_pool(struct ceph_mount_info *cmount, const char *path)
1361{
1362 file_layout_t l;
1363 int r;
1364
1365 if (!cmount->is_mounted())
1e59de90 1366 return -CEPHFS_ENOTCONN;
7c673cae
FG
1367 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1368 if (r < 0)
1369 return r;
1370 return l.pool_id;
1371}
1372
1373extern "C" int ceph_get_file_pool_name(struct ceph_mount_info *cmount, int fh, char *buf, size_t len)
1374{
1375 file_layout_t l;
1376 int r;
1377
1378 if (!cmount->is_mounted())
1e59de90 1379 return -CEPHFS_ENOTCONN;
7c673cae
FG
1380 r = cmount->get_client()->fdescribe_layout(fh, &l);
1381 if (r < 0)
1382 return r;
1383 string name = cmount->get_client()->get_pool_name(l.pool_id);
1384 if (len == 0)
1385 return name.length();
1386 if (name.length() > len)
1e59de90 1387 return -CEPHFS_ERANGE;
7c673cae
FG
1388 strncpy(buf, name.c_str(), len);
1389 return name.length();
1390}
1391
1392extern "C" int ceph_get_pool_name(struct ceph_mount_info *cmount, int pool, char *buf, size_t len)
1393{
1394 if (!cmount->is_mounted())
1e59de90 1395 return -CEPHFS_ENOTCONN;
7c673cae
FG
1396 string name = cmount->get_client()->get_pool_name(pool);
1397 if (len == 0)
1398 return name.length();
1399 if (name.length() > len)
1e59de90 1400 return -CEPHFS_ERANGE;
7c673cae
FG
1401 strncpy(buf, name.c_str(), len);
1402 return name.length();
1403}
1404
1405extern "C" int ceph_get_path_pool_name(struct ceph_mount_info *cmount, const char *path, char *buf, size_t len)
1406{
1407 file_layout_t l;
1408 int r;
1409
1410 if (!cmount->is_mounted())
1e59de90 1411 return -CEPHFS_ENOTCONN;
7c673cae
FG
1412 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1413 if (r < 0)
1414 return r;
1415 string name = cmount->get_client()->get_pool_name(l.pool_id);
1416 if (len == 0)
1417 return name.length();
1418 if (name.length() > len)
1e59de90 1419 return -CEPHFS_ERANGE;
7c673cae
FG
1420 strncpy(buf, name.c_str(), len);
1421 return name.length();
1422}
1423
d2e6a577
FG
1424extern "C" int ceph_get_default_data_pool_name(struct ceph_mount_info *cmount, char *buf, size_t len)
1425{
1426 if (!cmount->is_mounted())
1e59de90 1427 return -CEPHFS_ENOTCONN;
d2e6a577
FG
1428 int64_t pool_id = cmount->get_client()->get_default_pool_id();
1429
1430 string name = cmount->get_client()->get_pool_name(pool_id);
1431 if (len == 0)
1432 return name.length();
1433 if (name.length() > len)
1e59de90 1434 return -CEPHFS_ERANGE;
d2e6a577
FG
1435 strncpy(buf, name.c_str(), len);
1436 return name.length();
1437}
1438
7c673cae
FG
1439extern "C" int ceph_get_file_layout(struct ceph_mount_info *cmount, int fh, int *stripe_unit, int *stripe_count, int *object_size, int *pg_pool)
1440{
1441 file_layout_t l;
1442 int r;
1443
1444 if (!cmount->is_mounted())
1e59de90 1445 return -CEPHFS_ENOTCONN;
7c673cae
FG
1446 r = cmount->get_client()->fdescribe_layout(fh, &l);
1447 if (r < 0)
1448 return r;
1449 if (stripe_unit)
1450 *stripe_unit = l.stripe_unit;
1451 if (stripe_count)
1452 *stripe_count = l.stripe_count;
1453 if (object_size)
1454 *object_size = l.object_size;
1455 if (pg_pool)
1456 *pg_pool = l.pool_id;
1457 return 0;
1458}
1459
1460extern "C" int ceph_get_path_layout(struct ceph_mount_info *cmount, const char *path, int *stripe_unit, int *stripe_count, int *object_size, int *pg_pool)
1461{
1462 file_layout_t l;
1463 int r;
1464
1465 if (!cmount->is_mounted())
1e59de90 1466 return -CEPHFS_ENOTCONN;
7c673cae
FG
1467 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1468 if (r < 0)
1469 return r;
1470 if (stripe_unit)
1471 *stripe_unit = l.stripe_unit;
1472 if (stripe_count)
1473 *stripe_count = l.stripe_count;
1474 if (object_size)
1475 *object_size = l.object_size;
1476 if (pg_pool)
1477 *pg_pool = l.pool_id;
1478 return 0;
1479}
1480
1481extern "C" int ceph_get_file_replication(struct ceph_mount_info *cmount, int fh)
1482{
1483 file_layout_t l;
1484 int r;
1485
1486 if (!cmount->is_mounted())
1e59de90 1487 return -CEPHFS_ENOTCONN;
7c673cae
FG
1488 r = cmount->get_client()->fdescribe_layout(fh, &l);
1489 if (r < 0)
1490 return r;
1491 int rep = cmount->get_client()->get_pool_replication(l.pool_id);
1492 return rep;
1493}
1494
1495extern "C" int ceph_get_path_replication(struct ceph_mount_info *cmount, const char *path)
1496{
1497 file_layout_t l;
1498 int r;
1499
1500 if (!cmount->is_mounted())
1e59de90 1501 return -CEPHFS_ENOTCONN;
7c673cae
FG
1502 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1503 if (r < 0)
1504 return r;
1505 int rep = cmount->get_client()->get_pool_replication(l.pool_id);
1506 return rep;
1507}
1508
1509extern "C" int ceph_set_default_file_stripe_unit(struct ceph_mount_info *cmount,
1510 int stripe)
1511{
1512 // this option no longer exists
1e59de90 1513 return -CEPHFS_EOPNOTSUPP;
7c673cae
FG
1514}
1515
1516extern "C" int ceph_set_default_file_stripe_count(struct ceph_mount_info *cmount,
1517 int count)
1518{
1519 // this option no longer exists
1e59de90 1520 return -CEPHFS_EOPNOTSUPP;
7c673cae
FG
1521}
1522
1523extern "C" int ceph_set_default_object_size(struct ceph_mount_info *cmount, int size)
1524{
1525 // this option no longer exists
1e59de90 1526 return -CEPHFS_EOPNOTSUPP;
7c673cae
FG
1527}
1528
1529extern "C" int ceph_set_default_file_replication(struct ceph_mount_info *cmount,
1530 int replication)
1531{
1532 // this option no longer exists
1e59de90 1533 return -CEPHFS_EOPNOTSUPP;
7c673cae
FG
1534}
1535
1536extern "C" int ceph_set_default_preferred_pg(struct ceph_mount_info *cmount, int osd)
1537{
1538 // this option no longer exists
1e59de90 1539 return -CEPHFS_EOPNOTSUPP;
7c673cae
FG
1540}
1541
1542extern "C" int ceph_get_file_extent_osds(struct ceph_mount_info *cmount, int fh,
1543 int64_t offset, int64_t *length, int *osds, int nosds)
1544{
1545 if (nosds < 0)
1e59de90 1546 return -CEPHFS_EINVAL;
7c673cae
FG
1547
1548 if (!cmount->is_mounted())
1e59de90 1549 return -CEPHFS_ENOTCONN;
7c673cae
FG
1550
1551 vector<int> vosds;
1552 int ret = cmount->get_client()->get_file_extent_osds(fh, offset, length, vosds);
1553 if (ret < 0)
1554 return ret;
1555
1556 if (!nosds)
1557 return vosds.size();
1558
1559 if ((int)vosds.size() > nosds)
1e59de90 1560 return -CEPHFS_ERANGE;
7c673cae
FG
1561
1562 for (int i = 0; i < (int)vosds.size(); i++)
1563 osds[i] = vosds[i];
1564
1565 return vosds.size();
1566}
1567
1568extern "C" int ceph_get_osd_crush_location(struct ceph_mount_info *cmount,
1569 int osd, char *path, size_t len)
1570{
1571 if (!cmount->is_mounted())
1e59de90 1572 return -CEPHFS_ENOTCONN;
7c673cae
FG
1573
1574 if (!path && len)
1e59de90 1575 return -CEPHFS_EINVAL;
7c673cae
FG
1576
1577 vector<pair<string, string> > loc;
1578 int ret = cmount->get_client()->get_osd_crush_location(osd, loc);
1579 if (ret)
1580 return ret;
1581
1582 size_t needed = 0;
1583 size_t cur = 0;
1584 vector<pair<string, string> >::iterator it;
1585 for (it = loc.begin(); it != loc.end(); ++it) {
1586 string& type = it->first;
1587 string& name = it->second;
1588 needed += type.size() + name.size() + 2;
1589 if (needed <= len) {
1590 if (path)
1591 strcpy(path + cur, type.c_str());
1592 cur += type.size() + 1;
1593 if (path)
1594 strcpy(path + cur, name.c_str());
1595 cur += name.size() + 1;
1596 }
1597 }
1598
1599 if (len == 0)
1600 return needed;
1601
1602 if (needed > len)
1e59de90 1603 return -CEPHFS_ERANGE;
7c673cae
FG
1604
1605 return needed;
1606}
1607
1608extern "C" int ceph_get_osd_addr(struct ceph_mount_info *cmount, int osd,
1609 struct sockaddr_storage *addr)
1610{
1611 if (!cmount->is_mounted())
1e59de90 1612 return -CEPHFS_ENOTCONN;
7c673cae
FG
1613
1614 if (!addr)
1e59de90 1615 return -CEPHFS_EINVAL;
7c673cae
FG
1616
1617 entity_addr_t address;
1618 int ret = cmount->get_client()->get_osd_addr(osd, address);
1619 if (ret < 0)
1620 return ret;
1621
1622 *addr = address.get_sockaddr_storage();
1623
1624 return 0;
1625}
1626
1627extern "C" int ceph_get_file_stripe_address(struct ceph_mount_info *cmount, int fh,
1628 int64_t offset, struct sockaddr_storage *addr, int naddr)
1629{
1630 vector<entity_addr_t> address;
1631 unsigned i;
1632 int r;
1633
1634 if (naddr < 0)
1e59de90 1635 return -CEPHFS_EINVAL;
7c673cae
FG
1636
1637 if (!cmount->is_mounted())
1e59de90 1638 return -CEPHFS_ENOTCONN;
7c673cae
FG
1639
1640 r = cmount->get_client()->get_file_stripe_address(fh, offset, address);
1641 if (r < 0)
1642 return r;
1643
1644 for (i = 0; i < (unsigned)naddr && i < address.size(); i++)
1645 addr[i] = address[i].get_sockaddr_storage();
1646
1647 /* naddr == 0: drop through and return actual size */
1648 if (naddr && (address.size() > (unsigned)naddr))
1e59de90 1649 return -CEPHFS_ERANGE;
7c673cae
FG
1650
1651 return address.size();
1652}
1653
1654extern "C" int ceph_localize_reads(struct ceph_mount_info *cmount, int val)
1655{
1656 if (!cmount->is_mounted())
1e59de90 1657 return -CEPHFS_ENOTCONN;
7c673cae
FG
1658 if (!val)
1659 cmount->get_client()->clear_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS);
1660 else
1661 cmount->get_client()->set_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS);
1662 return 0;
1663}
1664
1665extern "C" CephContext *ceph_get_mount_context(struct ceph_mount_info *cmount)
1666{
1667 return cmount->get_ceph_context();
1668}
1669
1670extern "C" int ceph_debug_get_fd_caps(struct ceph_mount_info *cmount, int fd)
1671{
1672 if (!cmount->is_mounted())
1e59de90 1673 return -CEPHFS_ENOTCONN;
7c673cae
FG
1674 return cmount->get_client()->get_caps_issued(fd);
1675}
1676
1677extern "C" int ceph_debug_get_file_caps(struct ceph_mount_info *cmount, const char *path)
1678{
1679 if (!cmount->is_mounted())
1e59de90 1680 return -CEPHFS_ENOTCONN;
7c673cae
FG
1681 return cmount->get_client()->get_caps_issued(path, cmount->default_perms);
1682}
1683
1684extern "C" int ceph_get_stripe_unit_granularity(struct ceph_mount_info *cmount)
1685{
1686 if (!cmount->is_mounted())
1e59de90 1687 return -CEPHFS_ENOTCONN;
7c673cae
FG
1688 return CEPH_MIN_STRIPE_UNIT;
1689}
1690
1691extern "C" int ceph_get_pool_id(struct ceph_mount_info *cmount, const char *pool_name)
1692{
1693 if (!cmount->is_mounted())
1e59de90 1694 return -CEPHFS_ENOTCONN;
7c673cae
FG
1695
1696 if (!pool_name || !pool_name[0])
1e59de90 1697 return -CEPHFS_EINVAL;
7c673cae
FG
1698
1699 /* negative range reserved for errors */
1700 int64_t pool_id = cmount->get_client()->get_pool_id(pool_name);
1701 if (pool_id > 0x7fffffff)
1e59de90 1702 return -CEPHFS_ERANGE;
7c673cae
FG
1703
1704 /* get_pool_id error codes fit in int */
1705 return (int)pool_id;
1706}
1707
1708extern "C" int ceph_get_pool_replication(struct ceph_mount_info *cmount,
1709 int pool_id)
1710{
1711 if (!cmount->is_mounted())
1e59de90 1712 return -CEPHFS_ENOTCONN;
7c673cae
FG
1713 return cmount->get_client()->get_pool_replication(pool_id);
1714}
1715/* Low-level exports */
1716
1717extern "C" int ceph_ll_lookup_root(struct ceph_mount_info *cmount,
1718 Inode **parent)
1719{
1720 *parent = cmount->get_client()->get_root();
1721 if (*parent)
1722 return 0;
1e59de90 1723 return -CEPHFS_EFAULT;
7c673cae
FG
1724}
1725
1726extern "C" struct Inode *ceph_ll_get_inode(class ceph_mount_info *cmount,
1727 vinodeno_t vino)
1728{
1729 return (cmount->get_client())->ll_get_inode(vino);
1730}
1731
1732
f67539c2
TL
1733extern "C" int ceph_ll_lookup_vino(
1734 struct ceph_mount_info *cmount,
1735 vinodeno_t vino,
1736 Inode **inode)
1737{
1738 return (cmount->get_client())->ll_lookup_vino(vino, cmount->default_perms, inode);
1739}
1740
7c673cae
FG
1741/**
1742 * Populates the client cache with the requested inode, and its
1743 * parent dentry.
1744 */
1745extern "C" int ceph_ll_lookup_inode(
1746 struct ceph_mount_info *cmount,
1747 struct inodeno_t ino,
1748 Inode **inode)
1749{
1adf2230 1750 return (cmount->get_client())->ll_lookup_inode(ino, cmount->default_perms, inode);
7c673cae
FG
1751}
1752
1753extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount,
1754 Inode *parent, const char *name, Inode **out,
1755 struct ceph_statx *stx, unsigned want,
1756 unsigned flags, const UserPerm *perms)
1757{
1758 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1759 return -CEPHFS_EINVAL;
7c673cae
FG
1760 return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want,
1761 flags, *perms);
1762}
1763
1764extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
1765{
1766 return (cmount->get_client()->ll_put(in));
1767}
1768
1769extern "C" int ceph_ll_forget(class ceph_mount_info *cmount, Inode *in,
1770 int count)
1771{
1772 return (cmount->get_client()->ll_forget(in, count));
1773}
1774
1775extern "C" int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
1776 struct ceph_statx *stx, unsigned int want, unsigned int flags,
1777 const UserPerm *perms)
1778{
1779 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1780 return -CEPHFS_EINVAL;
7c673cae
FG
1781 return(cmount->get_client()->ll_walk(name, i, stx, want, flags, *perms));
1782}
1783
1784extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount,
1785 Inode *in, struct ceph_statx *stx,
1786 unsigned int want, unsigned int flags,
1787 const UserPerm *perms)
1788{
1789 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1790 return -CEPHFS_EINVAL;
7c673cae
FG
1791 return (cmount->get_client()->ll_getattrx(in, stx, want, flags, *perms));
1792}
1793
1794extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount,
1795 Inode *in, struct ceph_statx *stx,
1796 int mask, const UserPerm *perms)
1797{
1798 return (cmount->get_client()->ll_setattrx(in, stx, mask, *perms));
1799}
1800
1801extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in,
1802 int flags, Fh **fh, const UserPerm *perms)
1803{
1804 return (cmount->get_client()->ll_open(in, flags, fh, *perms));
1805}
1806
1807extern "C" int ceph_ll_read(class ceph_mount_info *cmount, Fh* filehandle,
1808 int64_t off, uint64_t len, char* buf)
1809{
1810 bufferlist bl;
1811 int r = 0;
1812
1813 r = cmount->get_client()->ll_read(filehandle, off, len, &bl);
1814 if (r >= 0)
1815 {
9f95a23c 1816 bl.begin().copy(bl.length(), buf);
7c673cae
FG
1817 r = bl.length();
1818 }
1819 return r;
1820}
1821
1822extern "C" int ceph_ll_read_block(class ceph_mount_info *cmount,
1823 Inode *in, uint64_t blockid,
1824 char* buf, uint64_t offset,
1825 uint64_t length,
1826 struct ceph_file_layout* layout)
1827{
1828 file_layout_t l;
1829 int r = (cmount->get_client()->ll_read_block(in, blockid, buf, offset,
1830 length, &l));
1831 l.to_legacy(layout);
1832 return r;
1833}
1834
1835extern "C" int ceph_ll_write_block(class ceph_mount_info *cmount,
1836 Inode *in, uint64_t blockid,
1837 char *buf, uint64_t offset,
1838 uint64_t length,
1839 struct ceph_file_layout *layout,
1840 uint64_t snapseq, uint32_t sync)
1841{
1842 file_layout_t l;
1843 int r = (cmount->get_client()->ll_write_block(in, blockid, buf, offset,
1844 length, &l, snapseq, sync));
1845 l.to_legacy(layout);
1846 return r;
1847}
1848
1849extern "C" int ceph_ll_commit_blocks(class ceph_mount_info *cmount,
1850 Inode *in, uint64_t offset,
1851 uint64_t range)
1852{
1853 return (cmount->get_client()->ll_commit_blocks(in, offset, range));
1854}
1855
1856extern "C" int ceph_ll_fsync(class ceph_mount_info *cmount,
1857 Fh *fh, int syncdataonly)
1858{
1859 return (cmount->get_client()->ll_fsync(fh, syncdataonly));
1860}
1861
28e407b8
AA
1862extern "C" int ceph_ll_sync_inode(class ceph_mount_info *cmount,
1863 Inode *in, int syncdataonly)
1864{
1865 return (cmount->get_client()->ll_sync_inode(in, syncdataonly));
1866}
1867
11fdf7f2
TL
1868extern "C" int ceph_ll_fallocate(class ceph_mount_info *cmount, Fh *fh,
1869 int mode, int64_t offset, int64_t length)
1870{
1871 return cmount->get_client()->ll_fallocate(fh, mode, offset, length);
1872}
1873
7c673cae
FG
1874extern "C" off_t ceph_ll_lseek(class ceph_mount_info *cmount,
1875 Fh *fh, off_t offset, int whence)
1876{
1877 return (cmount->get_client()->ll_lseek(fh, offset, whence));
1878}
1879
1880extern "C" int ceph_ll_write(class ceph_mount_info *cmount,
1881 Fh *fh, int64_t off, uint64_t len,
1882 const char *data)
1883{
1884 return (cmount->get_client()->ll_write(fh, off, len, data));
1885}
1886
1887extern "C" int64_t ceph_ll_readv(class ceph_mount_info *cmount,
1888 struct Fh *fh, const struct iovec *iov,
1889 int iovcnt, int64_t off)
1890{
11fdf7f2 1891 return (cmount->get_client()->ll_readv(fh, iov, iovcnt, off));
7c673cae
FG
1892}
1893
1894extern "C" int64_t ceph_ll_writev(class ceph_mount_info *cmount,
1895 struct Fh *fh, const struct iovec *iov,
1896 int iovcnt, int64_t off)
1897{
11fdf7f2 1898 return (cmount->get_client()->ll_writev(fh, iov, iovcnt, off));
7c673cae
FG
1899}
1900
1901extern "C" int ceph_ll_close(class ceph_mount_info *cmount, Fh* fh)
1902{
1903 return (cmount->get_client()->ll_release(fh));
1904}
1905
1906extern "C" int ceph_ll_create(class ceph_mount_info *cmount,
1907 Inode *parent, const char *name, mode_t mode,
1908 int oflags, Inode **outp, Fh **fhp,
1909 struct ceph_statx *stx, unsigned want,
1910 unsigned lflags, const UserPerm *perms)
1911{
1912 if (lflags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1913 return -CEPHFS_EINVAL;
7c673cae
FG
1914 return (cmount->get_client())->ll_createx(parent, name, mode, oflags, outp,
1915 fhp, stx, want, lflags, *perms);
1916}
1917
1918extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent,
1919 const char *name, mode_t mode, dev_t rdev,
1920 Inode **out, struct ceph_statx *stx,
1921 unsigned want, unsigned flags,
1922 const UserPerm *perms)
1923{
1924 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1925 return -CEPHFS_EINVAL;
7c673cae
FG
1926 return (cmount->get_client())->ll_mknodx(parent, name, mode, rdev,
1927 out, stx, want, flags, *perms);
1928}
1929
1930extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent,
1931 const char *name, mode_t mode, Inode **out,
1932 struct ceph_statx *stx, unsigned want,
1933 unsigned flags, const UserPerm *perms)
1934{
1935 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1936 return -CEPHFS_EINVAL;
7c673cae
FG
1937 return cmount->get_client()->ll_mkdirx(parent, name, mode, out, stx, want,
1938 flags, *perms);
1939}
1940
1941extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
1942 Inode *in, Inode *newparent,
1943 const char *name, const UserPerm *perms)
1944{
1945 return cmount->get_client()->ll_link(in, newparent, name, *perms);
1946}
1947
1948extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
1949 Inode *in,
1950 struct ceph_dir_result **dirpp,
1951 const UserPerm *perms)
1952{
1953 return (cmount->get_client()->ll_opendir(in, O_RDONLY, (dir_result_t**) dirpp,
1954 *perms));
1955}
1956
1957extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,
1958 ceph_dir_result *dir)
1959{
9f95a23c 1960 return cmount->get_client()->ll_releasedir(reinterpret_cast<dir_result_t*>(dir));
7c673cae
FG
1961}
1962
1963extern "C" int ceph_ll_rename(class ceph_mount_info *cmount,
1964 Inode *parent, const char *name,
1965 Inode *newparent, const char *newname,
1966 const UserPerm *perms)
1967{
1968 return cmount->get_client()->ll_rename(parent, name, newparent,
1969 newname, *perms);
1970}
1971
1972extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, Inode *in,
1973 const char *name, const UserPerm *perms)
1974{
1975 return cmount->get_client()->ll_unlink(in, name, *perms);
1976}
1977
1978extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
1979 Inode *in, struct statvfs *stbuf)
1980{
1981 return (cmount->get_client()->ll_statfs(in, stbuf, cmount->default_perms));
1982}
1983
1984extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, Inode *in,
1985 char *buf, size_t bufsiz,
1986 const UserPerm *perms)
1987{
1988 return cmount->get_client()->ll_readlink(in, buf, bufsiz, *perms);
1989}
1990
1991extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,
1992 Inode *in, const char *name,
1993 const char *value, Inode **out,
1994 struct ceph_statx *stx, unsigned want,
1995 unsigned flags, const UserPerm *perms)
1996{
1997 if (flags & ~CEPH_REQ_FLAG_MASK)
1e59de90 1998 return -CEPHFS_EINVAL;
7c673cae
FG
1999 return (cmount->get_client()->ll_symlinkx(in, name, value, out, stx, want,
2000 flags, *perms));
2001}
2002
2003extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
2004 Inode *in, const char *name,
2005 const UserPerm *perms)
2006{
2007 return cmount->get_client()->ll_rmdir(in, name, *perms);
2008}
2009
2010extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount,
2011 Inode *in, const char *name, void *value,
2012 size_t size, const UserPerm *perms)
2013{
2014 return (cmount->get_client()->ll_getxattr(in, name, value, size, *perms));
2015}
2016
2017extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount,
2018 Inode *in, char *list,
2019 size_t buf_size, size_t *list_size,
2020 const UserPerm *perms)
2021{
2022 int res = cmount->get_client()->ll_listxattr(in, list, buf_size, *perms);
2023 if (res >= 0) {
2024 *list_size = (size_t)res;
2025 return 0;
2026 }
2027 return res;
2028}
2029
2030extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount,
2031 Inode *in, const char *name,
2032 const void *value, size_t size,
2033 int flags, const UserPerm *perms)
2034{
2035 return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, *perms));
2036}
2037
2038extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount,
2039 Inode *in, const char *name,
2040 const UserPerm *perms)
2041{
2042 return (cmount->get_client()->ll_removexattr(in, name, *perms));
2043}
2044
2045extern "C" int ceph_ll_getlk(struct ceph_mount_info *cmount,
2046 Fh *fh, struct flock *fl, uint64_t owner)
2047{
2048 return (cmount->get_client()->ll_getlk(fh, fl, owner));
2049}
2050
2051extern "C" int ceph_ll_setlk(struct ceph_mount_info *cmount,
2052 Fh *fh, struct flock *fl, uint64_t owner,
2053 int sleep)
2054{
2055 return (cmount->get_client()->ll_setlk(fh, fl, owner, sleep));
2056}
2057
11fdf7f2
TL
2058extern "C" int ceph_ll_lazyio(class ceph_mount_info *cmount,
2059 Fh *fh, int enable)
2060{
2061 return (cmount->get_client()->ll_lazyio(fh, enable));
2062}
2063
b32b8144
FG
2064extern "C" int ceph_ll_delegation(struct ceph_mount_info *cmount, Fh *fh,
2065 unsigned cmd, ceph_deleg_cb_t cb, void *priv)
2066{
2067 return (cmount->get_client()->ll_delegation(fh, cmd, cb, priv));
2068}
2069
7c673cae
FG
2070extern "C" uint32_t ceph_ll_stripe_unit(class ceph_mount_info *cmount,
2071 Inode *in)
2072{
2073 return (cmount->get_client()->ll_stripe_unit(in));
2074}
2075
2076extern "C" uint32_t ceph_ll_file_layout(class ceph_mount_info *cmount,
2077 Inode *in,
2078 struct ceph_file_layout *layout)
2079{
2080 file_layout_t l;
2081 int r = (cmount->get_client()->ll_file_layout(in, &l));
2082 l.to_legacy(layout);
2083 return r;
2084}
2085
2086uint64_t ceph_ll_snap_seq(class ceph_mount_info *cmount, Inode *in)
2087{
2088 return (cmount->get_client()->ll_snap_seq(in));
2089}
2090
2091extern "C" int ceph_ll_get_stripe_osd(class ceph_mount_info *cmount,
2092 Inode *in, uint64_t blockno,
2093 struct ceph_file_layout* layout)
2094{
2095 file_layout_t l;
2096 int r = (cmount->get_client()->ll_get_stripe_osd(in, blockno, &l));
2097 l.to_legacy(layout);
2098 return r;
2099}
2100
2101extern "C" int ceph_ll_num_osds(class ceph_mount_info *cmount)
2102{
2103 return (cmount->get_client()->ll_num_osds());
2104}
2105
2106extern "C" int ceph_ll_osdaddr(class ceph_mount_info *cmount,
2107 int osd, uint32_t *addr)
2108{
2109 return (cmount->get_client()->ll_osdaddr(osd, addr));
2110}
2111
2112extern "C" uint64_t ceph_ll_get_internal_offset(class ceph_mount_info *cmount,
2113 Inode *in,
2114 uint64_t blockno)
2115{
2116 return (cmount->get_client()->ll_get_internal_offset(in, blockno));
2117}
2118
2119extern "C" void ceph_buffer_free(char *buf)
2120{
2121 if (buf) {
2122 free(buf);
2123 }
2124}
b32b8144
FG
2125
2126extern "C" uint32_t ceph_get_cap_return_timeout(class ceph_mount_info *cmount)
2127{
2128 if (!cmount->is_mounted())
2129 return 0;
2130 return cmount->get_client()->mdsmap->get_session_autoclose().sec();
2131}
2132
2133extern "C" int ceph_set_deleg_timeout(class ceph_mount_info *cmount, uint32_t timeout)
2134{
2135 if (!cmount->is_mounted())
1e59de90 2136 return -CEPHFS_ENOTCONN;
b32b8144
FG
2137 return cmount->get_client()->set_deleg_timeout(timeout);
2138}
11fdf7f2
TL
2139
2140extern "C" void ceph_set_session_timeout(class ceph_mount_info *cmount, unsigned timeout)
2141{
2142 cmount->get_client()->set_session_timeout(timeout);
2143}
2144
2145extern "C" void ceph_set_uuid(class ceph_mount_info *cmount, const char *uuid)
2146{
2147 cmount->get_client()->set_uuid(std::string(uuid));
2148}
2149
2150extern "C" int ceph_start_reclaim(class ceph_mount_info *cmount,
2151 const char *uuid, unsigned flags)
2152{
2153 if (!cmount->is_initialized()) {
2154 int ret = cmount->init();
2155 if (ret != 0)
2156 return ret;
2157 }
2158 return cmount->get_client()->start_reclaim(std::string(uuid), flags,
2159 cmount->get_filesystem());
2160}
2161
2162extern "C" void ceph_finish_reclaim(class ceph_mount_info *cmount)
2163{
2164 cmount->get_client()->finish_reclaim();
2165}
e306af50 2166
20effc67 2167// This is deprecated, use ceph_ll_register_callbacks2 instead.
e306af50
TL
2168extern "C" void ceph_ll_register_callbacks(class ceph_mount_info *cmount,
2169 struct ceph_client_callback_args *args)
2170{
2171 cmount->get_client()->ll_register_callbacks(args);
20effc67 2172}
f67539c2 2173
20effc67
TL
2174extern "C" int ceph_ll_register_callbacks2(class ceph_mount_info *cmount,
2175 struct ceph_client_callback_args *args)
2176{
2177 return cmount->get_client()->ll_register_callbacks2(args);
f67539c2
TL
2178}
2179
2180
2181extern "C" int ceph_get_snap_info(struct ceph_mount_info *cmount,
2182 const char *path, struct snap_info *snap_info) {
2183 Client::SnapInfo info;
2184 int r = cmount->get_client()->get_snap_info(path, cmount->default_perms, &info);
2185 if (r < 0) {
2186 return r;
2187 }
2188
2189 size_t i = 0;
2190 auto nr_metadata = info.metadata.size();
2191
2192 snap_info->id = info.id.val;
2193 snap_info->nr_snap_metadata = nr_metadata;
2194 if (nr_metadata) {
2195 snap_info->snap_metadata = (struct snap_metadata *)calloc(nr_metadata, sizeof(struct snap_metadata));
2196 if (!snap_info->snap_metadata) {
1e59de90 2197 return -CEPHFS_ENOMEM;
f67539c2
TL
2198 }
2199
2200 // fill with key, value pairs
2201 for (auto &[key, value] : info.metadata) {
2202 // len(key) + '\0' + len(value) + '\0'
2203 char *kvp = (char *)malloc(key.size() + value.size() + 2);
2204 if (!kvp) {
2205 break;
2206 }
2207 char *_key = kvp;
2208 char *_value = kvp + key.size() + 1;
2209
2210 memcpy(_key, key.c_str(), key.size());
2211 _key[key.size()] = '\0';
2212 memcpy(_value, value.c_str(), value.size());
2213 _value[value.size()] = '\0';
2214
2215 snap_info->snap_metadata[i].key = _key;
2216 snap_info->snap_metadata[i].value = _value;
2217 ++i;
2218 }
2219 }
2220
2221 if (nr_metadata && i != nr_metadata) {
2222 ceph_free_snap_info_buffer(snap_info);
1e59de90 2223 return -CEPHFS_ENOMEM;
f67539c2
TL
2224 }
2225
2226 return 0;
2227}
2228
2229extern "C" void ceph_free_snap_info_buffer(struct snap_info *snap_info) {
2230 for (size_t i = 0; i < snap_info->nr_snap_metadata; ++i) {
2231 free((void *)snap_info->snap_metadata[i].key); // malloc'd memory is key+value composite
2232 }
2233 free(snap_info->snap_metadata);
e306af50 2234}