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