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