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