1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2009-2011 New Dream Network
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.
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"
34 #include "include/cephfs/libcephfs.h"
37 struct ceph_mount_info
40 explicit ceph_mount_info(CephContext *cct_)
49 if (cct_ != nullptr) {
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: "
75 common_init_finish(cct);
80 monclient = new MonClient(cct);
81 ret = -CEPHFS_ERROR_MON_MAP_BUILD; //defined in libcephfs.h;
82 if (monclient->build_initial_monmap() < 0)
86 messenger = Messenger::create_client_messenger(cct, "client");
89 ret = -CEPHFS_ERROR_NEW_CLIENT; //defined in libcephfs.h;
90 client = new StandaloneClient(messenger, monclient);
94 ret = -CEPHFS_ERROR_MESSENGER_START; //defined in libcephfs.h;
95 if (messenger->start() != 0)
102 default_perms = Client::pick_my_perms(cct);
111 int mount(const std::string &mount_root, const UserPerm& perms)
125 ret = client->mount(mount_root, perms);
154 messenger->shutdown();
169 bool is_initialized() const
179 int conf_read_file(const char *path_list)
181 int ret = cct->_conf->parse_config_files(path_list, NULL, 0);
184 cct->_conf->apply_changes(NULL);
185 cct->_conf->complain_about_parse_errors(cct);
189 int conf_parse_argv(int argc, const char **argv)
192 vector<const char*> args;
193 argv_to_vec(argc, argv, args);
194 ret = cct->_conf->parse_argv(args);
197 cct->_conf->apply_changes(NULL);
201 int conf_parse_env(const char *name)
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);
209 conf->apply_changes(NULL);
213 int conf_set(const char *option, const char *value)
215 int ret = cct->_conf->set_val(option, value);
218 cct->_conf->apply_changes(NULL);
222 int conf_get(const char *option, char *buf, size_t len)
225 return cct->_conf->get_val(option, &tmp, len);
233 const char *get_cwd(const UserPerm& perms)
235 client->getcwd(cwd, perms);
239 int chdir(const char *to, const UserPerm& perms)
241 return client->chdir(to, cwd, perms);
244 CephContext *get_ceph_context() const {
248 UserPerm default_perms;
252 StandaloneClient *client;
253 MonClient *monclient;
254 Messenger *messenger;
259 static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
262 if (outbl.length() > 0) {
263 *outbuf = (char *)malloc(outbl.length());
264 memcpy(*outbuf, outbl.c_str(), outbl.length());
270 *outbuflen = outbl.length();
273 static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
276 if (outbl.length() > 0) {
277 *outbuf = (char *)malloc(outbl.length());
278 memcpy(*outbuf, outbl.c_str(), outbl.length());
284 *outbuflen = outbl.length();
287 extern "C" UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids,
290 return new (std::nothrow) UserPerm(uid, gid, ngids, gidlist);
293 extern "C" void ceph_userperm_destroy(UserPerm *perm)
298 extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch)
300 int major, minor, patch;
301 const char *v = ceph_version_to_str();
303 int n = sscanf(v, "%d.%d.%d", &major, &minor, &patch);
305 *pmajor = (n >= 1) ? major : 0;
307 *pminor = (n >= 2) ? minor : 0;
309 *ppatch = (n >= 3) ? patch : 0;
313 extern "C" int ceph_create_with_context(struct ceph_mount_info **cmount, CephContext *cct)
315 *cmount = new struct ceph_mount_info(cct);
319 extern "C" int ceph_create_from_rados(struct ceph_mount_info **cmount,
322 auto rados = (librados::RadosClient *) cluster;
323 auto cct = rados->cct;
324 return ceph_create_with_context(cmount, cct);
327 extern "C" int ceph_create(struct ceph_mount_info **cmount, const char * const id)
329 CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
331 iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
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);
342 extern "C" int ceph_unmount(struct ceph_mount_info *cmount)
344 return cmount->unmount();
347 extern "C" int ceph_release(struct ceph_mount_info *cmount)
349 if (cmount->is_mounted())
355 extern "C" void ceph_shutdown(struct ceph_mount_info *cmount)
361 extern "C" int ceph_conf_read_file(struct ceph_mount_info *cmount, const char *path)
363 return cmount->conf_read_file(path);
366 extern "C" int ceph_conf_parse_argv(struct ceph_mount_info *cmount, int argc,
369 return cmount->conf_parse_argv(argc, argv);
372 extern "C" int ceph_conf_parse_env(struct ceph_mount_info *cmount, const char *name)
374 return cmount->conf_parse_env(name);
377 extern "C" int ceph_conf_set(struct ceph_mount_info *cmount, const char *option,
380 return cmount->conf_set(option, value);
383 extern "C" int ceph_conf_get(struct ceph_mount_info *cmount, const char *option,
384 char *buf, size_t len)
389 return cmount->conf_get(option, buf, len);
392 extern "C" int ceph_mds_command(struct ceph_mount_info *cmount,
393 const char *mds_spec,
396 const char *inbuf, size_t inbuflen,
397 char **outbuf, size_t *outbuflen,
398 char **outsbuf, size_t *outsbuflen)
402 std::vector<string> cmdv;
405 if (!cmount->is_initialized()) {
410 for (size_t i = 0; i < cmdlen; ++i) {
411 cmdv.push_back(cmd[i]);
413 inbl.append(inbuf, inbuflen);
415 // Issue remote command
417 int r = cmount->get_client()->mds_command(
427 // Wait for completion
431 do_out_buffer(outbl, outbuf, outbuflen);
432 do_out_buffer(outs, outsbuf, outsbuflen);
438 extern "C" int ceph_init(struct ceph_mount_info *cmount)
440 return cmount->init();
443 extern "C" int ceph_mount(struct ceph_mount_info *cmount, const char *root)
445 std::string mount_root;
448 return cmount->mount(mount_root, cmount->default_perms);
451 extern "C" int ceph_is_mounted(struct ceph_mount_info *cmount)
453 return cmount->is_mounted() ? 1 : 0;
456 extern "C" struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount)
458 return &cmount->default_perms;
461 extern "C" int ceph_statfs(struct ceph_mount_info *cmount, const char *path,
462 struct statvfs *stbuf)
464 if (!cmount->is_mounted())
466 return cmount->get_client()->statfs(path, stbuf, cmount->default_perms);
469 extern "C" int ceph_get_local_osd(struct ceph_mount_info *cmount)
471 if (!cmount->is_mounted())
473 return cmount->get_client()->get_local_osd();
476 extern "C" const char* ceph_getcwd(struct ceph_mount_info *cmount)
478 return cmount->get_cwd(cmount->default_perms);
481 extern "C" int ceph_chdir (struct ceph_mount_info *cmount, const char *s)
483 if (!cmount->is_mounted())
485 return cmount->chdir(s, cmount->default_perms);
488 extern "C" int ceph_opendir(struct ceph_mount_info *cmount,
489 const char *name, struct ceph_dir_result **dirpp)
491 if (!cmount->is_mounted())
493 return cmount->get_client()->opendir(name, (dir_result_t **)dirpp, cmount->default_perms);
496 extern "C" int ceph_closedir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
498 if (!cmount->is_mounted())
500 return cmount->get_client()->closedir(reinterpret_cast<dir_result_t*>(dirp));
503 extern "C" struct dirent * ceph_readdir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
505 if (!cmount->is_mounted()) {
506 /* Client::readdir also sets errno to signal errors. */
510 return cmount->get_client()->readdir(reinterpret_cast<dir_result_t*>(dirp));
513 extern "C" int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de)
515 if (!cmount->is_mounted())
517 return cmount->get_client()->readdir_r(reinterpret_cast<dir_result_t*>(dirp), de);
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)
524 if (!cmount->is_mounted())
526 if (flags & ~CEPH_REQ_FLAG_MASK)
528 return cmount->get_client()->readdirplus_r(reinterpret_cast<dir_result_t*>(dirp), de, stx, want, flags, out);
531 extern "C" int ceph_getdents(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
532 char *buf, int buflen)
534 if (!cmount->is_mounted())
536 return cmount->get_client()->getdents(reinterpret_cast<dir_result_t*>(dirp), buf, buflen);
539 extern "C" int ceph_getdnames(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp,
540 char *buf, int buflen)
542 if (!cmount->is_mounted())
544 return cmount->get_client()->getdnames(reinterpret_cast<dir_result_t*>(dirp), buf, buflen);
547 extern "C" void ceph_rewinddir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
549 if (!cmount->is_mounted())
551 cmount->get_client()->rewinddir(reinterpret_cast<dir_result_t*>(dirp));
554 extern "C" int64_t ceph_telldir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
556 if (!cmount->is_mounted())
558 return cmount->get_client()->telldir(reinterpret_cast<dir_result_t*>(dirp));
561 extern "C" void ceph_seekdir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, int64_t offset)
563 if (!cmount->is_mounted())
565 cmount->get_client()->seekdir(reinterpret_cast<dir_result_t*>(dirp), offset);
568 extern "C" int ceph_link (struct ceph_mount_info *cmount, const char *existing,
571 if (!cmount->is_mounted())
573 return cmount->get_client()->link(existing, newname, cmount->default_perms);
576 extern "C" int ceph_unlink(struct ceph_mount_info *cmount, const char *path)
578 if (!cmount->is_mounted())
580 return cmount->get_client()->unlink(path, cmount->default_perms);
583 extern "C" int ceph_rename(struct ceph_mount_info *cmount, const char *from,
586 if (!cmount->is_mounted())
588 return cmount->get_client()->rename(from, to, cmount->default_perms);
592 extern "C" int ceph_mkdir(struct ceph_mount_info *cmount, const char *path, mode_t mode)
594 if (!cmount->is_mounted())
596 return cmount->get_client()->mkdir(path, mode, cmount->default_perms);
599 extern "C" int ceph_mkdirs(struct ceph_mount_info *cmount, const char *path, mode_t mode)
601 if (!cmount->is_mounted())
603 return cmount->get_client()->mkdirs(path, mode, cmount->default_perms);
606 extern "C" int ceph_rmdir(struct ceph_mount_info *cmount, const char *path)
608 if (!cmount->is_mounted())
610 return cmount->get_client()->rmdir(path, cmount->default_perms);
614 extern "C" int ceph_readlink(struct ceph_mount_info *cmount, const char *path,
615 char *buf, int64_t size)
617 if (!cmount->is_mounted())
619 return cmount->get_client()->readlink(path, buf, size, cmount->default_perms);
622 extern "C" int ceph_symlink(struct ceph_mount_info *cmount, const char *existing,
625 if (!cmount->is_mounted())
627 return cmount->get_client()->symlink(existing, newname, cmount->default_perms);
630 extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx,
631 unsigned int want, unsigned int flags)
633 if (!cmount->is_mounted())
635 if (flags & ~CEPH_REQ_FLAG_MASK)
637 return cmount->get_client()->fstatx(fd, stx, cmount->default_perms,
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)
644 if (!cmount->is_mounted())
646 if (flags & ~CEPH_REQ_FLAG_MASK)
648 return cmount->get_client()->statx(path, stx, cmount->default_perms,
652 extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd,
653 struct ceph_statx *stx, int mask)
655 if (!cmount->is_mounted())
657 return cmount->get_client()->fsetattrx(fd, stx, mask, cmount->default_perms);
660 extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath,
661 struct ceph_statx *stx, int mask, int flags)
663 if (!cmount->is_mounted())
665 if (flags & ~CEPH_REQ_FLAG_MASK)
667 return cmount->get_client()->setattrx(relpath, stx, mask,
668 cmount->default_perms, flags);
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)
674 if (!cmount->is_mounted())
677 return cmount->get_client()->getxattr(path, name, value, size, cmount->default_perms);
680 extern "C" int ceph_lgetxattr(struct ceph_mount_info *cmount, const char *path, const char *name, void *value, size_t size)
682 if (!cmount->is_mounted())
684 return cmount->get_client()->lgetxattr(path, name, value, size, cmount->default_perms);
687 extern "C" int ceph_fgetxattr(struct ceph_mount_info *cmount, int fd, const char *name, void *value, size_t size)
689 if (!cmount->is_mounted())
691 return cmount->get_client()->fgetxattr(fd, name, value, size, cmount->default_perms);
695 extern "C" int ceph_listxattr(struct ceph_mount_info *cmount, const char *path, char *list, size_t size)
697 if (!cmount->is_mounted())
699 return cmount->get_client()->listxattr(path, list, size, cmount->default_perms);
702 extern "C" int ceph_llistxattr(struct ceph_mount_info *cmount, const char *path, char *list, size_t size)
704 if (!cmount->is_mounted())
706 return cmount->get_client()->llistxattr(path, list, size, cmount->default_perms);
709 extern "C" int ceph_flistxattr(struct ceph_mount_info *cmount, int fd, char *list, size_t size)
711 if (!cmount->is_mounted())
713 return cmount->get_client()->flistxattr(fd, list, size, cmount->default_perms);
716 extern "C" int ceph_removexattr(struct ceph_mount_info *cmount, const char *path, const char *name)
718 if (!cmount->is_mounted())
720 return cmount->get_client()->removexattr(path, name, cmount->default_perms);
723 extern "C" int ceph_lremovexattr(struct ceph_mount_info *cmount, const char *path, const char *name)
725 if (!cmount->is_mounted())
727 return cmount->get_client()->lremovexattr(path, name, cmount->default_perms);
730 extern "C" int ceph_fremovexattr(struct ceph_mount_info *cmount, int fd, const char *name)
732 if (!cmount->is_mounted())
734 return cmount->get_client()->fremovexattr(fd, name, cmount->default_perms);
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)
739 if (!cmount->is_mounted())
741 return cmount->get_client()->setxattr(path, name, value, size, flags, cmount->default_perms);
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)
746 if (!cmount->is_mounted())
748 return cmount->get_client()->lsetxattr(path, name, value, size, flags, cmount->default_perms);
751 extern "C" int ceph_fsetxattr(struct ceph_mount_info *cmount, int fd, const char *name, const void *value, size_t size, int flags)
753 if (!cmount->is_mounted())
755 return cmount->get_client()->fsetxattr(fd, name, value, size, flags, cmount->default_perms);
757 /* end xattr support */
759 extern "C" int ceph_chmod(struct ceph_mount_info *cmount, const char *path, mode_t mode)
761 if (!cmount->is_mounted())
763 return cmount->get_client()->chmod(path, mode, cmount->default_perms);
765 extern "C" int ceph_fchmod(struct ceph_mount_info *cmount, int fd, mode_t mode)
767 if (!cmount->is_mounted())
769 return cmount->get_client()->fchmod(fd, mode, cmount->default_perms);
771 extern "C" int ceph_chown(struct ceph_mount_info *cmount, const char *path,
774 if (!cmount->is_mounted())
776 return cmount->get_client()->chown(path, uid, gid, cmount->default_perms);
778 extern "C" int ceph_fchown(struct ceph_mount_info *cmount, int fd,
781 if (!cmount->is_mounted())
783 return cmount->get_client()->fchown(fd, uid, gid, cmount->default_perms);
785 extern "C" int ceph_lchown(struct ceph_mount_info *cmount, const char *path,
788 if (!cmount->is_mounted())
790 return cmount->get_client()->lchown(path, uid, gid, cmount->default_perms);
794 extern "C" int ceph_utime(struct ceph_mount_info *cmount, const char *path,
797 if (!cmount->is_mounted())
799 return cmount->get_client()->utime(path, buf, cmount->default_perms);
802 extern "C" int ceph_flock(struct ceph_mount_info *cmount, int fd, int operation,
805 if (!cmount->is_mounted())
807 return cmount->get_client()->flock(fd, operation, owner);
810 extern "C" int ceph_truncate(struct ceph_mount_info *cmount, const char *path,
813 if (!cmount->is_mounted())
815 return cmount->get_client()->truncate(path, size, cmount->default_perms);
819 extern "C" int ceph_mknod(struct ceph_mount_info *cmount, const char *path,
820 mode_t mode, dev_t rdev)
822 if (!cmount->is_mounted())
824 return cmount->get_client()->mknod(path, mode, cmount->default_perms, rdev);
827 extern "C" int ceph_open(struct ceph_mount_info *cmount, const char *path,
828 int flags, mode_t mode)
830 if (!cmount->is_mounted())
832 return cmount->get_client()->open(path, flags, cmount->default_perms, mode);
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)
838 if (!cmount->is_mounted())
840 return cmount->get_client()->open(path, flags, cmount->default_perms, mode,
841 stripe_unit, stripe_count,
842 object_size, data_pool);
845 extern "C" int ceph_close(struct ceph_mount_info *cmount, int fd)
847 if (!cmount->is_mounted())
849 return cmount->get_client()->close(fd);
852 extern "C" int64_t ceph_lseek(struct ceph_mount_info *cmount, int fd,
853 int64_t offset, int whence)
855 if (!cmount->is_mounted())
857 return cmount->get_client()->lseek(fd, offset, whence);
860 extern "C" int ceph_read(struct ceph_mount_info *cmount, int fd, char *buf,
861 int64_t size, int64_t offset)
863 if (!cmount->is_mounted())
865 return cmount->get_client()->read(fd, buf, size, offset);
868 extern "C" int ceph_preadv(struct ceph_mount_info *cmount, int fd,
869 const struct iovec *iov, int iovcnt, int64_t offset)
871 if (!cmount->is_mounted())
873 return cmount->get_client()->preadv(fd, iov, iovcnt, offset);
876 extern "C" int ceph_write(struct ceph_mount_info *cmount, int fd, const char *buf,
877 int64_t size, int64_t offset)
879 if (!cmount->is_mounted())
881 return cmount->get_client()->write(fd, buf, size, offset);
884 extern "C" int ceph_pwritev(struct ceph_mount_info *cmount, int fd,
885 const struct iovec *iov, int iovcnt, int64_t offset)
887 if (!cmount->is_mounted())
889 return cmount->get_client()->pwritev(fd, iov, iovcnt, offset);
892 extern "C" int ceph_ftruncate(struct ceph_mount_info *cmount, int fd, int64_t size)
894 if (!cmount->is_mounted())
896 return cmount->get_client()->ftruncate(fd, size, cmount->default_perms);
899 extern "C" int ceph_fsync(struct ceph_mount_info *cmount, int fd, int syncdataonly)
901 if (!cmount->is_mounted())
903 return cmount->get_client()->fsync(fd, syncdataonly);
906 extern "C" int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode,
907 int64_t offset, int64_t length)
909 if (!cmount->is_mounted())
911 return cmount->get_client()->fallocate(fd, mode, offset, length);
914 extern "C" int ceph_sync_fs(struct ceph_mount_info *cmount)
916 if (!cmount->is_mounted())
918 return cmount->get_client()->sync_fs();
922 extern "C" int ceph_get_file_stripe_unit(struct ceph_mount_info *cmount, int fh)
927 if (!cmount->is_mounted())
929 r = cmount->get_client()->fdescribe_layout(fh, &l);
932 return l.stripe_unit;
935 extern "C" int ceph_get_path_stripe_unit(struct ceph_mount_info *cmount, const char *path)
940 if (!cmount->is_mounted())
942 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
945 return l.stripe_unit;
948 extern "C" int ceph_get_file_stripe_count(struct ceph_mount_info *cmount, int fh)
953 if (!cmount->is_mounted())
955 r = cmount->get_client()->fdescribe_layout(fh, &l);
958 return l.stripe_count;
961 extern "C" int ceph_get_path_stripe_count(struct ceph_mount_info *cmount, const char *path)
966 if (!cmount->is_mounted())
968 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
971 return l.stripe_count;
974 extern "C" int ceph_get_file_object_size(struct ceph_mount_info *cmount, int fh)
979 if (!cmount->is_mounted())
981 r = cmount->get_client()->fdescribe_layout(fh, &l);
984 return l.object_size;
987 extern "C" int ceph_get_path_object_size(struct ceph_mount_info *cmount, const char *path)
992 if (!cmount->is_mounted())
994 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
997 return l.object_size;
1000 extern "C" int ceph_get_file_pool(struct ceph_mount_info *cmount, int fh)
1005 if (!cmount->is_mounted())
1007 r = cmount->get_client()->fdescribe_layout(fh, &l);
1013 extern "C" int ceph_get_path_pool(struct ceph_mount_info *cmount, const char *path)
1018 if (!cmount->is_mounted())
1020 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1026 extern "C" int ceph_get_file_pool_name(struct ceph_mount_info *cmount, int fh, char *buf, size_t len)
1031 if (!cmount->is_mounted())
1033 r = cmount->get_client()->fdescribe_layout(fh, &l);
1036 string name = cmount->get_client()->get_pool_name(l.pool_id);
1038 return name.length();
1039 if (name.length() > len)
1041 strncpy(buf, name.c_str(), len);
1042 return name.length();
1045 extern "C" int ceph_get_pool_name(struct ceph_mount_info *cmount, int pool, char *buf, size_t len)
1047 if (!cmount->is_mounted())
1049 string name = cmount->get_client()->get_pool_name(pool);
1051 return name.length();
1052 if (name.length() > len)
1054 strncpy(buf, name.c_str(), len);
1055 return name.length();
1058 extern "C" int ceph_get_path_pool_name(struct ceph_mount_info *cmount, const char *path, char *buf, size_t len)
1063 if (!cmount->is_mounted())
1065 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1068 string name = cmount->get_client()->get_pool_name(l.pool_id);
1070 return name.length();
1071 if (name.length() > len)
1073 strncpy(buf, name.c_str(), len);
1074 return name.length();
1077 extern "C" int ceph_get_default_data_pool_name(struct ceph_mount_info *cmount, char *buf, size_t len)
1079 if (!cmount->is_mounted())
1081 int64_t pool_id = cmount->get_client()->get_default_pool_id();
1083 string name = cmount->get_client()->get_pool_name(pool_id);
1085 return name.length();
1086 if (name.length() > len)
1088 strncpy(buf, name.c_str(), len);
1089 return name.length();
1092 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)
1097 if (!cmount->is_mounted())
1099 r = cmount->get_client()->fdescribe_layout(fh, &l);
1103 *stripe_unit = l.stripe_unit;
1105 *stripe_count = l.stripe_count;
1107 *object_size = l.object_size;
1109 *pg_pool = l.pool_id;
1113 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)
1118 if (!cmount->is_mounted())
1120 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1124 *stripe_unit = l.stripe_unit;
1126 *stripe_count = l.stripe_count;
1128 *object_size = l.object_size;
1130 *pg_pool = l.pool_id;
1134 extern "C" int ceph_get_file_replication(struct ceph_mount_info *cmount, int fh)
1139 if (!cmount->is_mounted())
1141 r = cmount->get_client()->fdescribe_layout(fh, &l);
1144 int rep = cmount->get_client()->get_pool_replication(l.pool_id);
1148 extern "C" int ceph_get_path_replication(struct ceph_mount_info *cmount, const char *path)
1153 if (!cmount->is_mounted())
1155 r = cmount->get_client()->describe_layout(path, &l, cmount->default_perms);
1158 int rep = cmount->get_client()->get_pool_replication(l.pool_id);
1162 extern "C" int ceph_set_default_file_stripe_unit(struct ceph_mount_info *cmount,
1165 // this option no longer exists
1169 extern "C" int ceph_set_default_file_stripe_count(struct ceph_mount_info *cmount,
1172 // this option no longer exists
1176 extern "C" int ceph_set_default_object_size(struct ceph_mount_info *cmount, int size)
1178 // this option no longer exists
1182 extern "C" int ceph_set_default_file_replication(struct ceph_mount_info *cmount,
1185 // this option no longer exists
1189 extern "C" int ceph_set_default_preferred_pg(struct ceph_mount_info *cmount, int osd)
1191 // this option no longer exists
1195 extern "C" int ceph_get_file_extent_osds(struct ceph_mount_info *cmount, int fh,
1196 int64_t offset, int64_t *length, int *osds, int nosds)
1201 if (!cmount->is_mounted())
1205 int ret = cmount->get_client()->get_file_extent_osds(fh, offset, length, vosds);
1210 return vosds.size();
1212 if ((int)vosds.size() > nosds)
1215 for (int i = 0; i < (int)vosds.size(); i++)
1218 return vosds.size();
1221 extern "C" int ceph_get_osd_crush_location(struct ceph_mount_info *cmount,
1222 int osd, char *path, size_t len)
1224 if (!cmount->is_mounted())
1230 vector<pair<string, string> > loc;
1231 int ret = cmount->get_client()->get_osd_crush_location(osd, loc);
1237 vector<pair<string, string> >::iterator it;
1238 for (it = loc.begin(); it != loc.end(); ++it) {
1239 string& type = it->first;
1240 string& name = it->second;
1241 needed += type.size() + name.size() + 2;
1242 if (needed <= len) {
1244 strcpy(path + cur, type.c_str());
1245 cur += type.size() + 1;
1247 strcpy(path + cur, name.c_str());
1248 cur += name.size() + 1;
1261 extern "C" int ceph_get_osd_addr(struct ceph_mount_info *cmount, int osd,
1262 struct sockaddr_storage *addr)
1264 if (!cmount->is_mounted())
1270 entity_addr_t address;
1271 int ret = cmount->get_client()->get_osd_addr(osd, address);
1275 *addr = address.get_sockaddr_storage();
1280 extern "C" int ceph_get_file_stripe_address(struct ceph_mount_info *cmount, int fh,
1281 int64_t offset, struct sockaddr_storage *addr, int naddr)
1283 vector<entity_addr_t> address;
1290 if (!cmount->is_mounted())
1293 r = cmount->get_client()->get_file_stripe_address(fh, offset, address);
1297 for (i = 0; i < (unsigned)naddr && i < address.size(); i++)
1298 addr[i] = address[i].get_sockaddr_storage();
1300 /* naddr == 0: drop through and return actual size */
1301 if (naddr && (address.size() > (unsigned)naddr))
1304 return address.size();
1307 extern "C" int ceph_localize_reads(struct ceph_mount_info *cmount, int val)
1309 if (!cmount->is_mounted())
1312 cmount->get_client()->clear_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS);
1314 cmount->get_client()->set_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS);
1318 extern "C" CephContext *ceph_get_mount_context(struct ceph_mount_info *cmount)
1320 return cmount->get_ceph_context();
1323 extern "C" int ceph_debug_get_fd_caps(struct ceph_mount_info *cmount, int fd)
1325 if (!cmount->is_mounted())
1327 return cmount->get_client()->get_caps_issued(fd);
1330 extern "C" int ceph_debug_get_file_caps(struct ceph_mount_info *cmount, const char *path)
1332 if (!cmount->is_mounted())
1334 return cmount->get_client()->get_caps_issued(path, cmount->default_perms);
1337 extern "C" int ceph_get_stripe_unit_granularity(struct ceph_mount_info *cmount)
1339 if (!cmount->is_mounted())
1341 return CEPH_MIN_STRIPE_UNIT;
1344 extern "C" int ceph_get_pool_id(struct ceph_mount_info *cmount, const char *pool_name)
1346 if (!cmount->is_mounted())
1349 if (!pool_name || !pool_name[0])
1352 /* negative range reserved for errors */
1353 int64_t pool_id = cmount->get_client()->get_pool_id(pool_name);
1354 if (pool_id > 0x7fffffff)
1357 /* get_pool_id error codes fit in int */
1358 return (int)pool_id;
1361 extern "C" int ceph_get_pool_replication(struct ceph_mount_info *cmount,
1364 if (!cmount->is_mounted())
1366 return cmount->get_client()->get_pool_replication(pool_id);
1368 /* Low-level exports */
1370 extern "C" int ceph_ll_lookup_root(struct ceph_mount_info *cmount,
1373 *parent = cmount->get_client()->get_root();
1379 extern "C" struct Inode *ceph_ll_get_inode(class ceph_mount_info *cmount,
1382 return (cmount->get_client())->ll_get_inode(vino);
1387 * Populates the client cache with the requested inode, and its
1390 extern "C" int ceph_ll_lookup_inode(
1391 struct ceph_mount_info *cmount,
1392 struct inodeno_t ino,
1395 int r = (cmount->get_client())->lookup_ino(ino, cmount->default_perms, inode);
1400 assert(inode != NULL);
1401 assert(*inode != NULL);
1403 // Request the parent inode, so that we can look up the name
1405 r = (cmount->get_client())->lookup_parent(*inode, cmount->default_perms, &parent);
1406 if (r && r != -EINVAL) {
1408 (cmount->get_client())->ll_forget(*inode, 1);
1410 } else if (r == -EINVAL) {
1411 // EINVAL indicates node without parents (root), drop out now
1412 // and don't try to look up the non-existent dentry.
1415 // FIXME: I don't think this works; lookup_parent() returns 0 if the parent
1416 // is already in cache
1417 assert(parent != NULL);
1419 // Finally, get the name (dentry) of the requested inode
1420 r = (cmount->get_client())->lookup_name(*inode, parent, cmount->default_perms);
1423 (cmount->get_client())->ll_forget(parent, 1);
1424 (cmount->get_client())->ll_forget(*inode, 1);
1428 (cmount->get_client())->ll_forget(parent, 1);
1432 extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount,
1433 Inode *parent, const char *name, Inode **out,
1434 struct ceph_statx *stx, unsigned want,
1435 unsigned flags, const UserPerm *perms)
1437 if (flags & ~CEPH_REQ_FLAG_MASK)
1439 return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want,
1443 extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
1445 return (cmount->get_client()->ll_put(in));
1448 extern "C" int ceph_ll_forget(class ceph_mount_info *cmount, Inode *in,
1451 return (cmount->get_client()->ll_forget(in, count));
1454 extern "C" int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i,
1455 struct ceph_statx *stx, unsigned int want, unsigned int flags,
1456 const UserPerm *perms)
1458 if (flags & ~CEPH_REQ_FLAG_MASK)
1460 return(cmount->get_client()->ll_walk(name, i, stx, want, flags, *perms));
1463 extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount,
1464 Inode *in, struct ceph_statx *stx,
1465 unsigned int want, unsigned int flags,
1466 const UserPerm *perms)
1468 if (flags & ~CEPH_REQ_FLAG_MASK)
1470 return (cmount->get_client()->ll_getattrx(in, stx, want, flags, *perms));
1473 extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount,
1474 Inode *in, struct ceph_statx *stx,
1475 int mask, const UserPerm *perms)
1477 return (cmount->get_client()->ll_setattrx(in, stx, mask, *perms));
1480 extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in,
1481 int flags, Fh **fh, const UserPerm *perms)
1483 return (cmount->get_client()->ll_open(in, flags, fh, *perms));
1486 extern "C" int ceph_ll_read(class ceph_mount_info *cmount, Fh* filehandle,
1487 int64_t off, uint64_t len, char* buf)
1492 r = cmount->get_client()->ll_read(filehandle, off, len, &bl);
1495 bl.copy(0, bl.length(), buf);
1501 extern "C" int ceph_ll_read_block(class ceph_mount_info *cmount,
1502 Inode *in, uint64_t blockid,
1503 char* buf, uint64_t offset,
1505 struct ceph_file_layout* layout)
1508 int r = (cmount->get_client()->ll_read_block(in, blockid, buf, offset,
1510 l.to_legacy(layout);
1514 extern "C" int ceph_ll_write_block(class ceph_mount_info *cmount,
1515 Inode *in, uint64_t blockid,
1516 char *buf, uint64_t offset,
1518 struct ceph_file_layout *layout,
1519 uint64_t snapseq, uint32_t sync)
1522 int r = (cmount->get_client()->ll_write_block(in, blockid, buf, offset,
1523 length, &l, snapseq, sync));
1524 l.to_legacy(layout);
1528 extern "C" int ceph_ll_commit_blocks(class ceph_mount_info *cmount,
1529 Inode *in, uint64_t offset,
1532 return (cmount->get_client()->ll_commit_blocks(in, offset, range));
1535 extern "C" int ceph_ll_fsync(class ceph_mount_info *cmount,
1536 Fh *fh, int syncdataonly)
1538 return (cmount->get_client()->ll_fsync(fh, syncdataonly));
1541 extern "C" off_t ceph_ll_lseek(class ceph_mount_info *cmount,
1542 Fh *fh, off_t offset, int whence)
1544 return (cmount->get_client()->ll_lseek(fh, offset, whence));
1547 extern "C" int ceph_ll_write(class ceph_mount_info *cmount,
1548 Fh *fh, int64_t off, uint64_t len,
1551 return (cmount->get_client()->ll_write(fh, off, len, data));
1554 extern "C" int64_t ceph_ll_readv(class ceph_mount_info *cmount,
1555 struct Fh *fh, const struct iovec *iov,
1556 int iovcnt, int64_t off)
1558 return -1; // TODO: implement
1561 extern "C" int64_t ceph_ll_writev(class ceph_mount_info *cmount,
1562 struct Fh *fh, const struct iovec *iov,
1563 int iovcnt, int64_t off)
1565 return -1; // TODO: implement
1568 extern "C" int ceph_ll_close(class ceph_mount_info *cmount, Fh* fh)
1570 return (cmount->get_client()->ll_release(fh));
1573 extern "C" int ceph_ll_create(class ceph_mount_info *cmount,
1574 Inode *parent, const char *name, mode_t mode,
1575 int oflags, Inode **outp, Fh **fhp,
1576 struct ceph_statx *stx, unsigned want,
1577 unsigned lflags, const UserPerm *perms)
1579 if (lflags & ~CEPH_REQ_FLAG_MASK)
1581 return (cmount->get_client())->ll_createx(parent, name, mode, oflags, outp,
1582 fhp, stx, want, lflags, *perms);
1585 extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent,
1586 const char *name, mode_t mode, dev_t rdev,
1587 Inode **out, struct ceph_statx *stx,
1588 unsigned want, unsigned flags,
1589 const UserPerm *perms)
1591 if (flags & ~CEPH_REQ_FLAG_MASK)
1593 return (cmount->get_client())->ll_mknodx(parent, name, mode, rdev,
1594 out, stx, want, flags, *perms);
1597 extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent,
1598 const char *name, mode_t mode, Inode **out,
1599 struct ceph_statx *stx, unsigned want,
1600 unsigned flags, const UserPerm *perms)
1602 if (flags & ~CEPH_REQ_FLAG_MASK)
1604 return cmount->get_client()->ll_mkdirx(parent, name, mode, out, stx, want,
1608 extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
1609 Inode *in, Inode *newparent,
1610 const char *name, const UserPerm *perms)
1612 return cmount->get_client()->ll_link(in, newparent, name, *perms);
1615 extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
1617 struct ceph_dir_result **dirpp,
1618 const UserPerm *perms)
1620 return (cmount->get_client()->ll_opendir(in, O_RDONLY, (dir_result_t**) dirpp,
1624 extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,
1625 ceph_dir_result *dir)
1627 (void) cmount->get_client()->ll_releasedir(reinterpret_cast<dir_result_t*>(dir));
1631 extern "C" int ceph_ll_rename(class ceph_mount_info *cmount,
1632 Inode *parent, const char *name,
1633 Inode *newparent, const char *newname,
1634 const UserPerm *perms)
1636 return cmount->get_client()->ll_rename(parent, name, newparent,
1640 extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, Inode *in,
1641 const char *name, const UserPerm *perms)
1643 return cmount->get_client()->ll_unlink(in, name, *perms);
1646 extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
1647 Inode *in, struct statvfs *stbuf)
1649 return (cmount->get_client()->ll_statfs(in, stbuf, cmount->default_perms));
1652 extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, Inode *in,
1653 char *buf, size_t bufsiz,
1654 const UserPerm *perms)
1656 return cmount->get_client()->ll_readlink(in, buf, bufsiz, *perms);
1659 extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,
1660 Inode *in, const char *name,
1661 const char *value, Inode **out,
1662 struct ceph_statx *stx, unsigned want,
1663 unsigned flags, const UserPerm *perms)
1665 if (flags & ~CEPH_REQ_FLAG_MASK)
1667 return (cmount->get_client()->ll_symlinkx(in, name, value, out, stx, want,
1671 extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
1672 Inode *in, const char *name,
1673 const UserPerm *perms)
1675 return cmount->get_client()->ll_rmdir(in, name, *perms);
1678 extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount,
1679 Inode *in, const char *name, void *value,
1680 size_t size, const UserPerm *perms)
1682 return (cmount->get_client()->ll_getxattr(in, name, value, size, *perms));
1685 extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount,
1686 Inode *in, char *list,
1687 size_t buf_size, size_t *list_size,
1688 const UserPerm *perms)
1690 int res = cmount->get_client()->ll_listxattr(in, list, buf_size, *perms);
1692 *list_size = (size_t)res;
1698 extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount,
1699 Inode *in, const char *name,
1700 const void *value, size_t size,
1701 int flags, const UserPerm *perms)
1703 return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, *perms));
1706 extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount,
1707 Inode *in, const char *name,
1708 const UserPerm *perms)
1710 return (cmount->get_client()->ll_removexattr(in, name, *perms));
1713 extern "C" int ceph_ll_getlk(struct ceph_mount_info *cmount,
1714 Fh *fh, struct flock *fl, uint64_t owner)
1716 return (cmount->get_client()->ll_getlk(fh, fl, owner));
1719 extern "C" int ceph_ll_setlk(struct ceph_mount_info *cmount,
1720 Fh *fh, struct flock *fl, uint64_t owner,
1723 return (cmount->get_client()->ll_setlk(fh, fl, owner, sleep));
1726 extern "C" uint32_t ceph_ll_stripe_unit(class ceph_mount_info *cmount,
1729 return (cmount->get_client()->ll_stripe_unit(in));
1732 extern "C" uint32_t ceph_ll_file_layout(class ceph_mount_info *cmount,
1734 struct ceph_file_layout *layout)
1737 int r = (cmount->get_client()->ll_file_layout(in, &l));
1738 l.to_legacy(layout);
1742 uint64_t ceph_ll_snap_seq(class ceph_mount_info *cmount, Inode *in)
1744 return (cmount->get_client()->ll_snap_seq(in));
1747 extern "C" int ceph_ll_get_stripe_osd(class ceph_mount_info *cmount,
1748 Inode *in, uint64_t blockno,
1749 struct ceph_file_layout* layout)
1752 int r = (cmount->get_client()->ll_get_stripe_osd(in, blockno, &l));
1753 l.to_legacy(layout);
1757 extern "C" int ceph_ll_num_osds(class ceph_mount_info *cmount)
1759 return (cmount->get_client()->ll_num_osds());
1762 extern "C" int ceph_ll_osdaddr(class ceph_mount_info *cmount,
1763 int osd, uint32_t *addr)
1765 return (cmount->get_client()->ll_osdaddr(osd, addr));
1768 extern "C" uint64_t ceph_ll_get_internal_offset(class ceph_mount_info *cmount,
1772 return (cmount->get_client()->ll_get_internal_offset(in, blockno));
1775 extern "C" void ceph_buffer_free(char *buf)