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 "client/Inode.h"
23 #include "librados/RadosClient.h"
24 #include "common/async/context_pool.h"
25 #include "common/ceph_argparse.h"
26 #include "common/common_init.h"
27 #include "common/config.h"
28 #include "common/version.h"
29 #include "mon/MonClient.h"
30 #include "include/str_list.h"
31 #include "include/stringify.h"
32 #include "include/object.h"
33 #include "messages/MMonMap.h"
34 #include "msg/Messenger.h"
35 #include "include/ceph_assert.h"
36 #include "mds/MDSMap.h"
38 #include "include/cephfs/libcephfs.h"
40 #define DEFAULT_UMASK 002
44 static mode_t
umask_cb(void *);
46 // Set things up this way so we don't start up threads until mount and
47 // kill them off when the last mount goes away, but are tolerant to
48 // multiple mounts of overlapping duration.
49 std::shared_ptr
<ceph::async::io_context_pool
> get_icp(CephContext
* cct
)
52 static std::weak_ptr
<ceph::async::io_context_pool
> icwp
;
55 std::unique_lock
l(m
);
57 auto icp
= icwp
.lock();
61 icp
= std::make_shared
<ceph::async::io_context_pool
>();
63 icp
->start(cct
->_conf
.get_val
<std::uint64_t>("client_asio_thread_count"));
68 struct ceph_mount_info
70 mode_t umask
= DEFAULT_UMASK
;
71 std::shared_ptr
<ceph::async::io_context_pool
> icp
;
73 explicit ceph_mount_info(CephContext
*cct_
)
96 catch (const std::exception
& e
) {
97 // we shouldn't get here, but if we do, we want to know about it.
98 lderr(cct
) << "ceph_mount_info::~ceph_mount_info: caught exception: "
110 if (!cct
->_log
->is_started()) {
116 MonClient
mc_bootstrap(cct
, icp
->get_io_context());
117 ret
= mc_bootstrap
.get_monmap_and_config();
122 common_init_finish(cct
);
125 monclient
= new MonClient(cct
, icp
->get_io_context());
126 ret
= -CEPHFS_ERROR_MON_MAP_BUILD
; //defined in libcephfs.h;
127 if (monclient
->build_initial_monmap() < 0)
131 messenger
= Messenger::create_client_messenger(cct
, "client");
134 ret
= -CEPHFS_ERROR_NEW_CLIENT
; //defined in libcephfs.h;
135 client
= new StandaloneClient(messenger
, monclient
, icp
->get_io_context());
139 ret
= -CEPHFS_ERROR_MESSENGER_START
; //defined in libcephfs.h;
140 if (messenger
->start() != 0)
143 ret
= client
->init();
148 ceph_client_callback_args args
= {};
150 args
.umask_cb
= umask_cb
;
151 client
->ll_register_callbacks(&args
);
154 default_perms
= Client::pick_my_perms(cct
);
163 int select_filesystem(const std::string
&fs_name_
)
166 return -CEPHFS_EISCONN
;
173 const std::string
& get_filesystem(void)
178 int mount(const std::string
&mount_root
, const UserPerm
& perms
)
183 return -CEPHFS_EISCONN
;
192 ret
= client
->mount(mount_root
, perms
, false, fs_name
);
205 return -CEPHFS_ENOTCONN
;
212 client
->abort_conn();
229 messenger
->shutdown();
245 bool is_initialized() const
255 mode_t
set_umask(mode_t umask
)
261 std::string
getaddrs()
263 CachedStackStringStream cos
;
264 *cos
<< messenger
->get_myaddrs();
265 return std::string(cos
->strv());
268 int conf_read_file(const char *path_list
)
270 int ret
= cct
->_conf
.parse_config_files(path_list
, nullptr, 0);
273 cct
->_conf
.apply_changes(nullptr);
274 cct
->_conf
.complain_about_parse_error(cct
);
278 int conf_parse_argv(int argc
, const char **argv
)
280 auto args
= argv_to_vec(argc
, argv
);
281 int ret
= cct
->_conf
.parse_argv(args
);
284 cct
->_conf
.apply_changes(nullptr);
288 int conf_parse_env(const char *name
)
290 auto& conf
= cct
->_conf
;
291 conf
.parse_env(cct
->get_module_type(), name
);
292 conf
.apply_changes(nullptr);
296 int conf_set(const char *option
, const char *value
)
298 int ret
= cct
->_conf
.set_val(option
, value
);
301 cct
->_conf
.apply_changes(nullptr);
305 int conf_get(const char *option
, char *buf
, size_t len
)
308 return cct
->_conf
.get_val(option
, &tmp
, len
);
316 const char *get_cwd(const UserPerm
& perms
)
318 client
->getcwd(cwd
, perms
);
322 int chdir(const char *to
, const UserPerm
& perms
)
324 return client
->chdir(to
, cwd
, perms
);
327 CephContext
*get_ceph_context() const {
331 UserPerm default_perms
;
335 StandaloneClient
*client
;
336 MonClient
*monclient
;
337 Messenger
*messenger
;
343 static mode_t
umask_cb(void *handle
)
345 return ((struct ceph_mount_info
*)handle
)->umask
;
348 static void do_out_buffer(bufferlist
& outbl
, char **outbuf
, size_t *outbuflen
)
351 if (outbl
.length() > 0) {
352 *outbuf
= (char *)malloc(outbl
.length());
353 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
359 *outbuflen
= outbl
.length();
362 static void do_out_buffer(string
& outbl
, char **outbuf
, size_t *outbuflen
)
365 if (outbl
.length() > 0) {
366 *outbuf
= (char *)malloc(outbl
.length());
367 memcpy(*outbuf
, outbl
.c_str(), outbl
.length());
373 *outbuflen
= outbl
.length();
376 extern "C" UserPerm
*ceph_userperm_new(uid_t uid
, gid_t gid
, int ngids
,
379 return new (std::nothrow
) UserPerm(uid
, gid
, ngids
, gidlist
);
382 extern "C" void ceph_userperm_destroy(UserPerm
*perm
)
387 extern "C" const char *ceph_version(int *pmajor
, int *pminor
, int *ppatch
)
389 int major
, minor
, patch
;
390 const char *v
= ceph_version_to_str();
392 int n
= sscanf(v
, "%d.%d.%d", &major
, &minor
, &patch
);
394 *pmajor
= (n
>= 1) ? major
: 0;
396 *pminor
= (n
>= 2) ? minor
: 0;
398 *ppatch
= (n
>= 3) ? patch
: 0;
399 return PROJECT_VERSION
;
402 extern "C" int ceph_create_with_context(struct ceph_mount_info
**cmount
, CephContext
*cct
)
404 *cmount
= new struct ceph_mount_info(cct
);
408 extern "C" int ceph_create_from_rados(struct ceph_mount_info
**cmount
,
411 auto rados
= (librados::RadosClient
*) cluster
;
412 auto cct
= rados
->cct
;
413 return ceph_create_with_context(cmount
, cct
);
416 extern "C" int ceph_create(struct ceph_mount_info
**cmount
, const char * const id
)
418 CephInitParameters
iparams(CEPH_ENTITY_TYPE_CLIENT
);
420 iparams
.name
.set(CEPH_ENTITY_TYPE_CLIENT
, id
);
423 CephContext
*cct
= common_preinit(iparams
, CODE_ENVIRONMENT_LIBRARY
, 0);
424 cct
->_conf
.parse_env(cct
->get_module_type()); // environment variables coverride
425 cct
->_conf
.apply_changes(nullptr);
426 int ret
= ceph_create_with_context(cmount
, cct
);
432 extern "C" int ceph_unmount(struct ceph_mount_info
*cmount
)
434 return cmount
->unmount();
437 extern "C" int ceph_abort_conn(struct ceph_mount_info
*cmount
)
439 return cmount
->abort_conn();
442 extern "C" int ceph_release(struct ceph_mount_info
*cmount
)
444 if (cmount
->is_mounted())
445 return -CEPHFS_EISCONN
;
451 extern "C" void ceph_shutdown(struct ceph_mount_info
*cmount
)
458 extern "C" uint64_t ceph_get_instance_id(struct ceph_mount_info
*cmount
)
460 if (cmount
->is_initialized())
461 return cmount
->get_client()->get_nodeid().v
;
465 extern "C" int ceph_getaddrs(struct ceph_mount_info
*cmount
, char** addrs
)
467 if (!cmount
->is_initialized())
468 return -CEPHFS_ENOTCONN
;
469 auto s
= cmount
->getaddrs();
470 *addrs
= strdup(s
.c_str());
474 extern "C" int ceph_conf_read_file(struct ceph_mount_info
*cmount
, const char *path
)
476 return cmount
->conf_read_file(path
);
479 extern "C" mode_t
ceph_umask(struct ceph_mount_info
*cmount
, mode_t mode
)
481 return cmount
->set_umask(mode
);
484 extern "C" int ceph_conf_parse_argv(struct ceph_mount_info
*cmount
, int argc
,
487 return cmount
->conf_parse_argv(argc
, argv
);
490 extern "C" int ceph_conf_parse_env(struct ceph_mount_info
*cmount
, const char *name
)
492 return cmount
->conf_parse_env(name
);
495 extern "C" int ceph_conf_set(struct ceph_mount_info
*cmount
, const char *option
,
498 return cmount
->conf_set(option
, value
);
501 extern "C" int ceph_conf_get(struct ceph_mount_info
*cmount
, const char *option
,
502 char *buf
, size_t len
)
505 return -CEPHFS_EINVAL
;
507 return cmount
->conf_get(option
, buf
, len
);
510 extern "C" int ceph_set_mount_timeout(struct ceph_mount_info
*cmount
, uint32_t timeout
) {
511 if (cmount
->is_mounted()) {
512 return -CEPHFS_EINVAL
;
515 auto timeout_str
= stringify(timeout
);
516 return ceph_conf_set(cmount
, "client_mount_timeout", timeout_str
.c_str());
519 extern "C" int ceph_mds_command(struct ceph_mount_info
*cmount
,
520 const char *mds_spec
,
523 const char *inbuf
, size_t inbuflen
,
524 char **outbuf
, size_t *outbuflen
,
525 char **outsbuf
, size_t *outsbuflen
)
529 std::vector
<string
> cmdv
;
532 if (!cmount
->is_initialized()) {
533 return -CEPHFS_ENOTCONN
;
537 for (size_t i
= 0; i
< cmdlen
; ++i
) {
538 cmdv
.push_back(cmd
[i
]);
540 inbl
.append(inbuf
, inbuflen
);
542 // Issue remote command
544 int r
= cmount
->get_client()->mds_command(
554 // Wait for completion
558 do_out_buffer(outbl
, outbuf
, outbuflen
);
559 do_out_buffer(outs
, outsbuf
, outsbuflen
);
565 extern "C" int ceph_init(struct ceph_mount_info
*cmount
)
567 return cmount
->init();
570 extern "C" int ceph_select_filesystem(struct ceph_mount_info
*cmount
,
573 if (fs_name
== nullptr) {
574 return -CEPHFS_EINVAL
;
577 return cmount
->select_filesystem(fs_name
);
580 extern "C" int ceph_mount(struct ceph_mount_info
*cmount
, const char *root
)
582 std::string mount_root
;
585 return cmount
->mount(mount_root
, cmount
->default_perms
);
588 extern "C" int ceph_is_mounted(struct ceph_mount_info
*cmount
)
590 return cmount
->is_mounted() ? 1 : 0;
593 extern "C" struct UserPerm
*ceph_mount_perms(struct ceph_mount_info
*cmount
)
595 return &cmount
->default_perms
;
598 extern "C" int64_t ceph_get_fs_cid(struct ceph_mount_info
*cmount
)
600 if (!cmount
->is_mounted())
601 return -CEPHFS_ENOTCONN
;
602 return cmount
->get_client()->get_fs_cid();
605 extern "C" int ceph_mount_perms_set(struct ceph_mount_info
*cmount
,
606 struct UserPerm
*perms
)
608 if (cmount
->is_mounted())
609 return -CEPHFS_EISCONN
;
610 cmount
->default_perms
= *perms
;
614 extern "C" int ceph_statfs(struct ceph_mount_info
*cmount
, const char *path
,
615 struct statvfs
*stbuf
)
617 if (!cmount
->is_mounted())
618 return -CEPHFS_ENOTCONN
;
619 return cmount
->get_client()->statfs(path
, stbuf
, cmount
->default_perms
);
622 extern "C" int ceph_get_local_osd(struct ceph_mount_info
*cmount
)
624 if (!cmount
->is_mounted())
625 return -CEPHFS_ENOTCONN
;
626 return cmount
->get_client()->get_local_osd();
629 extern "C" const char* ceph_getcwd(struct ceph_mount_info
*cmount
)
631 return cmount
->get_cwd(cmount
->default_perms
);
634 extern "C" int ceph_chdir (struct ceph_mount_info
*cmount
, const char *s
)
636 if (!cmount
->is_mounted())
637 return -CEPHFS_ENOTCONN
;
638 return cmount
->chdir(s
, cmount
->default_perms
);
641 extern "C" int ceph_opendir(struct ceph_mount_info
*cmount
,
642 const char *name
, struct ceph_dir_result
**dirpp
)
644 if (!cmount
->is_mounted())
645 return -CEPHFS_ENOTCONN
;
646 return cmount
->get_client()->opendir(name
, (dir_result_t
**)dirpp
, cmount
->default_perms
);
649 extern "C" int ceph_fdopendir(struct ceph_mount_info
*cmount
, int dirfd
,
650 struct ceph_dir_result
**dirpp
)
652 if (!cmount
->is_mounted())
653 return -CEPHFS_ENOTCONN
;
654 return cmount
->get_client()->fdopendir(dirfd
, (dir_result_t
**)dirpp
, cmount
->default_perms
);
657 extern "C" int ceph_closedir(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
)
659 if (!cmount
->is_mounted())
660 return -CEPHFS_ENOTCONN
;
661 return cmount
->get_client()->closedir(reinterpret_cast<dir_result_t
*>(dirp
));
664 extern "C" struct dirent
* ceph_readdir(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
)
666 if (!cmount
->is_mounted()) {
667 /* Client::readdir also sets errno to signal errors. */
668 errno
= CEPHFS_ENOTCONN
;
671 return cmount
->get_client()->readdir(reinterpret_cast<dir_result_t
*>(dirp
));
674 extern "C" int ceph_readdir_r(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
, struct dirent
*de
)
676 if (!cmount
->is_mounted())
677 return -CEPHFS_ENOTCONN
;
678 return cmount
->get_client()->readdir_r(reinterpret_cast<dir_result_t
*>(dirp
), de
);
681 extern "C" int ceph_readdirplus_r(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
,
682 struct dirent
*de
, struct ceph_statx
*stx
, unsigned want
,
683 unsigned flags
, struct Inode
**out
)
685 if (!cmount
->is_mounted())
686 return -CEPHFS_ENOTCONN
;
687 if (flags
& ~CEPH_REQ_FLAG_MASK
)
688 return -CEPHFS_EINVAL
;
689 return cmount
->get_client()->readdirplus_r(reinterpret_cast<dir_result_t
*>(dirp
), de
, stx
, want
, flags
, out
);
692 extern "C" int ceph_open_snapdiff(struct ceph_mount_info
* cmount
,
693 const char* root_path
,
694 const char* rel_path
,
697 struct ceph_snapdiff_info
* out
)
699 if (!cmount
->is_mounted()) {
700 /* we set errno to signal errors. */
704 if (!out
|| !root_path
|| !rel_path
||
705 !snap1
|| !*snap1
|| !snap2
|| !*snap2
) {
709 out
->cmount
= cmount
;
710 out
->dir1
= out
->dir_aux
= nullptr;
712 char full_path1
[PATH_MAX
];
713 char snapdir
[PATH_MAX
];
714 cmount
->conf_get("client_snapdir", snapdir
, sizeof(snapdir
) - 1);
715 int n
= snprintf(full_path1
, PATH_MAX
,
716 "%s/%s/%s/%s", root_path
, snapdir
, snap1
, rel_path
);
717 if (n
< 0 || n
== PATH_MAX
) {
718 errno
= ENAMETOOLONG
;
721 char full_path2
[PATH_MAX
];
722 n
= snprintf(full_path2
, PATH_MAX
,
723 "%s/%s/%s/%s", root_path
, snapdir
, snap2
, rel_path
);
724 if (n
< 0 || n
== PATH_MAX
) {
725 errno
= ENAMETOOLONG
;
729 int r
= ceph_opendir(cmount
, full_path1
, &(out
->dir1
));
731 //it's OK to have one of the snap paths absent - attempting another one
732 r
= ceph_opendir(cmount
, full_path2
, &(out
->dir1
));
734 // both snaps are absent, giving up
738 std::swap(snap1
, snap2
); // will use snap1 to learn snap_other below
740 // trying to open second snapshot to learn snapid and
741 // get the entry loaded into the client cache if any.
742 r
= ceph_opendir(cmount
, full_path2
, &(out
->dir_aux
));
743 //paranoic, rely on this value below
744 out
->dir_aux
= r
== 0 ? out
->dir_aux
: nullptr;
747 // now trying to learn the second snapshot's id by using snapshot's root
748 n
= snprintf(full_path2
, PATH_MAX
,
749 "%s/%s/%s", root_path
, snapdir
, snap2
);
750 ceph_assert(n
> 0 && n
< PATH_MAX
); //we've already checked above
751 //that longer string fits.
752 // Hence unlikely to assert
753 r
= ceph_opendir(cmount
, full_path2
, &(out
->dir_aux
));
761 ceph_close_snapdiff(out
);
765 extern "C" int ceph_readdir_snapdiff(struct ceph_snapdiff_info
* snapdiff
,
766 struct ceph_snapdiff_entry_t
* out
)
768 if (!snapdiff
->cmount
->is_mounted()) {
769 /* also sets errno to signal errors. */
773 dir_result_t
* d1
= reinterpret_cast<dir_result_t
*>(snapdiff
->dir1
);
774 dir_result_t
* d2
= reinterpret_cast<dir_result_t
*>(snapdiff
->dir_aux
);
775 if (!d1
|| !d2
|| !d1
->inode
|| !d2
->inode
) {
780 int r
= snapdiff
->cmount
->get_client()->readdir_snapdiff(
786 // converting snapid_t to uint64_t to avoid snapid_t exposure
787 out
->snapid
= snapid
;
792 extern "C" int ceph_close_snapdiff(struct ceph_snapdiff_info
* snapdiff
)
794 if (!snapdiff
->cmount
|| !snapdiff
->cmount
->is_mounted()) {
795 /* also sets errno to signal errors. */
799 if (snapdiff
->dir_aux
) {
800 ceph_closedir(snapdiff
->cmount
, snapdiff
->dir_aux
);
802 if (snapdiff
->dir1
) {
803 ceph_closedir(snapdiff
->cmount
, snapdiff
->dir1
);
805 snapdiff
->cmount
= nullptr;
806 snapdiff
->dir1
= snapdiff
->dir_aux
= nullptr;
810 extern "C" int ceph_getdents(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
,
811 char *buf
, int buflen
)
813 if (!cmount
->is_mounted())
814 return -CEPHFS_ENOTCONN
;
815 return cmount
->get_client()->getdents(reinterpret_cast<dir_result_t
*>(dirp
), buf
, buflen
);
818 extern "C" int ceph_getdnames(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
,
819 char *buf
, int buflen
)
821 if (!cmount
->is_mounted())
822 return -CEPHFS_ENOTCONN
;
823 return cmount
->get_client()->getdnames(reinterpret_cast<dir_result_t
*>(dirp
), buf
, buflen
);
826 extern "C" void ceph_rewinddir(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
)
828 if (!cmount
->is_mounted())
830 cmount
->get_client()->rewinddir(reinterpret_cast<dir_result_t
*>(dirp
));
833 extern "C" int64_t ceph_telldir(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
)
835 if (!cmount
->is_mounted())
836 return -CEPHFS_ENOTCONN
;
837 return cmount
->get_client()->telldir(reinterpret_cast<dir_result_t
*>(dirp
));
840 extern "C" void ceph_seekdir(struct ceph_mount_info
*cmount
, struct ceph_dir_result
*dirp
, int64_t offset
)
842 if (!cmount
->is_mounted())
844 cmount
->get_client()->seekdir(reinterpret_cast<dir_result_t
*>(dirp
), offset
);
847 extern "C" int ceph_may_delete(struct ceph_mount_info
*cmount
, const char *path
)
849 if (!cmount
->is_mounted())
850 return -CEPHFS_ENOTCONN
;
851 return cmount
->get_client()->may_delete(path
, cmount
->default_perms
);
854 extern "C" int ceph_link (struct ceph_mount_info
*cmount
, const char *existing
,
857 if (!cmount
->is_mounted())
858 return -CEPHFS_ENOTCONN
;
859 return cmount
->get_client()->link(existing
, newname
, cmount
->default_perms
);
862 extern "C" int ceph_unlink(struct ceph_mount_info
*cmount
, const char *path
)
864 if (!cmount
->is_mounted())
865 return -CEPHFS_ENOTCONN
;
866 return cmount
->get_client()->unlink(path
, cmount
->default_perms
);
869 extern "C" int ceph_unlinkat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
, int flags
)
871 if (!cmount
->is_mounted())
872 return -CEPHFS_ENOTCONN
;
873 return cmount
->get_client()->unlinkat(dirfd
, relpath
, flags
, cmount
->default_perms
);
876 extern "C" int ceph_rename(struct ceph_mount_info
*cmount
, const char *from
,
879 if (!cmount
->is_mounted())
880 return -CEPHFS_ENOTCONN
;
881 return cmount
->get_client()->rename(from
, to
, cmount
->default_perms
);
885 extern "C" int ceph_mkdir(struct ceph_mount_info
*cmount
, const char *path
, mode_t mode
)
887 if (!cmount
->is_mounted())
888 return -CEPHFS_ENOTCONN
;
889 return cmount
->get_client()->mkdir(path
, mode
, cmount
->default_perms
);
892 extern "C" int ceph_mkdirat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
895 if (!cmount
->is_mounted())
896 return -CEPHFS_ENOTCONN
;
897 return cmount
->get_client()->mkdirat(dirfd
, relpath
, mode
, cmount
->default_perms
);
900 extern "C" int ceph_mksnap(struct ceph_mount_info
*cmount
, const char *path
, const char *name
,
901 mode_t mode
, struct snap_metadata
*snap_metadata
, size_t nr_snap_metadata
)
903 if (!cmount
->is_mounted())
904 return -CEPHFS_ENOTCONN
;
906 std::map
<std::string
, std::string
> metadata
;
907 while (i
< nr_snap_metadata
) {
908 metadata
.emplace(snap_metadata
[i
].key
, snap_metadata
[i
].value
);
911 return cmount
->get_client()->mksnap(path
, name
, cmount
->default_perms
, mode
, metadata
);
914 extern "C" int ceph_rmsnap(struct ceph_mount_info
*cmount
, const char *path
, const char *name
)
916 if (!cmount
->is_mounted())
917 return -CEPHFS_ENOTCONN
;
918 return cmount
->get_client()->rmsnap(path
, name
, cmount
->default_perms
, true);
921 extern "C" int ceph_mkdirs(struct ceph_mount_info
*cmount
, const char *path
, mode_t mode
)
923 if (!cmount
->is_mounted())
924 return -CEPHFS_ENOTCONN
;
925 return cmount
->get_client()->mkdirs(path
, mode
, cmount
->default_perms
);
928 extern "C" int ceph_rmdir(struct ceph_mount_info
*cmount
, const char *path
)
930 if (!cmount
->is_mounted())
931 return -CEPHFS_ENOTCONN
;
932 return cmount
->get_client()->rmdir(path
, cmount
->default_perms
);
936 extern "C" int ceph_readlink(struct ceph_mount_info
*cmount
, const char *path
,
937 char *buf
, int64_t size
)
939 if (!cmount
->is_mounted())
940 return -CEPHFS_ENOTCONN
;
941 return cmount
->get_client()->readlink(path
, buf
, size
, cmount
->default_perms
);
944 extern "C" int ceph_readlinkat(struct ceph_mount_info
*cmount
, int dirfd
,
945 const char *relpath
, char *buf
, int64_t size
)
947 if (!cmount
->is_mounted())
948 return -CEPHFS_ENOTCONN
;
949 return cmount
->get_client()->readlinkat(dirfd
, relpath
, buf
, size
, cmount
->default_perms
);
952 extern "C" int ceph_symlink(struct ceph_mount_info
*cmount
, const char *existing
,
955 if (!cmount
->is_mounted())
956 return -CEPHFS_ENOTCONN
;
957 return cmount
->get_client()->symlink(existing
, newname
, cmount
->default_perms
);
960 extern "C" int ceph_symlinkat(struct ceph_mount_info
*cmount
, const char *existing
, int dirfd
,
963 if (!cmount
->is_mounted())
964 return -CEPHFS_ENOTCONN
;
965 return cmount
->get_client()->symlinkat(existing
, dirfd
, newname
, cmount
->default_perms
);
968 extern "C" int ceph_fstatx(struct ceph_mount_info
*cmount
, int fd
, struct ceph_statx
*stx
,
969 unsigned int want
, unsigned int flags
)
971 if (!cmount
->is_mounted())
972 return -CEPHFS_ENOTCONN
;
973 if (flags
& ~CEPH_REQ_FLAG_MASK
)
974 return -CEPHFS_EINVAL
;
975 return cmount
->get_client()->fstatx(fd
, stx
, cmount
->default_perms
,
979 extern "C" int ceph_statxat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
980 struct ceph_statx
*stx
, unsigned int want
, unsigned int flags
)
982 if (!cmount
->is_mounted())
983 return -CEPHFS_ENOTCONN
;
984 if (flags
& ~CEPH_REQ_FLAG_MASK
)
985 return -CEPHFS_EINVAL
;
986 return cmount
->get_client()->statxat(dirfd
, relpath
, stx
, cmount
->default_perms
,
990 extern "C" int ceph_statx(struct ceph_mount_info
*cmount
, const char *path
,
991 struct ceph_statx
*stx
, unsigned int want
, unsigned int flags
)
993 if (!cmount
->is_mounted())
994 return -CEPHFS_ENOTCONN
;
995 if (flags
& ~CEPH_REQ_FLAG_MASK
)
996 return -CEPHFS_EINVAL
;
997 return cmount
->get_client()->statx(path
, stx
, cmount
->default_perms
,
1001 extern "C" int ceph_fsetattrx(struct ceph_mount_info
*cmount
, int fd
,
1002 struct ceph_statx
*stx
, int mask
)
1004 if (!cmount
->is_mounted())
1005 return -CEPHFS_ENOTCONN
;
1006 return cmount
->get_client()->fsetattrx(fd
, stx
, mask
, cmount
->default_perms
);
1009 extern "C" int ceph_setattrx(struct ceph_mount_info
*cmount
, const char *relpath
,
1010 struct ceph_statx
*stx
, int mask
, int flags
)
1012 if (!cmount
->is_mounted())
1013 return -CEPHFS_ENOTCONN
;
1014 if (flags
& ~CEPH_REQ_FLAG_MASK
)
1015 return -CEPHFS_EINVAL
;
1016 return cmount
->get_client()->setattrx(relpath
, stx
, mask
,
1017 cmount
->default_perms
, flags
);
1020 // *xattr() calls supporting samba/vfs
1021 extern "C" int ceph_getxattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
, void *value
, size_t size
)
1023 if (!cmount
->is_mounted())
1024 return -CEPHFS_ENOTCONN
;
1026 return cmount
->get_client()->getxattr(path
, name
, value
, size
, cmount
->default_perms
);
1029 extern "C" int ceph_lgetxattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
, void *value
, size_t size
)
1031 if (!cmount
->is_mounted())
1032 return -CEPHFS_ENOTCONN
;
1033 return cmount
->get_client()->lgetxattr(path
, name
, value
, size
, cmount
->default_perms
);
1036 extern "C" int ceph_fgetxattr(struct ceph_mount_info
*cmount
, int fd
, const char *name
, void *value
, size_t size
)
1038 if (!cmount
->is_mounted())
1039 return -CEPHFS_ENOTCONN
;
1040 return cmount
->get_client()->fgetxattr(fd
, name
, value
, size
, cmount
->default_perms
);
1044 extern "C" int ceph_listxattr(struct ceph_mount_info
*cmount
, const char *path
, char *list
, size_t size
)
1046 if (!cmount
->is_mounted())
1047 return -CEPHFS_ENOTCONN
;
1048 return cmount
->get_client()->listxattr(path
, list
, size
, cmount
->default_perms
);
1051 extern "C" int ceph_llistxattr(struct ceph_mount_info
*cmount
, const char *path
, char *list
, size_t size
)
1053 if (!cmount
->is_mounted())
1054 return -CEPHFS_ENOTCONN
;
1055 return cmount
->get_client()->llistxattr(path
, list
, size
, cmount
->default_perms
);
1058 extern "C" int ceph_flistxattr(struct ceph_mount_info
*cmount
, int fd
, char *list
, size_t size
)
1060 if (!cmount
->is_mounted())
1061 return -CEPHFS_ENOTCONN
;
1062 return cmount
->get_client()->flistxattr(fd
, list
, size
, cmount
->default_perms
);
1065 extern "C" int ceph_removexattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
)
1067 if (!cmount
->is_mounted())
1068 return -CEPHFS_ENOTCONN
;
1069 return cmount
->get_client()->removexattr(path
, name
, cmount
->default_perms
);
1072 extern "C" int ceph_lremovexattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
)
1074 if (!cmount
->is_mounted())
1075 return -CEPHFS_ENOTCONN
;
1076 return cmount
->get_client()->lremovexattr(path
, name
, cmount
->default_perms
);
1079 extern "C" int ceph_fremovexattr(struct ceph_mount_info
*cmount
, int fd
, const char *name
)
1081 if (!cmount
->is_mounted())
1082 return -CEPHFS_ENOTCONN
;
1083 return cmount
->get_client()->fremovexattr(fd
, name
, cmount
->default_perms
);
1086 extern "C" int ceph_setxattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1088 if (!cmount
->is_mounted())
1089 return -CEPHFS_ENOTCONN
;
1090 return cmount
->get_client()->setxattr(path
, name
, value
, size
, flags
, cmount
->default_perms
);
1093 extern "C" int ceph_lsetxattr(struct ceph_mount_info
*cmount
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1095 if (!cmount
->is_mounted())
1096 return -CEPHFS_ENOTCONN
;
1097 return cmount
->get_client()->lsetxattr(path
, name
, value
, size
, flags
, cmount
->default_perms
);
1100 extern "C" int ceph_fsetxattr(struct ceph_mount_info
*cmount
, int fd
, const char *name
, const void *value
, size_t size
, int flags
)
1102 if (!cmount
->is_mounted())
1103 return -CEPHFS_ENOTCONN
;
1104 return cmount
->get_client()->fsetxattr(fd
, name
, value
, size
, flags
, cmount
->default_perms
);
1106 /* end xattr support */
1108 extern "C" int ceph_stat(struct ceph_mount_info
*cmount
, const char *path
, struct stat
*stbuf
)
1110 if (!cmount
->is_mounted())
1111 return -CEPHFS_ENOTCONN
;
1112 return cmount
->get_client()->stat(path
, stbuf
, cmount
->default_perms
);
1115 extern "C" int ceph_fstat(struct ceph_mount_info
*cmount
, int fd
, struct stat
*stbuf
)
1117 if (!cmount
->is_mounted())
1118 return -CEPHFS_ENOTCONN
;
1119 return cmount
->get_client()->fstat(fd
, stbuf
, cmount
->default_perms
);
1122 extern int ceph_lstat(struct ceph_mount_info
*cmount
, const char *path
, struct stat
*stbuf
)
1124 if (!cmount
->is_mounted())
1125 return -CEPHFS_ENOTCONN
;
1126 return cmount
->get_client()->lstat(path
, stbuf
, cmount
->default_perms
);
1129 extern "C" int ceph_chmod(struct ceph_mount_info
*cmount
, const char *path
, mode_t mode
)
1131 if (!cmount
->is_mounted())
1132 return -CEPHFS_ENOTCONN
;
1133 return cmount
->get_client()->chmod(path
, mode
, cmount
->default_perms
);
1135 extern "C" int ceph_lchmod(struct ceph_mount_info
*cmount
, const char *path
, mode_t mode
)
1137 if (!cmount
->is_mounted())
1138 return -CEPHFS_ENOTCONN
;
1139 return cmount
->get_client()->lchmod(path
, mode
, cmount
->default_perms
);
1141 extern "C" int ceph_fchmod(struct ceph_mount_info
*cmount
, int fd
, mode_t mode
)
1143 if (!cmount
->is_mounted())
1144 return -CEPHFS_ENOTCONN
;
1145 return cmount
->get_client()->fchmod(fd
, mode
, cmount
->default_perms
);
1148 extern "C" int ceph_chmodat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
1149 mode_t mode
, int flags
) {
1150 if (!cmount
->is_mounted())
1151 return -CEPHFS_ENOTCONN
;
1152 return cmount
->get_client()->chmodat(dirfd
, relpath
, mode
, flags
, cmount
->default_perms
);
1155 extern "C" int ceph_chown(struct ceph_mount_info
*cmount
, const char *path
,
1158 if (!cmount
->is_mounted())
1159 return -CEPHFS_ENOTCONN
;
1160 return cmount
->get_client()->chown(path
, uid
, gid
, cmount
->default_perms
);
1162 extern "C" int ceph_fchown(struct ceph_mount_info
*cmount
, int fd
,
1165 if (!cmount
->is_mounted())
1166 return -CEPHFS_ENOTCONN
;
1167 return cmount
->get_client()->fchown(fd
, uid
, gid
, cmount
->default_perms
);
1169 extern "C" int ceph_lchown(struct ceph_mount_info
*cmount
, const char *path
,
1172 if (!cmount
->is_mounted())
1173 return -CEPHFS_ENOTCONN
;
1174 return cmount
->get_client()->lchown(path
, uid
, gid
, cmount
->default_perms
);
1177 extern "C" int ceph_chownat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
1178 uid_t uid
, gid_t gid
, int flags
) {
1179 if (!cmount
->is_mounted())
1180 return -CEPHFS_ENOTCONN
;
1181 return cmount
->get_client()->chownat(dirfd
, relpath
, uid
, gid
, flags
, cmount
->default_perms
);
1184 extern "C" int ceph_utime(struct ceph_mount_info
*cmount
, const char *path
,
1185 struct utimbuf
*buf
)
1187 if (!cmount
->is_mounted())
1188 return -CEPHFS_ENOTCONN
;
1189 return cmount
->get_client()->utime(path
, buf
, cmount
->default_perms
);
1192 extern "C" int ceph_futime(struct ceph_mount_info
*cmount
, int fd
,
1193 struct utimbuf
*buf
)
1195 if (!cmount
->is_mounted())
1196 return -CEPHFS_ENOTCONN
;
1197 return cmount
->get_client()->futime(fd
, buf
, cmount
->default_perms
);
1200 extern "C" int ceph_utimes(struct ceph_mount_info
*cmount
, const char *path
,
1201 struct timeval times
[2])
1203 if (!cmount
->is_mounted())
1204 return -CEPHFS_ENOTCONN
;
1205 return cmount
->get_client()->utimes(path
, times
, cmount
->default_perms
);
1208 extern "C" int ceph_lutimes(struct ceph_mount_info
*cmount
, const char *path
,
1209 struct timeval times
[2])
1211 if (!cmount
->is_mounted())
1212 return -CEPHFS_ENOTCONN
;
1213 return cmount
->get_client()->lutimes(path
, times
, cmount
->default_perms
);
1216 extern "C" int ceph_futimes(struct ceph_mount_info
*cmount
, int fd
,
1217 struct timeval times
[2])
1219 if (!cmount
->is_mounted())
1220 return -CEPHFS_ENOTCONN
;
1221 return cmount
->get_client()->futimes(fd
, times
, cmount
->default_perms
);
1224 extern "C" int ceph_futimens(struct ceph_mount_info
*cmount
, int fd
,
1225 struct timespec times
[2])
1227 if (!cmount
->is_mounted())
1228 return -CEPHFS_ENOTCONN
;
1229 return cmount
->get_client()->futimens(fd
, times
, cmount
->default_perms
);
1232 extern "C" int ceph_utimensat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
1233 struct timespec times
[2], int flags
) {
1234 if (!cmount
->is_mounted())
1235 return -CEPHFS_ENOTCONN
;
1236 return cmount
->get_client()->utimensat(dirfd
, relpath
, times
, flags
, cmount
->default_perms
);
1239 extern "C" int ceph_flock(struct ceph_mount_info
*cmount
, int fd
, int operation
,
1242 if (!cmount
->is_mounted())
1243 return -CEPHFS_ENOTCONN
;
1244 return cmount
->get_client()->flock(fd
, operation
, owner
);
1247 extern "C" int ceph_truncate(struct ceph_mount_info
*cmount
, const char *path
,
1250 if (!cmount
->is_mounted())
1251 return -CEPHFS_ENOTCONN
;
1252 return cmount
->get_client()->truncate(path
, size
, cmount
->default_perms
);
1256 extern "C" int ceph_mknod(struct ceph_mount_info
*cmount
, const char *path
,
1257 mode_t mode
, dev_t rdev
)
1259 if (!cmount
->is_mounted())
1260 return -CEPHFS_ENOTCONN
;
1261 return cmount
->get_client()->mknod(path
, mode
, cmount
->default_perms
, rdev
);
1264 extern "C" int ceph_open(struct ceph_mount_info
*cmount
, const char *path
,
1265 int flags
, mode_t mode
)
1267 if (!cmount
->is_mounted())
1268 return -CEPHFS_ENOTCONN
;
1269 return cmount
->get_client()->open(path
, flags
, cmount
->default_perms
, mode
);
1272 extern "C" int ceph_openat(struct ceph_mount_info
*cmount
, int dirfd
, const char *relpath
,
1273 int flags
, mode_t mode
)
1275 if (!cmount
->is_mounted())
1276 return -CEPHFS_ENOTCONN
;
1277 return cmount
->get_client()->openat(dirfd
, relpath
, flags
, cmount
->default_perms
, mode
);
1280 extern "C" int ceph_open_layout(struct ceph_mount_info
*cmount
, const char *path
, int flags
,
1281 mode_t mode
, int stripe_unit
, int stripe_count
, int object_size
, const char *data_pool
)
1283 if (!cmount
->is_mounted())
1284 return -CEPHFS_ENOTCONN
;
1285 return cmount
->get_client()->open(path
, flags
, cmount
->default_perms
, mode
,
1286 stripe_unit
, stripe_count
,
1287 object_size
, data_pool
);
1290 extern "C" int ceph_close(struct ceph_mount_info
*cmount
, int fd
)
1292 if (!cmount
->is_mounted())
1293 return -CEPHFS_ENOTCONN
;
1294 return cmount
->get_client()->close(fd
);
1297 extern "C" int64_t ceph_lseek(struct ceph_mount_info
*cmount
, int fd
,
1298 int64_t offset
, int whence
)
1300 if (!cmount
->is_mounted())
1301 return -CEPHFS_ENOTCONN
;
1302 return cmount
->get_client()->lseek(fd
, offset
, whence
);
1305 extern "C" int ceph_read(struct ceph_mount_info
*cmount
, int fd
, char *buf
,
1306 int64_t size
, int64_t offset
)
1308 if (!cmount
->is_mounted())
1309 return -CEPHFS_ENOTCONN
;
1310 return cmount
->get_client()->read(fd
, buf
, size
, offset
);
1313 extern "C" int ceph_preadv(struct ceph_mount_info
*cmount
, int fd
,
1314 const struct iovec
*iov
, int iovcnt
, int64_t offset
)
1316 if (!cmount
->is_mounted())
1317 return -CEPHFS_ENOTCONN
;
1318 return cmount
->get_client()->preadv(fd
, iov
, iovcnt
, offset
);
1321 extern "C" int ceph_write(struct ceph_mount_info
*cmount
, int fd
, const char *buf
,
1322 int64_t size
, int64_t offset
)
1324 if (!cmount
->is_mounted())
1325 return -CEPHFS_ENOTCONN
;
1326 return cmount
->get_client()->write(fd
, buf
, size
, offset
);
1329 extern "C" int ceph_pwritev(struct ceph_mount_info
*cmount
, int fd
,
1330 const struct iovec
*iov
, int iovcnt
, int64_t offset
)
1332 if (!cmount
->is_mounted())
1333 return -CEPHFS_ENOTCONN
;
1334 return cmount
->get_client()->pwritev(fd
, iov
, iovcnt
, offset
);
1337 extern "C" int ceph_ftruncate(struct ceph_mount_info
*cmount
, int fd
, int64_t size
)
1339 if (!cmount
->is_mounted())
1340 return -CEPHFS_ENOTCONN
;
1341 return cmount
->get_client()->ftruncate(fd
, size
, cmount
->default_perms
);
1344 extern "C" int ceph_fsync(struct ceph_mount_info
*cmount
, int fd
, int syncdataonly
)
1346 if (!cmount
->is_mounted())
1347 return -CEPHFS_ENOTCONN
;
1348 return cmount
->get_client()->fsync(fd
, syncdataonly
);
1351 extern "C" int ceph_fallocate(struct ceph_mount_info
*cmount
, int fd
, int mode
,
1352 int64_t offset
, int64_t length
)
1354 if (!cmount
->is_mounted())
1355 return -CEPHFS_ENOTCONN
;
1356 return cmount
->get_client()->fallocate(fd
, mode
, offset
, length
);
1359 extern "C" int ceph_lazyio(class ceph_mount_info
*cmount
,
1362 return (cmount
->get_client()->lazyio(fd
, enable
));
1365 extern "C" int ceph_lazyio_propagate(class ceph_mount_info
*cmount
,
1366 int fd
, int64_t offset
, size_t count
)
1368 if (!cmount
->is_mounted())
1369 return -CEPHFS_ENOTCONN
;
1370 return (cmount
->get_client()->lazyio_propagate(fd
, offset
, count
));
1373 extern "C" int ceph_lazyio_synchronize(class ceph_mount_info
*cmount
,
1374 int fd
, int64_t offset
, size_t count
)
1376 if (!cmount
->is_mounted())
1377 return -CEPHFS_ENOTCONN
;
1378 return (cmount
->get_client()->lazyio_synchronize(fd
, offset
, count
));
1382 extern "C" int ceph_sync_fs(struct ceph_mount_info
*cmount
)
1384 if (!cmount
->is_mounted())
1385 return -CEPHFS_ENOTCONN
;
1386 return cmount
->get_client()->sync_fs();
1389 extern "C" int ceph_get_file_stripe_unit(struct ceph_mount_info
*cmount
, int fh
)
1394 if (!cmount
->is_mounted())
1395 return -CEPHFS_ENOTCONN
;
1396 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1399 return l
.stripe_unit
;
1402 extern "C" int ceph_get_path_stripe_unit(struct ceph_mount_info
*cmount
, const char *path
)
1407 if (!cmount
->is_mounted())
1408 return -CEPHFS_ENOTCONN
;
1409 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1412 return l
.stripe_unit
;
1415 extern "C" int ceph_get_file_stripe_count(struct ceph_mount_info
*cmount
, int fh
)
1420 if (!cmount
->is_mounted())
1421 return -CEPHFS_ENOTCONN
;
1422 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1425 return l
.stripe_count
;
1428 extern "C" int ceph_get_path_stripe_count(struct ceph_mount_info
*cmount
, const char *path
)
1433 if (!cmount
->is_mounted())
1434 return -CEPHFS_ENOTCONN
;
1435 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1438 return l
.stripe_count
;
1441 extern "C" int ceph_get_file_object_size(struct ceph_mount_info
*cmount
, int fh
)
1446 if (!cmount
->is_mounted())
1447 return -CEPHFS_ENOTCONN
;
1448 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1451 return l
.object_size
;
1454 extern "C" int ceph_get_path_object_size(struct ceph_mount_info
*cmount
, const char *path
)
1459 if (!cmount
->is_mounted())
1460 return -CEPHFS_ENOTCONN
;
1461 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1464 return l
.object_size
;
1467 extern "C" int ceph_get_file_pool(struct ceph_mount_info
*cmount
, int fh
)
1472 if (!cmount
->is_mounted())
1473 return -CEPHFS_ENOTCONN
;
1474 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1480 extern "C" int ceph_get_path_pool(struct ceph_mount_info
*cmount
, const char *path
)
1485 if (!cmount
->is_mounted())
1486 return -CEPHFS_ENOTCONN
;
1487 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1493 extern "C" int ceph_get_file_pool_name(struct ceph_mount_info
*cmount
, int fh
, char *buf
, size_t len
)
1498 if (!cmount
->is_mounted())
1499 return -CEPHFS_ENOTCONN
;
1500 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1503 string name
= cmount
->get_client()->get_pool_name(l
.pool_id
);
1505 return name
.length();
1506 if (name
.length() > len
)
1507 return -CEPHFS_ERANGE
;
1508 strncpy(buf
, name
.c_str(), len
);
1509 return name
.length();
1512 extern "C" int ceph_get_pool_name(struct ceph_mount_info
*cmount
, int pool
, char *buf
, size_t len
)
1514 if (!cmount
->is_mounted())
1515 return -CEPHFS_ENOTCONN
;
1516 string name
= cmount
->get_client()->get_pool_name(pool
);
1518 return name
.length();
1519 if (name
.length() > len
)
1520 return -CEPHFS_ERANGE
;
1521 strncpy(buf
, name
.c_str(), len
);
1522 return name
.length();
1525 extern "C" int ceph_get_path_pool_name(struct ceph_mount_info
*cmount
, const char *path
, char *buf
, size_t len
)
1530 if (!cmount
->is_mounted())
1531 return -CEPHFS_ENOTCONN
;
1532 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1535 string name
= cmount
->get_client()->get_pool_name(l
.pool_id
);
1537 return name
.length();
1538 if (name
.length() > len
)
1539 return -CEPHFS_ERANGE
;
1540 strncpy(buf
, name
.c_str(), len
);
1541 return name
.length();
1544 extern "C" int ceph_get_default_data_pool_name(struct ceph_mount_info
*cmount
, char *buf
, size_t len
)
1546 if (!cmount
->is_mounted())
1547 return -CEPHFS_ENOTCONN
;
1548 int64_t pool_id
= cmount
->get_client()->get_default_pool_id();
1550 string name
= cmount
->get_client()->get_pool_name(pool_id
);
1552 return name
.length();
1553 if (name
.length() > len
)
1554 return -CEPHFS_ERANGE
;
1555 strncpy(buf
, name
.c_str(), len
);
1556 return name
.length();
1559 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
)
1564 if (!cmount
->is_mounted())
1565 return -CEPHFS_ENOTCONN
;
1566 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1570 *stripe_unit
= l
.stripe_unit
;
1572 *stripe_count
= l
.stripe_count
;
1574 *object_size
= l
.object_size
;
1576 *pg_pool
= l
.pool_id
;
1580 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
)
1585 if (!cmount
->is_mounted())
1586 return -CEPHFS_ENOTCONN
;
1587 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1591 *stripe_unit
= l
.stripe_unit
;
1593 *stripe_count
= l
.stripe_count
;
1595 *object_size
= l
.object_size
;
1597 *pg_pool
= l
.pool_id
;
1601 extern "C" int ceph_get_file_replication(struct ceph_mount_info
*cmount
, int fh
)
1606 if (!cmount
->is_mounted())
1607 return -CEPHFS_ENOTCONN
;
1608 r
= cmount
->get_client()->fdescribe_layout(fh
, &l
);
1611 int rep
= cmount
->get_client()->get_pool_replication(l
.pool_id
);
1615 extern "C" int ceph_get_path_replication(struct ceph_mount_info
*cmount
, const char *path
)
1620 if (!cmount
->is_mounted())
1621 return -CEPHFS_ENOTCONN
;
1622 r
= cmount
->get_client()->describe_layout(path
, &l
, cmount
->default_perms
);
1625 int rep
= cmount
->get_client()->get_pool_replication(l
.pool_id
);
1629 extern "C" int ceph_set_default_file_stripe_unit(struct ceph_mount_info
*cmount
,
1632 // this option no longer exists
1633 return -CEPHFS_EOPNOTSUPP
;
1636 extern "C" int ceph_set_default_file_stripe_count(struct ceph_mount_info
*cmount
,
1639 // this option no longer exists
1640 return -CEPHFS_EOPNOTSUPP
;
1643 extern "C" int ceph_set_default_object_size(struct ceph_mount_info
*cmount
, int size
)
1645 // this option no longer exists
1646 return -CEPHFS_EOPNOTSUPP
;
1649 extern "C" int ceph_set_default_file_replication(struct ceph_mount_info
*cmount
,
1652 // this option no longer exists
1653 return -CEPHFS_EOPNOTSUPP
;
1656 extern "C" int ceph_set_default_preferred_pg(struct ceph_mount_info
*cmount
, int osd
)
1658 // this option no longer exists
1659 return -CEPHFS_EOPNOTSUPP
;
1662 extern "C" int ceph_get_file_extent_osds(struct ceph_mount_info
*cmount
, int fh
,
1663 int64_t offset
, int64_t *length
, int *osds
, int nosds
)
1666 return -CEPHFS_EINVAL
;
1668 if (!cmount
->is_mounted())
1669 return -CEPHFS_ENOTCONN
;
1672 int ret
= cmount
->get_client()->get_file_extent_osds(fh
, offset
, length
, vosds
);
1677 return vosds
.size();
1679 if ((int)vosds
.size() > nosds
)
1680 return -CEPHFS_ERANGE
;
1682 for (int i
= 0; i
< (int)vosds
.size(); i
++)
1685 return vosds
.size();
1688 extern "C" int ceph_get_osd_crush_location(struct ceph_mount_info
*cmount
,
1689 int osd
, char *path
, size_t len
)
1691 if (!cmount
->is_mounted())
1692 return -CEPHFS_ENOTCONN
;
1695 return -CEPHFS_EINVAL
;
1697 vector
<pair
<string
, string
> > loc
;
1698 int ret
= cmount
->get_client()->get_osd_crush_location(osd
, loc
);
1704 vector
<pair
<string
, string
> >::iterator it
;
1705 for (it
= loc
.begin(); it
!= loc
.end(); ++it
) {
1706 string
& type
= it
->first
;
1707 string
& name
= it
->second
;
1708 needed
+= type
.size() + name
.size() + 2;
1709 if (needed
<= len
) {
1711 strcpy(path
+ cur
, type
.c_str());
1712 cur
+= type
.size() + 1;
1714 strcpy(path
+ cur
, name
.c_str());
1715 cur
+= name
.size() + 1;
1723 return -CEPHFS_ERANGE
;
1728 extern "C" int ceph_get_osd_addr(struct ceph_mount_info
*cmount
, int osd
,
1729 struct sockaddr_storage
*addr
)
1731 if (!cmount
->is_mounted())
1732 return -CEPHFS_ENOTCONN
;
1735 return -CEPHFS_EINVAL
;
1737 entity_addr_t address
;
1738 int ret
= cmount
->get_client()->get_osd_addr(osd
, address
);
1742 *addr
= address
.get_sockaddr_storage();
1747 extern "C" int ceph_get_file_stripe_address(struct ceph_mount_info
*cmount
, int fh
,
1748 int64_t offset
, struct sockaddr_storage
*addr
, int naddr
)
1750 vector
<entity_addr_t
> address
;
1755 return -CEPHFS_EINVAL
;
1757 if (!cmount
->is_mounted())
1758 return -CEPHFS_ENOTCONN
;
1760 r
= cmount
->get_client()->get_file_stripe_address(fh
, offset
, address
);
1764 for (i
= 0; i
< (unsigned)naddr
&& i
< address
.size(); i
++)
1765 addr
[i
] = address
[i
].get_sockaddr_storage();
1767 /* naddr == 0: drop through and return actual size */
1768 if (naddr
&& (address
.size() > (unsigned)naddr
))
1769 return -CEPHFS_ERANGE
;
1771 return address
.size();
1774 extern "C" int ceph_localize_reads(struct ceph_mount_info
*cmount
, int val
)
1776 if (!cmount
->is_mounted())
1777 return -CEPHFS_ENOTCONN
;
1779 cmount
->get_client()->clear_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS
);
1781 cmount
->get_client()->set_filer_flags(CEPH_OSD_FLAG_LOCALIZE_READS
);
1785 extern "C" CephContext
*ceph_get_mount_context(struct ceph_mount_info
*cmount
)
1787 return cmount
->get_ceph_context();
1790 extern "C" int ceph_debug_get_fd_caps(struct ceph_mount_info
*cmount
, int fd
)
1792 if (!cmount
->is_mounted())
1793 return -CEPHFS_ENOTCONN
;
1794 return cmount
->get_client()->get_caps_issued(fd
);
1797 extern "C" int ceph_debug_get_file_caps(struct ceph_mount_info
*cmount
, const char *path
)
1799 if (!cmount
->is_mounted())
1800 return -CEPHFS_ENOTCONN
;
1801 return cmount
->get_client()->get_caps_issued(path
, cmount
->default_perms
);
1804 extern "C" int ceph_get_stripe_unit_granularity(struct ceph_mount_info
*cmount
)
1806 if (!cmount
->is_mounted())
1807 return -CEPHFS_ENOTCONN
;
1808 return CEPH_MIN_STRIPE_UNIT
;
1811 extern "C" int ceph_get_pool_id(struct ceph_mount_info
*cmount
, const char *pool_name
)
1813 if (!cmount
->is_mounted())
1814 return -CEPHFS_ENOTCONN
;
1816 if (!pool_name
|| !pool_name
[0])
1817 return -CEPHFS_EINVAL
;
1819 /* negative range reserved for errors */
1820 int64_t pool_id
= cmount
->get_client()->get_pool_id(pool_name
);
1821 if (pool_id
> 0x7fffffff)
1822 return -CEPHFS_ERANGE
;
1824 /* get_pool_id error codes fit in int */
1825 return (int)pool_id
;
1828 extern "C" int ceph_get_pool_replication(struct ceph_mount_info
*cmount
,
1831 if (!cmount
->is_mounted())
1832 return -CEPHFS_ENOTCONN
;
1833 return cmount
->get_client()->get_pool_replication(pool_id
);
1835 /* Low-level exports */
1837 extern "C" int ceph_ll_lookup_root(struct ceph_mount_info
*cmount
,
1840 *parent
= cmount
->get_client()->get_root();
1843 return -CEPHFS_EFAULT
;
1846 extern "C" struct Inode
*ceph_ll_get_inode(class ceph_mount_info
*cmount
,
1849 return (cmount
->get_client())->ll_get_inode(vino
);
1853 extern "C" int ceph_ll_lookup_vino(
1854 struct ceph_mount_info
*cmount
,
1858 return (cmount
->get_client())->ll_lookup_vino(vino
, cmount
->default_perms
, inode
);
1862 * Populates the client cache with the requested inode, and its
1865 extern "C" int ceph_ll_lookup_inode(
1866 struct ceph_mount_info
*cmount
,
1867 struct inodeno_t ino
,
1870 return (cmount
->get_client())->ll_lookup_inode(ino
, cmount
->default_perms
, inode
);
1873 extern "C" int ceph_ll_lookup(struct ceph_mount_info
*cmount
,
1874 Inode
*parent
, const char *name
, Inode
**out
,
1875 struct ceph_statx
*stx
, unsigned want
,
1876 unsigned flags
, const UserPerm
*perms
)
1878 if (flags
& ~CEPH_REQ_FLAG_MASK
)
1879 return -CEPHFS_EINVAL
;
1880 return (cmount
->get_client())->ll_lookupx(parent
, name
, out
, stx
, want
,
1884 extern "C" int ceph_ll_put(class ceph_mount_info
*cmount
, Inode
*in
)
1886 return (cmount
->get_client()->ll_put(in
));
1889 extern "C" int ceph_ll_forget(class ceph_mount_info
*cmount
, Inode
*in
,
1892 return (cmount
->get_client()->ll_forget(in
, count
));
1895 extern "C" int ceph_ll_walk(struct ceph_mount_info
*cmount
, const char* name
, Inode
**i
,
1896 struct ceph_statx
*stx
, unsigned int want
, unsigned int flags
,
1897 const UserPerm
*perms
)
1899 if (flags
& ~CEPH_REQ_FLAG_MASK
)
1900 return -CEPHFS_EINVAL
;
1901 return(cmount
->get_client()->ll_walk(name
, i
, stx
, want
, flags
, *perms
));
1904 extern "C" int ceph_ll_getattr(class ceph_mount_info
*cmount
,
1905 Inode
*in
, struct ceph_statx
*stx
,
1906 unsigned int want
, unsigned int flags
,
1907 const UserPerm
*perms
)
1909 if (flags
& ~CEPH_REQ_FLAG_MASK
)
1910 return -CEPHFS_EINVAL
;
1911 return (cmount
->get_client()->ll_getattrx(in
, stx
, want
, flags
, *perms
));
1914 extern "C" int ceph_ll_setattr(class ceph_mount_info
*cmount
,
1915 Inode
*in
, struct ceph_statx
*stx
,
1916 int mask
, const UserPerm
*perms
)
1918 return (cmount
->get_client()->ll_setattrx(in
, stx
, mask
, *perms
));
1921 extern "C" int ceph_ll_open(class ceph_mount_info
*cmount
, Inode
*in
,
1922 int flags
, Fh
**fh
, const UserPerm
*perms
)
1924 return (cmount
->get_client()->ll_open(in
, flags
, fh
, *perms
));
1927 extern "C" int ceph_ll_read(class ceph_mount_info
*cmount
, Fh
* filehandle
,
1928 int64_t off
, uint64_t len
, char* buf
)
1933 r
= cmount
->get_client()->ll_read(filehandle
, off
, len
, &bl
);
1936 bl
.begin().copy(bl
.length(), buf
);
1942 extern "C" int ceph_ll_read_block(class ceph_mount_info
*cmount
,
1943 Inode
*in
, uint64_t blockid
,
1944 char* buf
, uint64_t offset
,
1946 struct ceph_file_layout
* layout
)
1949 int r
= (cmount
->get_client()->ll_read_block(in
, blockid
, buf
, offset
,
1951 l
.to_legacy(layout
);
1955 extern "C" int ceph_ll_write_block(class ceph_mount_info
*cmount
,
1956 Inode
*in
, uint64_t blockid
,
1957 char *buf
, uint64_t offset
,
1959 struct ceph_file_layout
*layout
,
1960 uint64_t snapseq
, uint32_t sync
)
1963 int r
= (cmount
->get_client()->ll_write_block(in
, blockid
, buf
, offset
,
1964 length
, &l
, snapseq
, sync
));
1965 l
.to_legacy(layout
);
1969 extern "C" int ceph_ll_commit_blocks(class ceph_mount_info
*cmount
,
1970 Inode
*in
, uint64_t offset
,
1973 return (cmount
->get_client()->ll_commit_blocks(in
, offset
, range
));
1976 extern "C" int ceph_ll_fsync(class ceph_mount_info
*cmount
,
1977 Fh
*fh
, int syncdataonly
)
1979 return (cmount
->get_client()->ll_fsync(fh
, syncdataonly
));
1982 extern "C" int ceph_ll_sync_inode(class ceph_mount_info
*cmount
,
1983 Inode
*in
, int syncdataonly
)
1985 return (cmount
->get_client()->ll_sync_inode(in
, syncdataonly
));
1988 extern "C" int ceph_ll_fallocate(class ceph_mount_info
*cmount
, Fh
*fh
,
1989 int mode
, int64_t offset
, int64_t length
)
1991 return cmount
->get_client()->ll_fallocate(fh
, mode
, offset
, length
);
1994 extern "C" off_t
ceph_ll_lseek(class ceph_mount_info
*cmount
,
1995 Fh
*fh
, off_t offset
, int whence
)
1997 return (cmount
->get_client()->ll_lseek(fh
, offset
, whence
));
2000 extern "C" int ceph_ll_write(class ceph_mount_info
*cmount
,
2001 Fh
*fh
, int64_t off
, uint64_t len
,
2004 return (cmount
->get_client()->ll_write(fh
, off
, len
, data
));
2007 extern "C" int64_t ceph_ll_readv(class ceph_mount_info
*cmount
,
2008 struct Fh
*fh
, const struct iovec
*iov
,
2009 int iovcnt
, int64_t off
)
2011 return (cmount
->get_client()->ll_readv(fh
, iov
, iovcnt
, off
));
2014 extern "C" int64_t ceph_ll_writev(class ceph_mount_info
*cmount
,
2015 struct Fh
*fh
, const struct iovec
*iov
,
2016 int iovcnt
, int64_t off
)
2018 return (cmount
->get_client()->ll_writev(fh
, iov
, iovcnt
, off
));
2021 extern "C" int ceph_ll_close(class ceph_mount_info
*cmount
, Fh
* fh
)
2023 return (cmount
->get_client()->ll_release(fh
));
2026 extern "C" int ceph_ll_create(class ceph_mount_info
*cmount
,
2027 Inode
*parent
, const char *name
, mode_t mode
,
2028 int oflags
, Inode
**outp
, Fh
**fhp
,
2029 struct ceph_statx
*stx
, unsigned want
,
2030 unsigned lflags
, const UserPerm
*perms
)
2032 if (lflags
& ~CEPH_REQ_FLAG_MASK
)
2033 return -CEPHFS_EINVAL
;
2034 return (cmount
->get_client())->ll_createx(parent
, name
, mode
, oflags
, outp
,
2035 fhp
, stx
, want
, lflags
, *perms
);
2038 extern "C" int ceph_ll_mknod(class ceph_mount_info
*cmount
, Inode
*parent
,
2039 const char *name
, mode_t mode
, dev_t rdev
,
2040 Inode
**out
, struct ceph_statx
*stx
,
2041 unsigned want
, unsigned flags
,
2042 const UserPerm
*perms
)
2044 if (flags
& ~CEPH_REQ_FLAG_MASK
)
2045 return -CEPHFS_EINVAL
;
2046 return (cmount
->get_client())->ll_mknodx(parent
, name
, mode
, rdev
,
2047 out
, stx
, want
, flags
, *perms
);
2050 extern "C" int ceph_ll_mkdir(class ceph_mount_info
*cmount
, Inode
*parent
,
2051 const char *name
, mode_t mode
, Inode
**out
,
2052 struct ceph_statx
*stx
, unsigned want
,
2053 unsigned flags
, const UserPerm
*perms
)
2055 if (flags
& ~CEPH_REQ_FLAG_MASK
)
2056 return -CEPHFS_EINVAL
;
2057 return cmount
->get_client()->ll_mkdirx(parent
, name
, mode
, out
, stx
, want
,
2061 extern "C" int ceph_ll_link(class ceph_mount_info
*cmount
,
2062 Inode
*in
, Inode
*newparent
,
2063 const char *name
, const UserPerm
*perms
)
2065 return cmount
->get_client()->ll_link(in
, newparent
, name
, *perms
);
2068 extern "C" int ceph_ll_opendir(class ceph_mount_info
*cmount
,
2070 struct ceph_dir_result
**dirpp
,
2071 const UserPerm
*perms
)
2073 return (cmount
->get_client()->ll_opendir(in
, O_RDONLY
, (dir_result_t
**) dirpp
,
2077 extern "C" int ceph_ll_releasedir(class ceph_mount_info
*cmount
,
2078 ceph_dir_result
*dir
)
2080 return cmount
->get_client()->ll_releasedir(reinterpret_cast<dir_result_t
*>(dir
));
2083 extern "C" int ceph_ll_rename(class ceph_mount_info
*cmount
,
2084 Inode
*parent
, const char *name
,
2085 Inode
*newparent
, const char *newname
,
2086 const UserPerm
*perms
)
2088 return cmount
->get_client()->ll_rename(parent
, name
, newparent
,
2092 extern "C" int ceph_ll_unlink(class ceph_mount_info
*cmount
, Inode
*in
,
2093 const char *name
, const UserPerm
*perms
)
2095 return cmount
->get_client()->ll_unlink(in
, name
, *perms
);
2098 extern "C" int ceph_ll_statfs(class ceph_mount_info
*cmount
,
2099 Inode
*in
, struct statvfs
*stbuf
)
2101 return (cmount
->get_client()->ll_statfs(in
, stbuf
, cmount
->default_perms
));
2104 extern "C" int ceph_ll_readlink(class ceph_mount_info
*cmount
, Inode
*in
,
2105 char *buf
, size_t bufsiz
,
2106 const UserPerm
*perms
)
2108 return cmount
->get_client()->ll_readlink(in
, buf
, bufsiz
, *perms
);
2111 extern "C" int ceph_ll_symlink(class ceph_mount_info
*cmount
,
2112 Inode
*in
, const char *name
,
2113 const char *value
, Inode
**out
,
2114 struct ceph_statx
*stx
, unsigned want
,
2115 unsigned flags
, const UserPerm
*perms
)
2117 if (flags
& ~CEPH_REQ_FLAG_MASK
)
2118 return -CEPHFS_EINVAL
;
2119 return (cmount
->get_client()->ll_symlinkx(in
, name
, value
, out
, stx
, want
,
2123 extern "C" int ceph_ll_rmdir(class ceph_mount_info
*cmount
,
2124 Inode
*in
, const char *name
,
2125 const UserPerm
*perms
)
2127 return cmount
->get_client()->ll_rmdir(in
, name
, *perms
);
2130 extern "C" int ceph_ll_getxattr(class ceph_mount_info
*cmount
,
2131 Inode
*in
, const char *name
, void *value
,
2132 size_t size
, const UserPerm
*perms
)
2134 return (cmount
->get_client()->ll_getxattr(in
, name
, value
, size
, *perms
));
2137 extern "C" int ceph_ll_listxattr(struct ceph_mount_info
*cmount
,
2138 Inode
*in
, char *list
,
2139 size_t buf_size
, size_t *list_size
,
2140 const UserPerm
*perms
)
2142 int res
= cmount
->get_client()->ll_listxattr(in
, list
, buf_size
, *perms
);
2144 *list_size
= (size_t)res
;
2150 extern "C" int ceph_ll_setxattr(class ceph_mount_info
*cmount
,
2151 Inode
*in
, const char *name
,
2152 const void *value
, size_t size
,
2153 int flags
, const UserPerm
*perms
)
2155 return (cmount
->get_client()->ll_setxattr(in
, name
, value
, size
, flags
, *perms
));
2158 extern "C" int ceph_ll_removexattr(class ceph_mount_info
*cmount
,
2159 Inode
*in
, const char *name
,
2160 const UserPerm
*perms
)
2162 return (cmount
->get_client()->ll_removexattr(in
, name
, *perms
));
2165 extern "C" int ceph_ll_getlk(struct ceph_mount_info
*cmount
,
2166 Fh
*fh
, struct flock
*fl
, uint64_t owner
)
2168 return (cmount
->get_client()->ll_getlk(fh
, fl
, owner
));
2171 extern "C" int ceph_ll_setlk(struct ceph_mount_info
*cmount
,
2172 Fh
*fh
, struct flock
*fl
, uint64_t owner
,
2175 return (cmount
->get_client()->ll_setlk(fh
, fl
, owner
, sleep
));
2178 extern "C" int ceph_ll_lazyio(class ceph_mount_info
*cmount
,
2181 return (cmount
->get_client()->ll_lazyio(fh
, enable
));
2184 extern "C" int ceph_ll_delegation(struct ceph_mount_info
*cmount
, Fh
*fh
,
2185 unsigned cmd
, ceph_deleg_cb_t cb
, void *priv
)
2187 return (cmount
->get_client()->ll_delegation(fh
, cmd
, cb
, priv
));
2190 extern "C" uint32_t ceph_ll_stripe_unit(class ceph_mount_info
*cmount
,
2193 return (cmount
->get_client()->ll_stripe_unit(in
));
2196 extern "C" uint32_t ceph_ll_file_layout(class ceph_mount_info
*cmount
,
2198 struct ceph_file_layout
*layout
)
2201 int r
= (cmount
->get_client()->ll_file_layout(in
, &l
));
2202 l
.to_legacy(layout
);
2206 uint64_t ceph_ll_snap_seq(class ceph_mount_info
*cmount
, Inode
*in
)
2208 return (cmount
->get_client()->ll_snap_seq(in
));
2211 extern "C" int ceph_ll_get_stripe_osd(class ceph_mount_info
*cmount
,
2212 Inode
*in
, uint64_t blockno
,
2213 struct ceph_file_layout
* layout
)
2216 int r
= (cmount
->get_client()->ll_get_stripe_osd(in
, blockno
, &l
));
2217 l
.to_legacy(layout
);
2221 extern "C" int ceph_ll_num_osds(class ceph_mount_info
*cmount
)
2223 return (cmount
->get_client()->ll_num_osds());
2226 extern "C" int ceph_ll_osdaddr(class ceph_mount_info
*cmount
,
2227 int osd
, uint32_t *addr
)
2229 return (cmount
->get_client()->ll_osdaddr(osd
, addr
));
2232 extern "C" uint64_t ceph_ll_get_internal_offset(class ceph_mount_info
*cmount
,
2236 return (cmount
->get_client()->ll_get_internal_offset(in
, blockno
));
2239 extern "C" void ceph_buffer_free(char *buf
)
2246 extern "C" uint32_t ceph_get_cap_return_timeout(class ceph_mount_info
*cmount
)
2248 if (!cmount
->is_mounted())
2250 return cmount
->get_client()->mdsmap
->get_session_autoclose().sec();
2253 extern "C" int ceph_set_deleg_timeout(class ceph_mount_info
*cmount
, uint32_t timeout
)
2255 if (!cmount
->is_mounted())
2256 return -CEPHFS_ENOTCONN
;
2257 return cmount
->get_client()->set_deleg_timeout(timeout
);
2260 extern "C" void ceph_set_session_timeout(class ceph_mount_info
*cmount
, unsigned timeout
)
2262 cmount
->get_client()->set_session_timeout(timeout
);
2265 extern "C" void ceph_set_uuid(class ceph_mount_info
*cmount
, const char *uuid
)
2267 cmount
->get_client()->set_uuid(std::string(uuid
));
2270 extern "C" int ceph_start_reclaim(class ceph_mount_info
*cmount
,
2271 const char *uuid
, unsigned flags
)
2273 if (!cmount
->is_initialized()) {
2274 int ret
= cmount
->init();
2278 return cmount
->get_client()->start_reclaim(std::string(uuid
), flags
,
2279 cmount
->get_filesystem());
2282 extern "C" void ceph_finish_reclaim(class ceph_mount_info
*cmount
)
2284 cmount
->get_client()->finish_reclaim();
2287 // This is deprecated, use ceph_ll_register_callbacks2 instead.
2288 extern "C" void ceph_ll_register_callbacks(class ceph_mount_info
*cmount
,
2289 struct ceph_client_callback_args
*args
)
2291 cmount
->get_client()->ll_register_callbacks(args
);
2294 extern "C" int ceph_ll_register_callbacks2(class ceph_mount_info
*cmount
,
2295 struct ceph_client_callback_args
*args
)
2297 return cmount
->get_client()->ll_register_callbacks2(args
);
2301 extern "C" int ceph_get_snap_info(struct ceph_mount_info
*cmount
,
2302 const char *path
, struct snap_info
*snap_info
) {
2303 Client::SnapInfo info
;
2304 int r
= cmount
->get_client()->get_snap_info(path
, cmount
->default_perms
, &info
);
2310 auto nr_metadata
= info
.metadata
.size();
2312 snap_info
->id
= info
.id
.val
;
2313 snap_info
->nr_snap_metadata
= nr_metadata
;
2315 snap_info
->snap_metadata
= (struct snap_metadata
*)calloc(nr_metadata
, sizeof(struct snap_metadata
));
2316 if (!snap_info
->snap_metadata
) {
2317 return -CEPHFS_ENOMEM
;
2320 // fill with key, value pairs
2321 for (auto &[key
, value
] : info
.metadata
) {
2322 // len(key) + '\0' + len(value) + '\0'
2323 char *kvp
= (char *)malloc(key
.size() + value
.size() + 2);
2328 char *_value
= kvp
+ key
.size() + 1;
2330 memcpy(_key
, key
.c_str(), key
.size());
2331 _key
[key
.size()] = '\0';
2332 memcpy(_value
, value
.c_str(), value
.size());
2333 _value
[value
.size()] = '\0';
2335 snap_info
->snap_metadata
[i
].key
= _key
;
2336 snap_info
->snap_metadata
[i
].value
= _value
;
2341 if (nr_metadata
&& i
!= nr_metadata
) {
2342 ceph_free_snap_info_buffer(snap_info
);
2343 return -CEPHFS_ENOMEM
;
2349 extern "C" void ceph_free_snap_info_buffer(struct snap_info
*snap_info
) {
2350 for (size_t i
= 0; i
< snap_info
->nr_snap_metadata
; ++i
) {
2351 free((void *)snap_info
->snap_metadata
[i
].key
); // malloc'd memory is key+value composite
2353 free(snap_info
->snap_metadata
);