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