From 3361edd2f9a6e82853e685ba05022cc188210014 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 25 Oct 2016 08:53:48 -0400 Subject: [PATCH 01/31] client: fix new pg_files command to use ceph_statx Signed-off-by: Jeff Layton --- src/tools/cephfs/PgFiles.cc | 19 ++++++++++--------- src/tools/cephfs/PgFiles.h | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/tools/cephfs/PgFiles.cc b/src/tools/cephfs/PgFiles.cc index c581eb9ac509a..c027eafca75c4 100644 --- a/src/tools/cephfs/PgFiles.cc +++ b/src/tools/cephfs/PgFiles.cc @@ -69,9 +69,10 @@ void PgFiles::hit_dir(std::string const &path) continue; } - struct stat st; + struct ceph_statx stx; std::string de_path = (path + std::string("/") + de.d_name); - r = ceph_stat(cmount, de_path.c_str(), &st); + r = ceph_statx(cmount, de_path.c_str(), &stx, + CEPH_STATX_INO|CEPH_STATX_SIZE, 0); if (r != 0) { derr << "Failed to stat path " << de_path << ": " << cpp_strerror(r) << dendl; @@ -79,9 +80,9 @@ void PgFiles::hit_dir(std::string const &path) continue; } - if (S_ISREG(st.st_mode)) { - hit_file(de_path, st); - } else if (S_ISDIR(st.st_mode)) { + if (S_ISREG(stx.stx_mode)) { + hit_file(de_path, stx); + } else if (S_ISDIR(stx.stx_mode)) { hit_dir(de_path); } else { dout(20) << "Skipping non reg/dir file: " << de_path << dendl; @@ -95,9 +96,9 @@ void PgFiles::hit_dir(std::string const &path) } } -void PgFiles::hit_file(std::string const &path, struct stat const &st) +void PgFiles::hit_file(std::string const &path, const struct ceph_statx &stx) { - assert(S_ISREG(st.st_mode)); + assert(S_ISREG(stx.stx_mode)); dout(20) << "Hitting file '" << path << "'" << dendl; @@ -127,11 +128,11 @@ void PgFiles::hit_file(std::string const &path, struct stat const &st) return; } - auto num_objects = Striper::get_num_objects(layout, st.st_size); + auto num_objects = Striper::get_num_objects(layout, stx.stx_size); for (uint64_t i = 0; i < num_objects; ++i) { char buf[32]; - snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)st.st_ino, + snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)stx.stx_ino, (long long unsigned int)i); dout(20) << " object " << std::string(buf) << dendl; diff --git a/src/tools/cephfs/PgFiles.h b/src/tools/cephfs/PgFiles.h index 38337b6460b02..238da054065b2 100644 --- a/src/tools/cephfs/PgFiles.h +++ b/src/tools/cephfs/PgFiles.h @@ -35,7 +35,7 @@ class PgFiles std::set pgs; std::set pools; - void hit_file(std::string const &path, const struct stat &st); + void hit_file(std::string const &path, const struct ceph_statx &stx); void hit_dir(std::string const &path); From c18a4be5fb882c4d2c50b7c3bbb79c75d2621480 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 25 Oct 2016 09:14:20 -0400 Subject: [PATCH 02/31] client: add a ceph_fsetattrx ...and convert ceph_fsetattr callers to use it instead. Signed-off-by: Jeff Layton --- src/client/Client.cc | 17 +++++++++++++++++ src/client/Client.h | 1 + src/include/cephfs/libcephfs.h | 21 ++++++++++++++++----- src/libcephfs.cc | 8 ++++++++ src/test/libcephfs/test.cc | 13 ++++++------- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index a3194f23a8850..ee18d1caf687c 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6682,6 +6682,23 @@ int Client::fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms) return _setattr(f->inode, attr, mask, perms); } +int Client::fsetattrx(int fd, struct ceph_statx *stx, int mask, const UserPerm& perms) +{ + Mutex::Locker lock(client_lock); + tout(cct) << "fsetattr" << std::endl; + tout(cct) << fd << std::endl; + tout(cct) << mask << std::endl; + + Fh *f = get_filehandle(fd); + if (!f) + return -EBADF; +#if defined(__linux__) && defined(O_PATH) + if (f->flags & O_PATH) + return -EBADF; +#endif + return _setattrx(f->inode, stx, mask, perms); +} + int Client::stat(const char *relpath, struct stat *stbuf, const UserPerm& perms, frag_info_t *dirstat, int mask) { diff --git a/src/client/Client.h b/src/client/Client.h index d544e927558f2..2e2591710361f 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1007,6 +1007,7 @@ class Client : public Dispatcher, public md_config_obs_t { int setattrx(const char *relpath, struct ceph_statx *stx, int mask, const UserPerm& perms, int flags=0); int fsetattr(int fd, struct stat *attr, int mask, const UserPerm& perms); + int fsetattrx(int fd, struct ceph_statx *stx, int mask, const UserPerm& perms); int chmod(const char *path, mode_t mode, const UserPerm& perms); int fchmod(int fd, mode_t mode, const UserPerm& perms); int lchmod(const char *path, mode_t mode, const UserPerm& perms); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 09e9801ea35bd..ca8de2066bebd 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -655,6 +655,18 @@ int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *st */ int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath, struct stat *attr, int mask); +/** + * Set a file's attributes (extended version). + * + * @param cmount the ceph mount handle to use for performing the setattr. + * @param relpath the path to the file/directory to set the attributes of. + * @param stx the statx struct that must include attribute values to set on the file. + * @param mask a mask of all the CEPH_SETATTR_* values that have been set in the statx struct. + * @param flags mask of AT_* flags (only AT_ATTR_NOFOLLOW is respected for now) + * @returns 0 on success or negative error code on failure. + */ +int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, struct ceph_statx *stx, int mask, int flags); + /** * Set a file's attributes. * @@ -668,15 +680,14 @@ int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, struct stat *attr, int /** * Set a file's attributes (extended version). - * + * * @param cmount the ceph mount handle to use for performing the setattr. - * @param relpath the path to the file/directory to set the attributes of. + * @param fd the fd of the open file/directory to set the attributes of. * @param stx the statx struct that must include attribute values to set on the file. - * @param mask a mask of all the CEPH_SETATTR_* values that have been set in the statx struct. - * @param flags mask of AT_* flags (only AT_ATTR_NOFOLLOW is respected for now) + * @param mask a mask of all the stat values that have been set on the stat struct. * @returns 0 on success or negative error code on failure. */ -int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, struct ceph_statx *stx, int mask, int flags); +int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx, int mask); /** * Change the mode bits (permissions) of a file/directory. diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 40a7b50bda1dc..bf3d414063b98 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -649,6 +649,14 @@ extern "C" int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, return cmount->get_client()->fsetattr(fd, attr, mask, cmount->default_perms); } +extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd, + struct ceph_statx *stx, int mask) +{ + if (!cmount->is_mounted()) + return -ENOTCONN; + return cmount->get_client()->fsetattrx(fd, stx, mask, cmount->default_perms); +} + extern "C" int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, struct ceph_statx *stx, int mask, int flags) { diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 3fe62a790353c..919683f5724e0 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1158,6 +1158,7 @@ TEST(LibCephFS, UseUnmounted) { EXPECT_EQ(-ENOTCONN, ceph_setxattr(cmount, "/path", "name", NULL, 0, 0)); EXPECT_EQ(-ENOTCONN, ceph_lsetxattr(cmount, "/path", "name", NULL, 0, 0)); EXPECT_EQ(-ENOTCONN, ceph_fsetattr(cmount, 0, &st, 0)); + EXPECT_EQ(-ENOTCONN, ceph_fsetattrx(cmount, 0, &stx, 0)); EXPECT_EQ(-ENOTCONN, ceph_chmod(cmount, "/path", 0)); EXPECT_EQ(-ENOTCONN, ceph_fchmod(cmount, 0, 0)); EXPECT_EQ(-ENOTCONN, ceph_chown(cmount, "/path", 0, 0)); @@ -1685,14 +1686,12 @@ TEST(LibCephFS, SetSize) { int fd = ceph_open(cmount, filename, O_RDWR|O_CREAT|O_EXCL, 0666); ASSERT_LT(0, fd); - struct stat st; + struct ceph_statx stx; uint64_t size = 8388608; - st.st_size = (off_t)size; - ASSERT_EQ(ceph_fsetattr(cmount, fd, &st, CEPH_SETATTR_SIZE), 0); - - struct stat stbuf; - ASSERT_EQ(ceph_fstat(cmount, fd, &stbuf), 0); - ASSERT_EQ(stbuf.st_size, (off_t)size); + stx.stx_size = (off_t)size; + ASSERT_EQ(ceph_fsetattrx(cmount, fd, &stx, CEPH_SETATTR_SIZE), 0); + ASSERT_EQ(ceph_fstatx(cmount, fd, &stx, CEPH_STATX_SIZE, 0), 0); + ASSERT_EQ(stx.stx_size, (off_t)size); ceph_close(cmount, fd); ceph_shutdown(cmount); From ce8c6f3c9f9f35b7458ab95d9affc9ed4712d0eb Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:58 -0400 Subject: [PATCH 03/31] client: remove ceph_stat, ceph_lstat, ceph_fstat, ceph_setattr, and ceph_fsetattr ...there are no more callers. Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 53 ---------------------------------- src/libcephfs.cc | 40 ------------------------- src/test/libcephfs/test.cc | 1 - 3 files changed, 94 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index ca8de2066bebd..117e7368a254a 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -611,16 +611,6 @@ int ceph_unlink(struct ceph_mount_info *cmount, const char *path); */ int ceph_rename(struct ceph_mount_info *cmount, const char *from, const char *to); -/** - * Get a file's statistics and attributes. - * - * @param cmount the ceph mount handle to use for performing the stat. - * @param path the file or directory to get the statistics of. - * @param stbuf the stat struct that will be filled in with the file's statistics. - * @returns 0 on success or negative error code on failure. - */ -int ceph_stat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf); - /** * Get a file's extended statistics and attributes. * @@ -634,29 +624,8 @@ int ceph_stat(struct ceph_mount_info *cmount, const char *path, struct stat *stb int ceph_statx(struct ceph_mount_info *cmount, const char *path, struct ceph_statx *stx, unsigned int want, unsigned int flags); -/** - * Get a file's statistics and attributes, without following symlinks. - * - * @param cmount the ceph mount handle to use for performing the stat. - * @param path the file or directory to get the statistics of. - * @param stbuf the stat struct that will be filled in with the file's statistics. - * @returns 0 on success or negative error code on failure. - */ -int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf); - /** * Set a file's attributes. - * - * @param cmount the ceph mount handle to use for performing the setattr. - * @param relpath the path to the file/directory to set the attributes of. - * @param attr the stat struct that must include attribute values to set on the file. - * @param mask a mask of all the CEPH_SETATTR_* values that have been set in the stat struct. - * @returns 0 on success or negative error code on failure. - */ -int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath, struct stat *attr, int mask); - -/** - * Set a file's attributes (extended version). * * @param cmount the ceph mount handle to use for performing the setattr. * @param relpath the path to the file/directory to set the attributes of. @@ -667,17 +636,6 @@ int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath, struct sta */ int ceph_setattrx(struct ceph_mount_info *cmount, const char *relpath, struct ceph_statx *stx, int mask, int flags); -/** - * Set a file's attributes. - * - * @param cmount the ceph mount handle to use for performing the setattr. - * @param fd the fd of the open file/directory to set the attributes of. - * @param attr the stat struct that must include attribute values to set on the file. - * @param mask a mask of all the stat values that have been set on the stat struct. - * @returns 0 on success or negative error code on failure. - */ -int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, struct stat *attr, int mask); - /** * Set a file's attributes (extended version). * @@ -939,17 +897,6 @@ int ceph_fsync(struct ceph_mount_info *cmount, int fd, int syncdataonly); int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode, int64_t offset, int64_t length); -/** - * Get the open file's statistics. - * - * @param cmount the ceph mount handle to use for performing the fstat. - * @param fd the file descriptor of the file to get statistics of. - * @param stbuf the stat struct of the file's statistics, filled in by the - * function. - * @returns 0 on success or a negative error code on failure - */ -int ceph_fstat(struct ceph_mount_info *cmount, int fd, struct stat *stbuf); - /** * Get an open file's extended statistics and attributes. * diff --git a/src/libcephfs.cc b/src/libcephfs.cc index bf3d414063b98..f5e31c9ccbdd1 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -607,15 +607,6 @@ extern "C" int ceph_symlink(struct ceph_mount_info *cmount, const char *existing return cmount->get_client()->symlink(existing, newname, cmount->default_perms); } -// inode stuff -extern "C" int ceph_stat(struct ceph_mount_info *cmount, const char *path, - struct stat *stbuf) -{ - if (!cmount->is_mounted()) - return -ENOTCONN; - return cmount->get_client()->stat(path, stbuf, cmount->default_perms); -} - extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path, struct ceph_statx *stx, unsigned int want, unsigned int flags) { @@ -625,30 +616,6 @@ extern "C" int ceph_statx(struct ceph_mount_info *cmount, const char *path, want, flags); } -extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path, - struct stat *stbuf) -{ - if (!cmount->is_mounted()) - return -ENOTCONN; - return cmount->get_client()->lstat(path, stbuf, cmount->default_perms); -} - -extern "C" int ceph_setattr(struct ceph_mount_info *cmount, const char *relpath, - struct stat *attr, int mask) -{ - if (!cmount->is_mounted()) - return -ENOTCONN; - return cmount->get_client()->setattr(relpath, attr, mask, cmount->default_perms); -} - -extern "C" int ceph_fsetattr(struct ceph_mount_info *cmount, int fd, - struct stat *attr, int mask) -{ - if (!cmount->is_mounted()) - return -ENOTCONN; - return cmount->get_client()->fsetattr(fd, attr, mask, cmount->default_perms); -} - extern "C" int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx, int mask) { @@ -909,13 +876,6 @@ extern "C" int ceph_fallocate(struct ceph_mount_info *cmount, int fd, int mode, return cmount->get_client()->fallocate(fd, mode, offset, length); } -extern "C" int ceph_fstat(struct ceph_mount_info *cmount, int fd, struct stat *stbuf) -{ - if (!cmount->is_mounted()) - return -ENOTCONN; - return cmount->get_client()->fstat(fd, stbuf, cmount->default_perms); -} - extern "C" int ceph_fstatx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *stx, unsigned int want, unsigned int flags) { diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 919683f5724e0..2f36b40b174ea 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1157,7 +1157,6 @@ TEST(LibCephFS, UseUnmounted) { EXPECT_EQ(-ENOTCONN, ceph_lremovexattr(cmount, "/path", "name")); EXPECT_EQ(-ENOTCONN, ceph_setxattr(cmount, "/path", "name", NULL, 0, 0)); EXPECT_EQ(-ENOTCONN, ceph_lsetxattr(cmount, "/path", "name", NULL, 0, 0)); - EXPECT_EQ(-ENOTCONN, ceph_fsetattr(cmount, 0, &st, 0)); EXPECT_EQ(-ENOTCONN, ceph_fsetattrx(cmount, 0, &stx, 0)); EXPECT_EQ(-ENOTCONN, ceph_chmod(cmount, "/path", 0)); EXPECT_EQ(-ENOTCONN, ceph_fchmod(cmount, 0, 0)); From 6b65e86fb8b4c655f4e3a6404c91be08b34bfc82 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:58 -0400 Subject: [PATCH 04/31] client: allow UserPerm constructor to populate gid list Add args for the gids_count and gids list, and give them default values so that callers can populate it correctly. We'll need this for ganesha so it can populate the UserPerm from a RPC AUTH object. Note that the gidlist pointer must be valid for the lifetime of the created object! Signed-off-by: Jeff Layton --- src/client/UserPerm.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/UserPerm.h b/src/client/UserPerm.h index 9ce510412077d..1895c15c2d495 100644 --- a/src/client/UserPerm.h +++ b/src/client/UserPerm.h @@ -42,8 +42,9 @@ struct UserPerm public: UserPerm() : m_uid(-1), m_gid(-1), gid_count(0), gids(NULL), alloced_gids(false) {} - UserPerm(int uid, int gid) : m_uid(uid), m_gid(gid), gid_count(0), - gids(NULL), alloced_gids(false) {} + UserPerm(uid_t uid, gid_t gid, int ngids=0, gid_t *gidlist=NULL) : + m_uid(uid), m_gid(gid), gid_count(ngids), + gids(gidlist), alloced_gids(false) {} UserPerm(const UserPerm& o) : UserPerm() { deep_copy_from(o); } From 35cd1a78428a15ee7ce587e28c3c03e8df2b5568 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:58 -0400 Subject: [PATCH 05/31] client: add C bindings for UserPerm constructor and destructor Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 31 +++++++++++++++++++++++++++++++ src/libcephfs.cc | 11 +++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 117e7368a254a..f333937423e37 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -97,6 +97,9 @@ typedef struct vinodeno_t vinodeno; #endif /* ! __cplusplus */ +struct UserPerm; +typedef struct UserPerm UserPerm; + struct Inode; typedef struct Inode Inode; @@ -121,6 +124,34 @@ struct CephContext; # define CEPHFS_ERROR_NEW_CLIENT 1002 # define CEPHFS_ERROR_MESSENGER_START 1003 +/** + * Create a UserPerm credential object. + * + * Some calls (most notably, the ceph_ll_* ones), take a credential object + * that represents the credentials that the calling program is using. This + * function creates a new credential object for this purpose. Returns a + * pointer to the object, or NULL if it can't be allocated. + * + * Note that the gidlist array is used directly and is not copied. It must + * remain valid over the lifetime of the created UserPerm object. + * + * @param uid uid to be used + * @param gid gid to be used + * @param ngids number of gids in supplemental grouplist + * @param gidlist array of gid_t's in the list of groups + */ +UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids, gid_t *gidlist); + +/** + * Destroy a UserPerm credential object. + * + * @param perm pointer to object to be destroyed + * + * Currently this just frees the object. Note that the gidlist array is not + * freed. The caller must do so if it's necessary. + */ +void ceph_userperm_destroy(UserPerm *perm); + /** * @defgroup libcephfs_h_init Setup and Teardown * These are the first and last functions that should be called diff --git a/src/libcephfs.cc b/src/libcephfs.cc index f5e31c9ccbdd1..8b33968346c90 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -284,6 +284,17 @@ static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen) *outbuflen = outbl.length(); } +extern "C" UserPerm *ceph_userperm_new(uid_t uid, gid_t gid, int ngids, + gid_t *gidlist) +{ + return new (std::nothrow) UserPerm(uid, gid, ngids, gidlist); +} + +extern "C" void ceph_userperm_destroy(UserPerm *perm) +{ + delete perm; +} + extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch) { int major, minor, patch; From 266300d9e181b09d605ca0017532b6e86ff1263b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:58 -0400 Subject: [PATCH 06/31] client: add a C accessor for the ceph_mount_info default_perms Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 2 ++ src/libcephfs.cc | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index f333937423e37..f1974bfcf790a 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -231,6 +231,8 @@ int ceph_init(struct ceph_mount_info *cmount); int ceph_mount(struct ceph_mount_info *cmount, const char *root); +struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount); + /** * Execute a management command remotely on an MDS. * diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 8b33968346c90..6b3dca649c07c 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -452,6 +452,11 @@ extern "C" int ceph_is_mounted(struct ceph_mount_info *cmount) return cmount->is_mounted() ? 1 : 0; } +extern "C" struct UserPerm *ceph_mount_perms(struct ceph_mount_info *cmount) +{ + return &cmount->default_perms; +} + extern "C" int ceph_statfs(struct ceph_mount_info *cmount, const char *path, struct statvfs *stbuf) { From 7e2d03e9c5959b5319e8c46ba4dfb88796fc8f8b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 07/31] client: rename ceph_ll_getattrx to ceph_ll_getattr, and drop the original Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 4 +--- src/libcephfs.cc | 17 ++++------------- src/test/libcephfs/test.cc | 2 +- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index f1974bfcf790a..14d400337ece4 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1435,10 +1435,8 @@ int ceph_ll_walk(struct ceph_mount_info *cmount, const char *name, struct Inode **i, struct stat *attr); int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in, - struct stat *attr, int uid, int gid); -int ceph_ll_getattrx(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_statx *stx, unsigned int want, unsigned int flags, - int uid, int gid); + const UserPerm *perms); int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in, struct stat *st, int mask, int uid, int gid); int ceph_ll_setattrx(struct ceph_mount_info *cmount, struct Inode *in, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 6b3dca649c07c..1f9c92030bbde 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1430,20 +1430,11 @@ extern "C" int ceph_ll_walk(class ceph_mount_info *cmount, const char *name, } extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount, - Inode *in, struct stat *attr, - int uid, int gid) -{ - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_getattr(in, attr, perms)); -} - -extern "C" int ceph_ll_getattrx(class ceph_mount_info *cmount, - Inode *in, struct ceph_statx *stx, - unsigned int want, unsigned int flags, - int uid, int gid) + Inode *in, struct ceph_statx *stx, + unsigned int want, unsigned int flags, + const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_getattrx(in, stx, want, flags, perms)); + return (cmount->get_client()->ll_getattrx(in, stx, want, flags, *perms)); } extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 2f36b40b174ea..96a5607977ff8 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1581,7 +1581,7 @@ TEST(LibCephFS, LazyStatx) { ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0); struct ceph_statx stx; - ASSERT_EQ(ceph_ll_getattrx(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, getuid(), getgid()), 0); + ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, ceph_mount_perms(cmount2)), 0); ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME); ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec && stx.stx_ctime.tv_nsec == old_ctime.tv_nsec); From 63cf828f6ff70434eec735fb4f505c23473c221d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 08/31] client: switch arguments on ceph_ll_lookup to use ceph_statx and UserPerm For now, we leave the old ->ll_lookup method in place, as FUSE needs it. We could do a ceph_statx -> stat conversion, but that's extra copies and I don't think we want the perf hit in FUSE. Signed-off-by: Jeff Layton --- src/client/Client.cc | 37 ++++++++++++++++++++++++++++++++++ src/client/Client.h | 3 +++ src/client/SyntheticClient.cc | 15 +++++++------- src/include/cephfs/libcephfs.h | 6 +++--- src/libcephfs.cc | 12 +++++------ src/test/libcephfs/test.cc | 23 ++++++++++++++------- 6 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index ee18d1caf687c..45262c89a9df1 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -9786,6 +9786,43 @@ int Client::ll_lookup(Inode *parent, const char *name, struct stat *attr, return r; } +int Client::ll_lookupx(Inode *parent, const char *name, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm& perms) +{ + Mutex::Locker lock(client_lock); + ldout(cct, 3) << "ll_lookupx " << parent << " " << name << dendl; + tout(cct) << "ll_lookupx" << std::endl; + tout(cct) << name << std::endl; + + int r = 0; + if (!cct->_conf->fuse_default_permissions) { + r = may_lookup(parent, perms); + if (r < 0) + return r; + } + + string dname(name); + InodeRef in; + + unsigned mask = statx_to_mask(flags, want); + r = _lookup(parent, dname, mask, &in, perms); + if (r < 0) { + stx->stx_ino = 0; + stx->stx_mask = 0; + } else { + assert(in); + fill_statx(in, mask, stx); + _ll_get(in.get()); + } + + ldout(cct, 3) << "ll_lookupx " << parent << " " << name + << " -> " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl; + tout(cct) << stx->stx_ino << std::endl; + *out = in.get(); + return r; +} + int Client::ll_walk(const char* name, Inode **out, struct stat *attr, const UserPerm& perms) { diff --git a/src/client/Client.h b/src/client/Client.h index 2e2591710361f..d4769cc764410 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1114,6 +1114,9 @@ class Client : public Dispatcher, public md_config_obs_t { Inode *ll_get_inode(vinodeno_t vino); int ll_lookup(Inode *parent, const char *name, struct stat *attr, Inode **out, const UserPerm& perms); + int ll_lookupx(Inode *parent, const char *name, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm& perms); bool ll_forget(Inode *in, int count); bool ll_put(Inode *in); int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms); diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc index 0a48d2680cff4..9c44d7a334b04 100644 --- a/src/client/SyntheticClient.cc +++ b/src/client/SyntheticClient.cc @@ -37,6 +37,7 @@ using namespace std; #include "common/errno.h" #include "include/assert.h" +#include "include/cephfs/ceph_statx.h" #define dout_subsys ceph_subsys_client #undef dout_prefix @@ -1023,11 +1024,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) const char *p = prefix.c_str(); if (prefix.length()) { client->mkdir(prefix.c_str(), 0755, perms); - struct stat attr; + struct ceph_statx stx; i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP)); - if (client->ll_lookup(i1, prefix.c_str(), &attr, &i2, perms) == 0) { - ll_inos[1] = attr.st_ino; - dout(5) << "'root' ino is " << inodeno_t(attr.st_ino) << dendl; + if (client->ll_lookupx(i1, prefix.c_str(), &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) { + ll_inos[1] = stx.stx_ino; + dout(5) << "'root' ino is " << inodeno_t(stx.stx_ino) << dendl; client->ll_put(i1); } else { dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl; @@ -1227,11 +1228,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) int64_t i = t.get_int(); const char *name = t.get_string(buf, p); int64_t r = t.get_int(); - struct stat attr; + struct ceph_statx stx; if (ll_inos.count(i)) { i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_lookup(i1, name, &attr, &i2, perms) == 0) - ll_inos[r] = attr.st_ino; + if (client->ll_lookupx(i1, name, &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) + ll_inos[r] = stx.stx_ino; client->ll_put(i1); } } else if (strcmp(op, "ll_forget") == 0) { diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 14d400337ece4..c1b24c8a98d2c 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1425,9 +1425,9 @@ int ceph_ll_lookup_inode( */ int ceph_ll_lookup_root(struct ceph_mount_info *cmount, Inode **parent); -int ceph_ll_lookup(struct ceph_mount_info *cmount, struct Inode *parent, - const char *name, struct stat *attr, - Inode **out, int uid, int gid); +int ceph_ll_lookup(struct ceph_mount_info *cmount, Inode *parent, + const char *name, Inode **out, struct ceph_statx *stx, + unsigned want, unsigned flags, const UserPerm *perms); int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in); int ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in, int count); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 1f9c92030bbde..ffcdb7ba856bd 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1402,13 +1402,13 @@ extern "C" int ceph_ll_lookup_inode( return 0; } -extern "C" int ceph_ll_lookup(class ceph_mount_info *cmount, - struct Inode *parent, const char *name, - struct stat *attr, Inode **out, - int uid, int gid) +extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount, + Inode *parent, const char *name, Inode **out, + struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client())->ll_lookup(parent, name, attr, out, perms); + return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want, + flags, *perms); } extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in) diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 96a5607977ff8..c2621f08f4689 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -568,11 +568,15 @@ TEST(LibCephFS, Xattrs_ll) { Inode *root = NULL; Inode *existent_file_handle = NULL; - struct stat attr; int res = ceph_ll_lookup_root(cmount, &root); ASSERT_EQ(res, 0); - res = ceph_ll_lookup(cmount, root, test_xattr_file, &attr, &existent_file_handle, 0, 0); + + UserPerm *perms = ceph_mount_perms(cmount); + struct ceph_statx stx; + + res = ceph_ll_lookup(cmount, root, test_xattr_file, &existent_file_handle, + &stx, 0, 0, perms); ASSERT_EQ(res, 0); const char *valid_name = "user.attrname"; @@ -1393,7 +1397,9 @@ TEST(LibCephFS, Nlink) { sprintf(linkname, "nlinklink%x", getpid()); struct stat st; + struct ceph_statx stx; Fh *fh; + UserPerm *perms = ceph_mount_perms(cmount); ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &st, &dir, getuid(), getgid()), 0); ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL, @@ -1404,7 +1410,8 @@ TEST(LibCephFS, Nlink) { ASSERT_EQ(st.st_nlink, (nlink_t)2); ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0); - ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &st, &file, getuid(), getgid()), 0); + ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx, + CEPH_STATX_NLINK, 0, perms), 0); ASSERT_EQ(st.st_nlink, (nlink_t)1); ceph_shutdown(cmount); @@ -1559,6 +1566,7 @@ TEST(LibCephFS, LazyStatx) { Inode *root1, *file1, *root2, *file2; struct stat st; + struct ceph_statx stx; Fh *fh; ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0); @@ -1568,9 +1576,11 @@ TEST(LibCephFS, LazyStatx) { ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0); - ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &st, &file2, getuid(), getgid()), 0); - struct timespec old_ctime = st.st_ctim; + UserPerm *perms = ceph_mount_perms(cmount2); + ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &file2, &stx, CEPH_STATX_CTIME, 0, perms), 0); + + struct timespec old_ctime = stx.stx_ctime; /* * Now sleep, do a chmod on the first client and the see whether we get a @@ -1580,8 +1590,7 @@ TEST(LibCephFS, LazyStatx) { st.st_mode = 0644; ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0); - struct ceph_statx stx; - ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, ceph_mount_perms(cmount2)), 0); + ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms), 0); ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME); ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec && stx.stx_ctime.tv_nsec == old_ctime.tv_nsec); From 0a19ec57c9c45a5f6ebb0595ba16c605f6f7b4e1 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 09/31] client: convert ceph_ll_walk to use ceph_statx In addition to acquiring the right caps for the requested attributes, we can also do a path walk that terminates on an existing symlink without following the link now. Is that useful? No idea... Signed-off-by: Jeff Layton --- src/client/Client.cc | 14 ++++++++------ src/client/Client.h | 4 ++-- src/include/cephfs/libcephfs.h | 6 +++--- src/libcephfs.cc | 8 ++++---- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 45262c89a9df1..969113a9aa192 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -9823,32 +9823,34 @@ int Client::ll_lookupx(Inode *parent, const char *name, Inode **out, return r; } -int Client::ll_walk(const char* name, Inode **out, struct stat *attr, - const UserPerm& perms) +int Client::ll_walk(const char* name, Inode **out, struct ceph_statx *stx, + unsigned int want, unsigned int flags, const UserPerm& perms) { Mutex::Locker lock(client_lock); filepath fp(name, 0); InodeRef in; int rc; + unsigned mask = statx_to_mask(flags, want); ldout(cct, 3) << "ll_walk" << name << dendl; tout(cct) << "ll_walk" << std::endl; tout(cct) << name << std::endl; - rc = path_walk(fp, &in, perms, false, CEPH_STAT_CAP_INODE_ALL); + rc = path_walk(fp, &in, perms, !(flags & AT_SYMLINK_NOFOLLOW), mask); if (rc < 0) { - attr->st_ino = 0; + /* zero out mask, just in case... */ + stx->stx_mask = 0; + stx->stx_ino = 0; *out = NULL; return rc; } else { assert(in); - fill_stat(in, attr); + fill_statx(in, mask, stx); *out = in.get(); return 0; } } - void Client::_ll_get(Inode *in) { if (in->ll_ref == 0) { diff --git a/src/client/Client.h b/src/client/Client.h index d4769cc764410..d2b4755baba1c 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1163,8 +1163,8 @@ class Client : public Dispatcher, public md_config_obs_t { int ll_commit_blocks(Inode *in, uint64_t offset, uint64_t length); int ll_statfs(Inode *in, struct statvfs *stbuf, const UserPerm& perms); - int ll_walk(const char* name, Inode **i, struct stat *attr, - const UserPerm& perms); // XXX in? + int ll_walk(const char* name, Inode **i, struct ceph_statx *stx, + unsigned int want, unsigned int flags, const UserPerm& perms); uint32_t ll_stripe_unit(Inode *in); int ll_file_layout(Inode *in, file_layout_t *layout); uint64_t ll_snap_seq(Inode *in); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index c1b24c8a98d2c..e49d888918074 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1431,9 +1431,9 @@ int ceph_ll_lookup(struct ceph_mount_info *cmount, Inode *parent, int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in); int ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in, int count); -int ceph_ll_walk(struct ceph_mount_info *cmount, const char *name, - struct Inode **i, - struct stat *attr); +int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i, + struct ceph_statx *stx, unsigned int want, unsigned int flags, + const UserPerm *perms); int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_statx *stx, unsigned int want, unsigned int flags, const UserPerm *perms); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index ffcdb7ba856bd..92db1c25005d1 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1422,11 +1422,11 @@ extern "C" int ceph_ll_forget(class ceph_mount_info *cmount, Inode *in, return (cmount->get_client()->ll_forget(in, count)); } -extern "C" int ceph_ll_walk(class ceph_mount_info *cmount, const char *name, - struct Inode **i, - struct stat *attr) +int ceph_ll_walk(struct ceph_mount_info *cmount, const char* name, Inode **i, + struct ceph_statx *stx, unsigned int want, unsigned int flags, + const UserPerm *perms) { - return (cmount->get_client()->ll_walk(name, i, attr, cmount->default_perms)); + return(cmount->get_client()->ll_walk(name, i, stx, want, flags, *perms)); } extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount, From a302d194133f320fa462e56b614e5fae6598d347 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 10/31] ceph: fix arguments to ceph_ll_setattr and remove ceph_ll_setattrx Again, for now we leave the underlying method called ll_setattrx, since FUSE is wired to use struct stat. Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 4 +--- src/libcephfs.cc | 19 +++++-------------- src/test/libcephfs/test.cc | 11 ++++++----- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index e49d888918074..18c9a8e16a781 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1438,9 +1438,7 @@ int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_statx *stx, unsigned int want, unsigned int flags, const UserPerm *perms); int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in, - struct stat *st, int mask, int uid, int gid); -int ceph_ll_setattrx(struct ceph_mount_info *cmount, struct Inode *in, - struct ceph_statx *stx, int mask, int uid, int gid); + struct ceph_statx *stx, int mask, const UserPerm *perms); int ceph_ll_open(struct ceph_mount_info *cmount, struct Inode *in, int flags, struct Fh **fh, int uid, int gid); off_t ceph_ll_lseek(struct ceph_mount_info *cmount, struct Fh* filehandle, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 92db1c25005d1..e867bc7c5df5e 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1438,19 +1438,10 @@ extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount, } extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount, - Inode *in, struct stat *st, - int mask, int uid, int gid) -{ - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_setattr(in, st, mask, perms)); -} - -extern "C" int ceph_ll_setattrx(class ceph_mount_info *cmount, Inode *in, struct ceph_statx *stx, - int mask, int uid, int gid) + int mask, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_setattrx(in, stx, mask, perms)); + return (cmount->get_client()->ll_setattrx(in, stx, mask, *perms)); } extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in, @@ -1589,11 +1580,11 @@ extern "C" int ceph_ll_truncate(class ceph_mount_info *cmount, Inode *in, uint64_t length, int uid, int gid) { - struct stat st; - st.st_size=length; + struct ceph_statx stx; + stx.stx_size = length; UserPerm perms(uid, gid); - return(cmount->get_client()->ll_setattr(in, &st, CEPH_SETATTR_SIZE, perms)); + return(cmount->get_client()->ll_setattrx(in, &stx, CEPH_SETATTR_SIZE, perms)); } extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index c2621f08f4689..e3888819c9a3d 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1568,6 +1568,8 @@ TEST(LibCephFS, LazyStatx) { struct stat st; struct ceph_statx stx; Fh *fh; + UserPerm *perms1 = ceph_mount_perms(cmount1); + UserPerm *perms2 = ceph_mount_perms(cmount2); ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0); ceph_ll_unlink(cmount1, root1, filename, getuid(), getgid()); @@ -1577,8 +1579,7 @@ TEST(LibCephFS, LazyStatx) { ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0); - UserPerm *perms = ceph_mount_perms(cmount2); - ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &file2, &stx, CEPH_STATX_CTIME, 0, perms), 0); + ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &file2, &stx, CEPH_STATX_CTIME, 0, perms2), 0); struct timespec old_ctime = stx.stx_ctime; @@ -1587,10 +1588,10 @@ TEST(LibCephFS, LazyStatx) { * different ctime with a statx that uses AT_NO_ATTR_SYNC */ sleep(1); - st.st_mode = 0644; - ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0); + stx.stx_mode = 0644; + ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &stx, CEPH_SETATTR_MODE, perms1), 0); - ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms), 0); + ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms2), 0); ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME); ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec && stx.stx_ctime.tv_nsec == old_ctime.tv_nsec); From b6c2faeabbe16993e5e4e51534cf3f2136a707ac Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 11/31] client: remove ceph_ll_truncate It's just a wrapper around ceph_ll_setattr that is only called from the ganesha SETATTR handler. There's no need for special casing truncate handling. Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 2 -- src/libcephfs.cc | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 18c9a8e16a781..3c6334c35e4a4 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1491,8 +1491,6 @@ int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent, int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in, struct Inode *newparrent, const char *name, struct stat *attr, int uid, int gid); -int ceph_ll_truncate(struct ceph_mount_info *cmount, struct Inode *in, - uint64_t length, int uid, int gid); int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_dir_result **dirpp, int uid, int gid); int ceph_ll_releasedir(struct ceph_mount_info *cmount, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index e867bc7c5df5e..0a3fbb2909105 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1576,17 +1576,6 @@ extern "C" int ceph_ll_link(class ceph_mount_info *cmount, return (cmount->get_client()->ll_link(in, newparent, name, attr, perms)); } -extern "C" int ceph_ll_truncate(class ceph_mount_info *cmount, - Inode *in, uint64_t length, int uid, - int gid) -{ - struct ceph_statx stx; - stx.stx_size = length; - UserPerm perms(uid, gid); - - return(cmount->get_client()->ll_setattrx(in, &stx, CEPH_SETATTR_SIZE, perms)); -} - extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount, Inode *in, struct ceph_dir_result **dirpp, From 22ca8a5a79173b78f0bef1e3afa34e7518b69576 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 12/31] client: convert ceph_ll_open to take a UserPerm pointer Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 2 +- src/libcephfs.cc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 3c6334c35e4a4..1401371ce4c2d 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1440,7 +1440,7 @@ int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in, int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_statx *stx, int mask, const UserPerm *perms); int ceph_ll_open(struct ceph_mount_info *cmount, struct Inode *in, int flags, - struct Fh **fh, int uid, int gid); + struct Fh **fh, const UserPerm *perms); off_t ceph_ll_lseek(struct ceph_mount_info *cmount, struct Fh* filehandle, off_t offset, int whence); int ceph_ll_read(struct ceph_mount_info *cmount, struct Fh* filehandle, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 0a3fbb2909105..5b880aa2ef34e 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1445,10 +1445,9 @@ extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount, } extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in, - int flags, Fh **fh, int uid, int gid) + int flags, Fh **fh, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_open(in, flags, fh, perms)); + return (cmount->get_client()->ll_open(in, flags, fh, *perms)); } extern "C" int ceph_ll_read(class ceph_mount_info *cmount, Fh* filehandle, From 1f5af30b2bda0f8185137e072defb9c326b0397b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 13/31] client: convert ceph_ll_getxattr to take a UserPerm pointer Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 7 +++---- src/libcephfs.cc | 6 +++--- src/test/libcephfs/test.cc | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 1401371ce4c2d..eb88915dad0e8 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1463,13 +1463,12 @@ int ceph_ll_iclose(struct ceph_mount_info *cmount, struct Inode *in, int mode); * @param name name of attribute * @param value pointer to begin buffer * @param size buffer size - * @param uid user ID - * @param gid group ID + * @param perms pointer to UserPerms object * @returns size of returned buffer. Negative number in error case */ int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in, - const char *name, void *value, size_t size, int uid, - int gid); + const char *name, void *value, size_t size, + const UserPerm *perms); int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in, const char *name, const void *value, size_t size, int flags, int uid, int gid); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 5b880aa2ef34e..5dca674ff291f 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1643,11 +1643,11 @@ extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount, extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount, Inode *in, const char *name, void *value, - size_t size, int uid, int gid) + size_t size, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_getxattr(in, name, value, size, perms)); + return (cmount->get_client()->ll_getxattr(in, name, value, size, *perms)); } + extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount, Inode *in, char *list, size_t buf_size, size_t *list_size, int uid, int gid) diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index e3888819c9a3d..810c03060cdf9 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -586,7 +586,7 @@ TEST(LibCephFS, Xattrs_ll) { res = ceph_ll_setxattr(cmount, existent_file_handle, valid_name, value, strlen(value), 0, 0, 0); ASSERT_EQ(res, 0); - res = ceph_ll_getxattr(cmount, existent_file_handle, valid_name, value_buf, 256, 0, 0); + res = ceph_ll_getxattr(cmount, existent_file_handle, valid_name, value_buf, 256, perms); ASSERT_EQ(res, (int)strlen(value)); value_buf[res] = '\0'; From 775900e9b362e00bdac2399452cf6688ecdb7f9c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 14/31] client: convert ceph_ll_setxattr, listxattr, removexattr to take a UserPerms pointer Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 7 ++++--- src/libcephfs.cc | 16 +++++++--------- src/test/libcephfs/test.cc | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index eb88915dad0e8..8bb8baf6f3d8b 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1471,11 +1471,12 @@ int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in, const UserPerm *perms); int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in, const char *name, const void *value, size_t size, - int flags, int uid, int gid); + int flags, const UserPerm *perms); int ceph_ll_listxattr(struct ceph_mount_info *cmount, struct Inode *in, - char *list, size_t buf_size, size_t *list_size, int uid, int gid); + char *list, size_t buf_size, size_t *list_size, + const UserPerm *perms); int ceph_ll_removexattr(struct ceph_mount_info *cmount, struct Inode *in, - const char *name, int uid, int gid); + const char *name, const UserPerm *perms); int ceph_ll_create(struct ceph_mount_info *cmount, struct Inode *parent, const char *name, mode_t mode, int flags, struct stat *attr, struct Inode **out, Fh **fhp, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 5dca674ff291f..ca5415aae213a 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1650,10 +1650,10 @@ extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount, extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount, Inode *in, char *list, - size_t buf_size, size_t *list_size, int uid, int gid) + size_t buf_size, size_t *list_size, + const UserPerm *perms) { - UserPerm perms(uid, gid); - int res = cmount->get_client()->ll_listxattr(in, list, buf_size, perms); + int res = cmount->get_client()->ll_listxattr(in, list, buf_size, *perms); if (res >= 0) { *list_size = (size_t)res; return 0; @@ -1664,18 +1664,16 @@ extern "C" int ceph_ll_listxattr(struct ceph_mount_info *cmount, extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount, Inode *in, const char *name, const void *value, size_t size, - int flags, int uid, int gid) + int flags, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, perms)); + return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, *perms)); } extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount, Inode *in, const char *name, - int uid, int gid) + const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_removexattr(in, name, perms)); + return (cmount->get_client()->ll_removexattr(in, name, *perms)); } extern "C" int ceph_ll_getlk(struct ceph_mount_info *cmount, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 810c03060cdf9..0f37fe7c2e82b 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -583,7 +583,7 @@ TEST(LibCephFS, Xattrs_ll) { const char *value = "attrvalue"; char value_buf[256] = { 0 }; - res = ceph_ll_setxattr(cmount, existent_file_handle, valid_name, value, strlen(value), 0, 0, 0); + res = ceph_ll_setxattr(cmount, existent_file_handle, valid_name, value, strlen(value), 0, perms); ASSERT_EQ(res, 0); res = ceph_ll_getxattr(cmount, existent_file_handle, valid_name, value_buf, 256, perms); From bf5c3d13e480a8fb19c41172cbae6ea776687156 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 15/31] client: abstract out the guts of ll_create into _ll_create Make a common function that can be called and move the handling of the out inode reference and attribute handling into the caller. Signed-off-by: Jeff Layton --- src/client/Client.cc | 67 +++++++++++++++++++++++++++++--------------- src/client/Client.h | 3 ++ 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 969113a9aa192..6f4c2b1dd738a 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11670,17 +11670,15 @@ int Client::ll_open(Inode *in, int flags, Fh **fhp, const UserPerm& perms) return r; } -int Client::ll_create(Inode *parent, const char *name, mode_t mode, - int flags, struct stat *attr, Inode **outp, Fh **fhp, +int Client::_ll_create(Inode *parent, const char *name, mode_t mode, + int flags, InodeRef *in, int caps, Fh **fhp, const UserPerm& perms) { *fhp = NULL; - Mutex::Locker lock(client_lock); - vinodeno_t vparent = _get_vino(parent); - ldout(cct, 3) << "ll_create " << vparent << " " << name << " 0" << oct << + ldout(cct, 3) << "_ll_create " << vparent << " " << name << " 0" << oct << mode << dec << " " << flags << ", uid " << perms.uid() << ", gid " << perms.gid() << dendl; tout(cct) << "ll_create" << std::endl; @@ -11690,8 +11688,7 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode, tout(cct) << flags << std::endl; bool created = false; - InodeRef in; - int r = _lookup(parent, name, CEPH_STAT_CAP_INODE_ALL, &in, perms); + int r = _lookup(parent, name, caps, in, perms); if (r == 0 && (flags & O_CREAT) && (flags & O_EXCL)) return -EEXIST; @@ -11702,7 +11699,7 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode, if (r < 0) goto out; } - r = _create(parent, name, flags, mode, &in, fhp, 0, 0, 0, NULL, &created, + r = _create(parent, name, flags, mode, in, fhp, 0, 0, 0, NULL, &created, perms); if (r < 0) goto out; @@ -11711,13 +11708,12 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode, if (r < 0) goto out; - assert(in); - fill_stat(in, attr); + assert(*in); - ldout(cct, 20) << "ll_create created = " << created << dendl; + ldout(cct, 20) << "_ll_create created = " << created << dendl; if (!created) { if (!cct->_conf->fuse_default_permissions) { - r = may_open(in.get(), flags, perms); + r = may_open(in->get(), flags, perms); if (r < 0) { if (*fhp) { int release_r = _release_fh(*fhp); @@ -11727,30 +11723,55 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode, } } if (*fhp == NULL) { - r = _open(in.get(), flags, mode, fhp, perms); + r = _open(in->get(), flags, mode, fhp, perms); if (r < 0) goto out; } } out: - if (r < 0) - attr->st_ino = 0; - if (*fhp) { ll_unclosed_fh_set.insert(*fhp); } + + ino_t ino = 0; + if (r >= 0) { + Inode *inode = in->get(); + if (use_faked_inos()) + ino = inode->faked_ino; + else + ino = inode->ino; + } + tout(cct) << (unsigned long)*fhp << std::endl; - tout(cct) << attr->st_ino << std::endl; - ldout(cct, 3) << "ll_create " << parent << " " << name << " 0" << oct << + tout(cct) << ino << std::endl; + ldout(cct, 3) << "_ll_create " << parent << " " << name << " 0" << oct << mode << dec << " " << flags << " = " << r << " (" << *fhp << " " << - hex << attr->st_ino << dec << ")" << dendl; + hex << ino << dec << ")" << dendl; - // passing an Inode in outp requires an additional ref - if (outp) { - if (in) + return r; +} + +int Client::ll_create(Inode *parent, const char *name, mode_t mode, + int flags, struct stat *attr, Inode **outp, Fh **fhp, + const UserPerm& perms) +{ + InodeRef in; + Mutex::Locker lock(client_lock); + + int r = _ll_create(parent, name, mode, flags, &in, CEPH_STAT_CAP_INODE_ALL, + fhp, perms); + if (r >= 0) { + assert(in); + + // passing an Inode in outp requires an additional ref + if (outp) { _ll_get(in.get()); - *outp = in.get(); + *outp = in.get(); + } + fill_stat(in, attr); + } else { + attr->st_ino = 0; } return r; diff --git a/src/client/Client.h b/src/client/Client.h index d2b4755baba1c..a48f30b290789 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1150,6 +1150,9 @@ class Client : public Dispatcher, public md_config_obs_t { int ll_link(Inode *in, Inode *newparent, const char *newname, struct stat *attr, const UserPerm& perm); int ll_open(Inode *in, int flags, Fh **fh, const UserPerm& perms); + int _ll_create(Inode *parent, const char *name, mode_t mode, + int flags, InodeRef *in, int caps, Fh **fhp, + const UserPerm& perms); int ll_create(Inode *parent, const char *name, mode_t mode, int flags, struct stat *attr, Inode **out, Fh **fhp, const UserPerm& perms); From af3a8a6a1d5192950f8cb11e784e6a95f5bddce0 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:02:59 -0400 Subject: [PATCH 16/31] client: add ll_createx Signed-off-by: Jeff Layton --- src/client/Client.cc | 27 ++++++++++++++++++++ src/client/Client.h | 4 +++ src/include/cephfs/libcephfs.h | 8 +++--- src/libcephfs.cc | 12 ++++----- src/test/libcephfs/recordlock.cc | 42 ++++++++++++++++---------------- src/test/libcephfs/test.cc | 10 +++----- 6 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 6f4c2b1dd738a..fe73d033f9f40 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11777,6 +11777,33 @@ int Client::ll_create(Inode *parent, const char *name, mode_t mode, return r; } +int Client::ll_createx(Inode *parent, const char *name, mode_t mode, + int oflags, Inode **outp, Fh **fhp, + struct ceph_statx *stx, unsigned want, unsigned lflags, + const UserPerm& perms) +{ + unsigned caps = statx_to_mask(lflags, want); + InodeRef in; + Mutex::Locker lock(client_lock); + + int r = _ll_create(parent, name, mode, oflags, &in, caps, fhp, perms); + if (r >= 0) { + assert(in); + + // passing an Inode in outp requires an additional ref + if (outp) { + _ll_get(in.get()); + *outp = in.get(); + } + fill_statx(in, caps, stx); + } else { + stx->stx_ino = 0; + stx->stx_mask = 0; + } + + return r; +} + loff_t Client::ll_lseek(Fh *fh, loff_t offset, int whence) { Mutex::Locker lock(client_lock); diff --git a/src/client/Client.h b/src/client/Client.h index a48f30b290789..c2f4e8cbf863d 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1156,6 +1156,10 @@ class Client : public Dispatcher, public md_config_obs_t { int ll_create(Inode *parent, const char *name, mode_t mode, int flags, struct stat *attr, Inode **out, Fh **fhp, const UserPerm& perms); + int ll_createx(Inode *parent, const char *name, mode_t mode, + int oflags, Inode **outp, Fh **fhp, + struct ceph_statx *stx, unsigned want, unsigned lflags, + const UserPerm& perms); int ll_read_block(Inode *in, uint64_t blockid, char *buf, uint64_t offset, uint64_t length, file_layout_t* layout); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 8bb8baf6f3d8b..f1b01812b9009 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1477,10 +1477,10 @@ int ceph_ll_listxattr(struct ceph_mount_info *cmount, struct Inode *in, const UserPerm *perms); int ceph_ll_removexattr(struct ceph_mount_info *cmount, struct Inode *in, const char *name, const UserPerm *perms); -int ceph_ll_create(struct ceph_mount_info *cmount, struct Inode *parent, - const char *name, mode_t mode, int flags, - struct stat *attr, struct Inode **out, Fh **fhp, - int uid, int gid); +int ceph_ll_create(struct ceph_mount_info *cmount, Inode *parent, + const char *name, mode_t mode, int oflags, Inode **outp, + Fh **fhp, struct ceph_statx *stx, unsigned want, + unsigned lflags, const UserPerm *perms); int ceph_ll_mknod(struct ceph_mount_info *cmount, struct Inode *parent, const char *name, mode_t mode, dev_t rdev, struct stat *attr, struct Inode **out, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index ca5415aae213a..4f4e99e7fd9e7 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1538,13 +1538,13 @@ extern "C" int ceph_ll_close(class ceph_mount_info *cmount, Fh* fh) } extern "C" int ceph_ll_create(class ceph_mount_info *cmount, - struct Inode *parent, const char *name, - mode_t mode, int flags, struct stat *attr, - struct Inode **out, Fh **fhp, int uid, int gid) + Inode *parent, const char *name, mode_t mode, + int oflags, Inode **outp, Fh **fhp, + struct ceph_statx *stx, unsigned want, + unsigned lflags, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client())->ll_create(parent, name, mode, flags, - attr, out, fhp, perms); + return (cmount->get_client())->ll_createx(parent, name, mode, oflags, outp, + fhp, stx, want, lflags, *perms); } extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/recordlock.cc b/src/test/libcephfs/recordlock.cc index e588ba2bb169f..8ba1cb5bf011d 100644 --- a/src/test/libcephfs/recordlock.cc +++ b/src/test/libcephfs/recordlock.cc @@ -80,7 +80,7 @@ TEST(LibCephFS, BasicRecordLocking) { sprintf(c_file, "recordlock_test_%d", getpid()); Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; int rc; struct flock lock1, lock2; @@ -89,8 +89,8 @@ TEST(LibCephFS, BasicRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); // write lock twice @@ -282,7 +282,7 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) { struct ceph_mount_info *const cmount = s.cmount; Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; struct flock lock1; int rc; struct timespec ts; @@ -292,8 +292,8 @@ static void thread_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); lock1.l_type = F_WRLCK; @@ -373,7 +373,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) { sprintf(c_file, "recordlock_test_%d", mypid); Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; struct flock lock1; int rc; @@ -382,8 +382,8 @@ TEST(LibCephFS, ConcurrentRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); // Lock @@ -515,7 +515,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) { sprintf(c_file, "recordlock_test_%d", mypid); Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; struct flock lock1; int rc; @@ -524,8 +524,8 @@ TEST(LibCephFS, ThreesomeRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); // Lock @@ -667,7 +667,7 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) { struct timespec ts; Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; int rc; struct flock lock1; @@ -679,8 +679,8 @@ static void process_ConcurrentRecordLocking(str_ConcurrentRecordLocking& s) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, s.file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); WAIT_MAIN(1); // (R1) @@ -758,7 +758,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) { sprintf(c_file, "recordlock_test_%d", mypid); Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; struct flock lock1; int rc; @@ -788,8 +788,8 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); // Lock @@ -919,7 +919,7 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) { sprintf(c_file, "recordlock_test_%d", mypid); Fh *fh = NULL; Inode *root = NULL, *inode = NULL; - struct stat attr; + struct ceph_statx stx; struct flock lock1; int rc; @@ -956,8 +956,8 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file - rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, &attr, - &inode, &fh, 0, 0); + rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, + &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); ASSERT_EQ(rc, 0); // Lock diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 0f37fe7c2e82b..edbccf2073419 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1403,8 +1403,8 @@ TEST(LibCephFS, Nlink) { ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &st, &dir, getuid(), getgid()), 0); ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL, - &st, &file, &fh, getuid(), getgid()), 0); - ASSERT_EQ(st.st_nlink, (nlink_t)1); + &file, &fh, &stx, CEPH_STATX_NLINK, 0, perms), 0); + ASSERT_EQ(stx.stx_nlink, (nlink_t)1); ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, &st, getuid(), getgid()), 0); ASSERT_EQ(st.st_nlink, (nlink_t)2); @@ -1412,7 +1412,7 @@ TEST(LibCephFS, Nlink) { ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0); ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx, CEPH_STATX_NLINK, 0, perms), 0); - ASSERT_EQ(st.st_nlink, (nlink_t)1); + ASSERT_EQ(stx.stx_nlink, (nlink_t)1); ceph_shutdown(cmount); } @@ -1565,7 +1565,6 @@ TEST(LibCephFS, LazyStatx) { sprintf(filename, "lazystatx%x", getpid()); Inode *root1, *file1, *root2, *file2; - struct stat st; struct ceph_statx stx; Fh *fh; UserPerm *perms1 = ceph_mount_perms(cmount1); @@ -1574,8 +1573,7 @@ TEST(LibCephFS, LazyStatx) { ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0); ceph_ll_unlink(cmount1, root1, filename, getuid(), getgid()); ASSERT_EQ(ceph_ll_create(cmount1, root1, filename, 0666, O_RDWR|O_CREAT|O_EXCL, - &st, &file1, &fh, getuid(), getgid()), 0); - + &file1, &fh, &stx, 0, 0, perms1), 0); ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0); From 4341b09891cb27d7d671ebb86d288513ca333f7b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 17/31] client: convert args to ceph_ll_mknod to use ceph_statx and UserPerm The underlying plumbing needs to remain the same for FUSE though. Signed-off-by: Jeff Layton --- src/client/Client.cc | 36 ++++++++++++++++++++++++++++++++++ src/client/Client.h | 3 +++ src/include/cephfs/libcephfs.h | 8 ++++---- src/libcephfs.cc | 16 +++++++-------- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index fe73d033f9f40..33cf900add9e2 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -10902,6 +10902,42 @@ int Client::ll_mknod(Inode *parent, const char *name, mode_t mode, return r; } +int Client::ll_mknodx(Inode *parent, const char *name, mode_t mode, + dev_t rdev, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm& perms) +{ + unsigned caps = statx_to_mask(flags, want); + Mutex::Locker lock(client_lock); + + vinodeno_t vparent = _get_vino(parent); + + ldout(cct, 3) << "ll_mknodx " << vparent << " " << name << dendl; + tout(cct) << "ll_mknodx" << std::endl; + tout(cct) << vparent.ino.val << std::endl; + tout(cct) << name << std::endl; + tout(cct) << mode << std::endl; + tout(cct) << rdev << std::endl; + + if (!cct->_conf->fuse_default_permissions) { + int r = may_create(parent, perms); + if (r < 0) + return r; + } + + InodeRef in; + int r = _mknod(parent, name, mode, rdev, perms, &in); + if (r == 0) { + fill_statx(in, caps, stx); + _ll_get(in.get()); + } + tout(cct) << stx->stx_ino << std::endl; + ldout(cct, 3) << "ll_mknodx " << vparent << " " << name + << " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl; + *out = in.get(); + return r; +} + int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, InodeRef *inp, Fh **fhp, int stripe_unit, int stripe_count, int object_size, const char *data_pool, bool *created, diff --git a/src/client/Client.h b/src/client/Client.h index c2f4e8cbf863d..9cc0679f7909c 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1139,6 +1139,9 @@ class Client : public Dispatcher, public md_config_obs_t { int ll_readlink(Inode *in, char *buf, size_t bufsize, const UserPerm& perms); int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev, struct stat *attr, Inode **out, const UserPerm& perms); + int ll_mknodx(Inode *parent, const char *name, mode_t mode, dev_t rdev, + Inode **out, struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm& perms); int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr, Inode **out, const UserPerm& perm); int ll_symlink(Inode *in, const char *name, const char *value, diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index f1b01812b9009..191d83e9acba8 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1481,10 +1481,10 @@ int ceph_ll_create(struct ceph_mount_info *cmount, Inode *parent, const char *name, mode_t mode, int oflags, Inode **outp, Fh **fhp, struct ceph_statx *stx, unsigned want, unsigned lflags, const UserPerm *perms); -int ceph_ll_mknod(struct ceph_mount_info *cmount, struct Inode *parent, - const char *name, mode_t mode, dev_t rdev, - struct stat *attr, struct Inode **out, - int uid, int gid); +int ceph_ll_mknod(struct ceph_mount_info *cmount, Inode *parent, + const char *name, mode_t mode, dev_t rdev, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm *perms); int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent, const char *name, mode_t mode, struct stat *attr, Inode **out, int uid, int gid); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 4f4e99e7fd9e7..79ced12d36879 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1547,14 +1547,14 @@ extern "C" int ceph_ll_create(class ceph_mount_info *cmount, fhp, stx, want, lflags, *perms); } -extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, - struct Inode *parent, const char *name, - mode_t mode, dev_t rdev, struct stat *attr, - struct Inode **out, int uid, int gid) -{ - UserPerm perms(uid, gid); - return (cmount->get_client())->ll_mknod(parent, name, mode, rdev, - attr, out, perms); +extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent, + const char *name, mode_t mode, dev_t rdev, + Inode **out, struct ceph_statx *stx, + unsigned want, unsigned flags, + const UserPerm *perms) +{ + return (cmount->get_client())->ll_mknodx(parent, name, mode, rdev, + out, stx, want, flags, *perms); } extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, From f6148de0b6d95fe1c110c0f5c0b2de1ae5ef1cc7 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 18/31] client: change ceph_ll_mkdir to ceph_statx and UserPerm args Signed-off-by: Jeff Layton --- src/client/Client.cc | 36 ++++++++++++++++++++++++++++++++++ src/client/Client.h | 3 +++ src/include/cephfs/libcephfs.h | 7 ++++--- src/libcephfs.cc | 12 ++++++------ src/test/libcephfs/test.cc | 2 +- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 33cf900add9e2..c8db94bef4e7a 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11119,6 +11119,42 @@ int Client::ll_mkdir(Inode *parent, const char *name, mode_t mode, return r; } +int Client::ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm& perms) +{ + Mutex::Locker lock(client_lock); + + vinodeno_t vparent = _get_vino(parent); + + ldout(cct, 3) << "ll_mkdirx " << vparent << " " << name << dendl; + tout(cct) << "ll_mkdirx" << std::endl; + tout(cct) << vparent.ino.val << std::endl; + tout(cct) << name << std::endl; + tout(cct) << mode << std::endl; + + if (!cct->_conf->fuse_default_permissions) { + int r = may_create(parent, perms); + if (r < 0) + return r; + } + + InodeRef in; + int r = _mkdir(parent, name, mode, perms, &in); + if (r == 0) { + fill_statx(in, statx_to_mask(flags, want), stx); + _ll_get(in.get()); + } else { + stx->stx_ino = 0; + stx->stx_mask = 0; + } + tout(cct) << stx->stx_ino << std::endl; + ldout(cct, 3) << "ll_mkdirx " << vparent << " " << name + << " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl; + *out = in.get(); + return r; +} + int Client::_symlink(Inode *dir, const char *name, const char *target, const UserPerm& perms, InodeRef *inp) { diff --git a/src/client/Client.h b/src/client/Client.h index 9cc0679f7909c..91badbfc45deb 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1144,6 +1144,9 @@ class Client : public Dispatcher, public md_config_obs_t { unsigned flags, const UserPerm& perms); int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr, Inode **out, const UserPerm& perm); + int ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out, + struct ceph_statx *stx, unsigned want, unsigned flags, + const UserPerm& perms); int ll_symlink(Inode *in, const char *name, const char *value, struct stat *attr, Inode **out, const UserPerm& perms); int ll_unlink(Inode *in, const char *name, const UserPerm& perm); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 191d83e9acba8..286973ff661f2 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1485,9 +1485,10 @@ int ceph_ll_mknod(struct ceph_mount_info *cmount, Inode *parent, const char *name, mode_t mode, dev_t rdev, Inode **out, struct ceph_statx *stx, unsigned want, unsigned flags, const UserPerm *perms); -int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent, - const char *name, mode_t mode, struct stat *attr, - Inode **out, int uid, int gid); +int ceph_ll_mkdir(struct ceph_mount_info *cmount, Inode *parent, + const char *name, mode_t mode, Inode **out, + struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm *perms); int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in, struct Inode *newparrent, const char *name, struct stat *attr, int uid, int gid); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 79ced12d36879..b565065756be6 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1557,13 +1557,13 @@ extern "C" int ceph_ll_mknod(class ceph_mount_info *cmount, Inode *parent, out, stx, want, flags, *perms); } -extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, - Inode *parent, const char *name, - mode_t mode, struct stat *attr, Inode **out, - int uid, int gid) +extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent, + const char *name, mode_t mode, Inode **out, + struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, perms)); + return cmount->get_client()->ll_mkdirx(parent, name, mode, out, stx, want, + flags, *perms); } extern "C" int ceph_ll_link(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index edbccf2073419..54164e31a634f 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1401,7 +1401,7 @@ TEST(LibCephFS, Nlink) { Fh *fh; UserPerm *perms = ceph_mount_perms(cmount); - ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &st, &dir, getuid(), getgid()), 0); + ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &dir, &stx, 0, 0, perms), 0); ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL, &file, &fh, &stx, CEPH_STATX_NLINK, 0, perms), 0); ASSERT_EQ(stx.stx_nlink, (nlink_t)1); From 9725a33d40271166eb0333b49b6039adacd931c3 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 19/31] client: convert ceph_ll_link to UserPerm and remove struct stat parameter The main user of this API (ganesha) doesn't do anything with the returned attributes, so there's no real point in returning them there. Also, we're not guaranteed to have any caps on the target inode after the link operation, so in the case of FUSE (which does require the post-op attributes) we should really do a getattr to get the latest attributes. Signed-off-by: Jeff Layton --- src/client/Client.cc | 22 ++++++++-------------- src/client/Client.h | 2 +- src/client/SyntheticClient.cc | 3 +-- src/client/fuse_ll.cc | 21 +++++++++++++++------ src/include/cephfs/libcephfs.h | 4 ++-- src/libcephfs.cc | 6 ++---- src/test/libcephfs/test.cc | 6 +++--- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index c8db94bef4e7a..12cd464717288 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11532,7 +11532,7 @@ int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& pe } int Client::ll_link(Inode *in, Inode *newparent, const char *newname, - struct stat *attr, const UserPerm& perm) + const UserPerm& perm) { Mutex::Locker lock(client_lock); @@ -11550,25 +11550,19 @@ int Client::ll_link(Inode *in, Inode *newparent, const char *newname, InodeRef target; if (!cct->_conf->fuse_default_permissions) { - if (S_ISDIR(in->mode)) { - r = -EPERM; - goto out; - } + if (S_ISDIR(in->mode)) + return -EPERM; + r = may_hardlink(in, perm); if (r < 0) - goto out; + return r; + r = may_create(newparent, perm); if (r < 0) - goto out; + return r; } - r = _link(in, newparent, newname, perm, &target); - if (r == 0) { - assert(target); - fill_stat(target, attr); - } -out: - return r; + return _link(in, newparent, newname, perm, &target); } int Client::ll_num_osds(void) diff --git a/src/client/Client.h b/src/client/Client.h index 91badbfc45deb..cbe7b1fb32f80 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1154,7 +1154,7 @@ class Client : public Dispatcher, public md_config_obs_t { int ll_rename(Inode *parent, const char *name, Inode *newparent, const char *newname, const UserPerm& perm); int ll_link(Inode *in, Inode *newparent, const char *newname, - struct stat *attr, const UserPerm& perm); + const UserPerm& perm); int ll_open(Inode *in, int flags, Fh **fh, const UserPerm& perms); int _ll_create(Inode *parent, const char *name, mode_t mode, int flags, InodeRef *in, int caps, Fh **fhp, diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc index 9c44d7a334b04..14e2c567a7eab 100644 --- a/src/client/SyntheticClient.cc +++ b/src/client/SyntheticClient.cc @@ -1344,12 +1344,11 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) int64_t i = t.get_int(); int64_t ni = t.get_int(); const char *nn = t.get_string(buf, p); - struct stat attr; if (ll_inos.count(i) && ll_inos.count(ni)) { i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],CEPH_NOSNAP)); - client->ll_link(i1, i2, nn, &attr, perms); + client->ll_link(i1, i2, nn, perms); client->ll_put(i1); client->ll_put(i2); } diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 97bca93935a22..f63f9274af6bc 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -515,14 +515,22 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, UserPerm perm(ctx->uid, ctx->gid); GET_GROUPS(perm, req); - int r = cfuse->client->ll_link(in, nin, newname, &fe.attr, perm); + /* + * Note that we could successfully link, but then fail the subsequent + * getattr and return an error. Perhaps we should ignore getattr errors, + * but then how do we tell FUSE that the attrs are bogus? + */ + int r = cfuse->client->ll_link(in, nin, newname, perm); if (r == 0) { - fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev); - fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev); - fuse_reply_entry(req, &fe); - } else { - fuse_reply_err(req, -r); + r = cfuse->client->ll_getattr(in, &fe.attr, perm); + if (r == 0) { + fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev); + fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev); + fuse_reply_entry(req, &fe); + } + } + if (r != 0) { /* * Many ll operations in libcephfs return an extra inode reference, but * ll_link currently does not. Still, FUSE needs one for the new dentry, @@ -530,6 +538,7 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, * On error however, we must put that reference. */ cfuse->iput(in); + fuse_reply_err(req, -r); } cfuse->iput(nin); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 286973ff661f2..39582af511386 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1490,8 +1490,8 @@ int ceph_ll_mkdir(struct ceph_mount_info *cmount, Inode *parent, struct ceph_statx *stx, unsigned want, unsigned flags, const UserPerm *perms); int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in, - struct Inode *newparrent, const char *name, - struct stat *attr, int uid, int gid); + struct Inode *newparent, const char *name, + const UserPerm *perms); int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in, struct ceph_dir_result **dirpp, int uid, int gid); int ceph_ll_releasedir(struct ceph_mount_info *cmount, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index b565065756be6..dd2e648afc953 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1568,11 +1568,9 @@ extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, Inode *parent, extern "C" int ceph_ll_link(class ceph_mount_info *cmount, Inode *in, Inode *newparent, - const char *name, struct stat *attr, int uid, - int gid) + const char *name, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_link(in, newparent, name, attr, perms)); + return cmount->get_client()->ll_link(in, newparent, name, *perms); } extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 54164e31a634f..385ac98d7a12f 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1396,7 +1396,6 @@ TEST(LibCephFS, Nlink) { sprintf(filename, "nlinkorig%x", getpid()); sprintf(linkname, "nlinklink%x", getpid()); - struct stat st; struct ceph_statx stx; Fh *fh; UserPerm *perms = ceph_mount_perms(cmount); @@ -1406,8 +1405,9 @@ TEST(LibCephFS, Nlink) { &file, &fh, &stx, CEPH_STATX_NLINK, 0, perms), 0); ASSERT_EQ(stx.stx_nlink, (nlink_t)1); - ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, &st, getuid(), getgid()), 0); - ASSERT_EQ(st.st_nlink, (nlink_t)2); + ASSERT_EQ(ceph_ll_link(cmount, file, dir, linkname, perms), 0); + ASSERT_EQ(ceph_ll_getattr(cmount, file, &stx, CEPH_STATX_NLINK, 0, perms), 0); + ASSERT_EQ(stx.stx_nlink, (nlink_t)2); ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0); ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx, From 6a2930abbb0f3fd1599485d6676b7b0f2dc6539b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 20/31] client: convert ceph_ll_opendir to UserPerm Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 2 +- src/libcephfs.cc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 39582af511386..746c5c797006c 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1493,7 +1493,7 @@ int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in, struct Inode *newparent, const char *name, const UserPerm *perms); int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in, - struct ceph_dir_result **dirpp, int uid, int gid); + struct ceph_dir_result **dirpp, const UserPerm *perms); int ceph_ll_releasedir(struct ceph_mount_info *cmount, struct ceph_dir_result* dir); int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index dd2e648afc953..664fb809fd8e2 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1576,11 +1576,10 @@ extern "C" int ceph_ll_link(class ceph_mount_info *cmount, extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount, Inode *in, struct ceph_dir_result **dirpp, - int uid, int gid) + const UserPerm *perms) { - UserPerm perms(uid, gid); return (cmount->get_client()->ll_opendir(in, O_RDONLY, (dir_result_t**) dirpp, - perms)); + *perms)); } extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount, From 1df52938024ee3e04eecd8111523537db82f0f15 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 21/31] client: convert ceph_ll_rename and ceph_ll_unlink to UserPerm Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 4 ++-- src/libcephfs.cc | 15 ++++++--------- src/test/libcephfs/recordlock.cc | 25 +++++++++++++++---------- src/test/libcephfs/test.cc | 4 ++-- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 746c5c797006c..5d5f8a0686184 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1498,9 +1498,9 @@ int ceph_ll_releasedir(struct ceph_mount_info *cmount, struct ceph_dir_result* dir); int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent, const char *name, struct Inode *newparent, - const char *newname, int uid, int gid); + const char *newname, const UserPerm *perms); int ceph_ll_unlink(struct ceph_mount_info *cmount, struct Inode *in, - const char *name, int uid, int gid); + const char *name, const UserPerm *perms); int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in, struct statvfs *stbuf); int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 664fb809fd8e2..97cfc6b551d2e 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1592,19 +1592,16 @@ extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount, extern "C" int ceph_ll_rename(class ceph_mount_info *cmount, Inode *parent, const char *name, Inode *newparent, const char *newname, - int uid, int gid) + const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_rename(parent, name, - newparent, newname, perms)); + return cmount->get_client()->ll_rename(parent, name, newparent, + newname, *perms); } -extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, - Inode *in, const char *name, - int uid, int gid) +extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount, Inode *in, + const char *name, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_unlink(in, name, perms)); + return cmount->get_client()->ll_unlink(in, name, *perms); } extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount, diff --git a/src/test/libcephfs/recordlock.cc b/src/test/libcephfs/recordlock.cc index 8ba1cb5bf011d..7f852ef3f4694 100644 --- a/src/test/libcephfs/recordlock.cc +++ b/src/test/libcephfs/recordlock.cc @@ -83,6 +83,7 @@ TEST(LibCephFS, BasicRecordLocking) { struct ceph_statx stx; int rc; struct flock lock1, lock2; + UserPerm *perms = ceph_mount_perms(cmount); // Get the root inode rc = ceph_ll_lookup_root(cmount, &root); @@ -90,7 +91,7 @@ TEST(LibCephFS, BasicRecordLocking) { // Get the inode and Fh corresponding to c_file rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, - &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); + &inode, &fh, &stx, 0, 0, perms); ASSERT_EQ(rc, 0); // write lock twice @@ -228,7 +229,7 @@ TEST(LibCephFS, BasicRecordLocking) { ASSERT_EQ(lock2.l_pid, getpid()); ASSERT_EQ(0, ceph_ll_close(cmount, fh)); - ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0)); + ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms)); CLEANUP_CEPH(); } @@ -376,6 +377,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) { struct ceph_statx stx; struct flock lock1; int rc; + UserPerm *perms = ceph_mount_perms(cmount); // Get the root inode rc = ceph_ll_lookup_root(cmount, &root); @@ -383,7 +385,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) { // Get the inode and Fh corresponding to c_file rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, - &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); + &inode, &fh, &stx, 0, 0, perms); ASSERT_EQ(rc, 0); // Lock @@ -502,7 +504,7 @@ TEST(LibCephFS, ConcurrentRecordLocking) { ASSERT_EQ(NULL, retval); s.sem_destroy(); ASSERT_EQ(0, ceph_ll_close(cmount, fh)); - ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0)); + ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms)); CLEANUP_CEPH(); } @@ -518,6 +520,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) { struct ceph_statx stx; struct flock lock1; int rc; + UserPerm *perms = ceph_mount_perms(cmount); // Get the root inode rc = ceph_ll_lookup_root(cmount, &root); @@ -525,7 +528,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) { // Get the inode and Fh corresponding to c_file rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, - &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); + &inode, &fh, &stx, 0, 0, perms); ASSERT_EQ(rc, 0); // Lock @@ -648,7 +651,7 @@ TEST(LibCephFS, ThreesomeRecordLocking) { ASSERT_EQ(NULL, retval); s.sem_destroy(); ASSERT_EQ(0, ceph_ll_close(cmount, fh)); - ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0)); + ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms)); CLEANUP_CEPH(); } @@ -782,6 +785,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) { struct timespec ts; struct ceph_mount_info *cmount; STARTUP_CEPH(); + UserPerm *perms = ceph_mount_perms(cmount); // Get the root inode rc = ceph_ll_lookup_root(cmount, &root); @@ -789,7 +793,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) { // Get the inode and Fh corresponding to c_file rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, - &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); + &inode, &fh, &stx, 0, 0, perms); ASSERT_EQ(rc, 0); // Lock @@ -906,7 +910,7 @@ TEST(LibCephFS, DISABLED_InterProcessRecordLocking) { s.sem_destroy(); ASSERT_EQ(0, munmap(shs, sizeof(*shs))); ASSERT_EQ(0, ceph_ll_close(cmount, fh)); - ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0)); + ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms)); CLEANUP_CEPH(); } @@ -956,8 +960,9 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) { ASSERT_EQ(rc, 0); // Get the inode and Fh corresponding to c_file + UserPerm *perms = ceph_mount_perms(cmount); rc = ceph_ll_create(cmount, root, c_file, fileMode, O_RDWR | O_CREAT, - &inode, &fh, &stx, 0, 0, ceph_mount_perms(cmount)); + &inode, &fh, &stx, 0, 0, perms); ASSERT_EQ(rc, 0); // Lock @@ -1077,6 +1082,6 @@ TEST(LibCephFS, DISABLED_ThreesomeInterProcessRecordLocking) { s.sem_destroy(); ASSERT_EQ(0, munmap(shs, sizeof(*shs))); ASSERT_EQ(0, ceph_ll_close(cmount, fh)); - ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, 0, 0)); + ASSERT_EQ(0, ceph_ll_unlink(cmount, root, c_file, perms)); CLEANUP_CEPH(); } diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 385ac98d7a12f..bcadc73d3f4d4 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1409,7 +1409,7 @@ TEST(LibCephFS, Nlink) { ASSERT_EQ(ceph_ll_getattr(cmount, file, &stx, CEPH_STATX_NLINK, 0, perms), 0); ASSERT_EQ(stx.stx_nlink, (nlink_t)2); - ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0); + ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, perms), 0); ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx, CEPH_STATX_NLINK, 0, perms), 0); ASSERT_EQ(stx.stx_nlink, (nlink_t)1); @@ -1571,7 +1571,7 @@ TEST(LibCephFS, LazyStatx) { UserPerm *perms2 = ceph_mount_perms(cmount2); ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0); - ceph_ll_unlink(cmount1, root1, filename, getuid(), getgid()); + ceph_ll_unlink(cmount1, root1, filename, perms1); ASSERT_EQ(ceph_ll_create(cmount1, root1, filename, 0666, O_RDWR|O_CREAT|O_EXCL, &file1, &fh, &stx, 0, 0, perms1), 0); From 236044554ad917e916958f97e1cf17ab39683e20 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 22/31] client: change ceph_ll_symlinkx to take a UserPerm and ceph_statx Signed-off-by: Jeff Layton --- src/client/Client.cc | 34 ++++++++++++++++++++++++++++++++++ src/client/Client.h | 3 +++ src/include/cephfs/libcephfs.h | 8 +++++--- src/libcephfs.cc | 9 +++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 12cd464717288..340f88696e8c5 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11234,6 +11234,40 @@ int Client::ll_symlink(Inode *parent, const char *name, const char *value, return r; } +int Client::ll_symlinkx(Inode *parent, const char *name, const char *value, + Inode **out, struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm& perms) +{ + Mutex::Locker lock(client_lock); + + vinodeno_t vparent = _get_vino(parent); + + ldout(cct, 3) << "ll_symlinkx " << vparent << " " << name << " -> " << value + << dendl; + tout(cct) << "ll_symlinkx" << std::endl; + tout(cct) << vparent.ino.val << std::endl; + tout(cct) << name << std::endl; + tout(cct) << value << std::endl; + + if (!cct->_conf->fuse_default_permissions) { + int r = may_create(parent, perms); + if (r < 0) + return r; + } + + InodeRef in; + int r = _symlink(parent, name, value, perms, &in); + if (r == 0) { + fill_statx(in, statx_to_mask(flags, want), stx); + _ll_get(in.get()); + } + tout(cct) << stx->stx_ino << std::endl; + ldout(cct, 3) << "ll_symlinkx " << vparent << " " << name + << " = " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl; + *out = in.get(); + return r; +} + int Client::_unlink(Inode *dir, const char *name, const UserPerm& perm) { ldout(cct, 3) << "_unlink(" << dir->ino << " " << name diff --git a/src/client/Client.h b/src/client/Client.h index cbe7b1fb32f80..c3e6ffdfc077e 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1149,6 +1149,9 @@ class Client : public Dispatcher, public md_config_obs_t { const UserPerm& perms); int ll_symlink(Inode *in, const char *name, const char *value, struct stat *attr, Inode **out, const UserPerm& perms); + int ll_symlinkx(Inode *parent, const char *name, const char *value, + Inode **out, struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm& perms); int ll_unlink(Inode *in, const char *name, const UserPerm& perm); int ll_rmdir(Inode *in, const char *name, const UserPerm& perms); int ll_rename(Inode *parent, const char *name, Inode *newparent, diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 5d5f8a0686184..a5802eebeedb6 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1505,9 +1505,11 @@ int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in, struct statvfs *stbuf); int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in, char *buf, size_t bufsize, int uid, int gid); -int ceph_ll_symlink(struct ceph_mount_info *cmount, struct Inode *parent, - const char *name, const char *value, struct stat *attr, - struct Inode **in, int uid, int gid); +int ceph_ll_symlink(struct ceph_mount_info *cmount, + Inode *in, const char *name, const char *value, + Inode **out, struct ceph_statx *stx, + unsigned want, unsigned flags, + const UserPerm *perms); int ceph_ll_rmdir(struct ceph_mount_info *cmount, struct Inode *in, const char *name, int uid, int gid); uint32_t ceph_ll_stripe_unit(struct ceph_mount_info *cmount, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 97cfc6b551d2e..ea6802973387f 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1620,11 +1620,12 @@ extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount, Inode *in, const char *name, - const char *value, struct stat *attr, - Inode **out, int uid, int gid) + const char *value, Inode **out, + struct ceph_statx *stx, unsigned want, + unsigned flags, const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_symlink(in, name, value, attr, out, perms)); + return (cmount->get_client()->ll_symlinkx(in, name, value, out, stx, want, + flags, *perms)); } extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount, From c248fa7be1e4c4e96df973230401e17f53dec4de Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 23/31] client: convert ceph_ll_readlink and ceph_ll_rmdir to UserPerm Signed-off-by: Jeff Layton --- src/include/cephfs/libcephfs.h | 4 ++-- src/libcephfs.cc | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index a5802eebeedb6..f54302a65e228 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1504,14 +1504,14 @@ int ceph_ll_unlink(struct ceph_mount_info *cmount, struct Inode *in, int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in, struct statvfs *stbuf); int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in, - char *buf, size_t bufsize, int uid, int gid); + char *buf, size_t bufsize, const UserPerm *perms); int ceph_ll_symlink(struct ceph_mount_info *cmount, Inode *in, const char *name, const char *value, Inode **out, struct ceph_statx *stx, unsigned want, unsigned flags, const UserPerm *perms); int ceph_ll_rmdir(struct ceph_mount_info *cmount, struct Inode *in, - const char *name, int uid, int gid); + const char *name, const UserPerm *perms); uint32_t ceph_ll_stripe_unit(struct ceph_mount_info *cmount, struct Inode *in); uint32_t ceph_ll_file_layout(struct ceph_mount_info *cmount, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index ea6802973387f..0b4934704a041 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1610,12 +1610,11 @@ extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount, return (cmount->get_client()->ll_statfs(in, stbuf, cmount->default_perms)); } -extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, - Inode *in, char *buf, size_t bufsiz, int uid, - int gid) +extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount, Inode *in, + char *buf, size_t bufsiz, + const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_readlink(in, buf, bufsiz, perms)); + return cmount->get_client()->ll_readlink(in, buf, bufsiz, *perms); } extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount, @@ -1630,10 +1629,9 @@ extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount, extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount, Inode *in, const char *name, - int uid, int gid) + const UserPerm *perms) { - UserPerm perms(uid, gid); - return (cmount->get_client()->ll_rmdir(in, name, perms)); + return cmount->get_client()->ll_rmdir(in, name, *perms); } extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount, From 57fe4da2a72b923346c7e845661520c015fa1078 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 24/31] client: plumb a "lazy" arg into _readdir_cache_cb and readdir_r_cb ...that defaults to true since that's what most of the callers want. Signed-off-by: Jeff Layton --- src/client/Client.cc | 6 +++--- src/client/Client.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 340f88696e8c5..78504dffc4bb6 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7324,7 +7324,7 @@ struct dentry_off_lt { } }; -int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p) +int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy) { assert(client_lock.is_locked()); ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino @@ -7397,7 +7397,7 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p) return 0; } -int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) +int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy) { Mutex::Locker lock(client_lock); @@ -7467,7 +7467,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) if (dirp->inode->snapid != CEPH_SNAPDIR && dirp->inode->is_complete_and_ordered() && dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) { - int err = _readdir_cache_cb(dirp, cb, p); + int err = _readdir_cache_cb(dirp, cb, p, lazy); if (err != -EAGAIN) return err; } diff --git a/src/client/Client.h b/src/client/Client.h index c3e6ffdfc077e..b19f41434bd2f 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -727,7 +727,7 @@ class Client : public Dispatcher, public md_config_obs_t { void _readdir_next_frag(dir_result_t *dirp); void _readdir_rechoose_frag(dir_result_t *dirp); int _readdir_get_frag(dir_result_t *dirp); - int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p); + int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy); void _closedir(dir_result_t *dirp); // other helpers @@ -952,7 +952,7 @@ class Client : public Dispatcher, public md_config_obs_t { * Returns 0 if it reached the end of the directory. * If @a cb returns a negative error code, stop and return that. */ - int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p); + int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy=true); struct dirent * readdir(dir_result_t *d); int readdir_r(dir_result_t *dirp, struct dirent *de); From 183cc07d4afaf1b7a0f52be9b23fbed715510e36 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:00 -0400 Subject: [PATCH 25/31] client: change args to ceph_readdirplus_r Make ceph_readdirplus_r take a ceph_statx, a want and a flags parm. With this, we can allow applications to express an interest in subset of the attributes, and can allow for a "lazy" readdirplus. Drop the stmask. It ends up returning the caps that the client holds on the inode. That's not well defined, and we can now express that in a better way via the stx_mask, which applications can use to tell which fields in the ceph_statx are actually valid. For now, the want mask is ignored. I don't see a way to ask for a set of caps in a ceph readdir request on the wire. Maybe we could add that? Signed-off-by: Jeff Layton --- src/client/Client.cc | 65 ++++++++++++++--------------- src/client/Client.h | 4 +- src/client/fuse_ll.cc | 14 ++++--- src/client/hypertable/CephBroker.cc | 6 +-- src/include/cephfs/libcephfs.h | 7 ++-- src/libcephfs.cc | 5 ++- src/test/libcephfs/test.cc | 15 ++++--- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 78504dffc4bb6..9667ecd0e2537 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7360,21 +7360,21 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, b continue; } - struct stat st; + struct ceph_statx stx; struct dirent de; - int stmask = fill_stat(dn->inode, &st); + fill_statx(dn->inode, lazy ? 0 : dn->inode->caps_issued(), &stx); uint64_t next_off = dn->offset + 1; ++pd; if (pd == dir->readdir_cache.end()) next_off = dir_result_t::END; - fill_dirent(&de, dn->name.c_str(), st.st_mode, st.st_ino, next_off); + fill_dirent(&de, dn->name.c_str(), stx.stx_mode, stx.stx_ino, next_off); dn_name = dn->name; // fill in name while we have lock client_lock.Unlock(); - int r = cb(p, &de, &st, stmask, next_off); // _next_ offset + int r = cb(p, &de, &stx, next_off); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec << " = " << r << dendl; @@ -7408,9 +7408,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy << " hash_order=" << dirp->hash_order() << dendl; struct dirent de; - struct stat st; + struct ceph_statx stx; memset(&de, 0, sizeof(de)); - memset(&st, 0, sizeof(st)); + memset(&stx, 0, sizeof(stx)); InodeRef& diri = dirp->inode; @@ -7422,11 +7422,11 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy assert(diri->dn_set.size() < 2); // can't have multiple hard-links to a dir uint64_t next_off = 1; - fill_stat(diri, &st); - fill_dirent(&de, ".", S_IFDIR, st.st_ino, next_off); + fill_statx(diri, lazy ? 0 : diri->caps_issued(), &stx); + fill_dirent(&de, ".", S_IFDIR, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &st, -1, next_off); + int r = cb(p, &de, &stx, next_off); client_lock.Lock(); if (r < 0) return r; @@ -7444,11 +7444,11 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy else in = diri->get_first_parent()->inode; - fill_stat(in, &st); - fill_dirent(&de, "..", S_IFDIR, st.st_ino, next_off); + fill_statx(in, lazy ? 0 : in->caps_issued(), &stx); + fill_dirent(&de, "..", S_IFDIR, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &st, -1, next_off); + int r = cb(p, &de, &stx, next_off); client_lock.Lock(); if (r < 0) return r; @@ -7495,11 +7495,11 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy dir_result_t::dentry &entry = *it; uint64_t next_off = entry.offset + 1; - int stmask = fill_stat(entry.inode, &st); - fill_dirent(&de, entry.name.c_str(), st.st_mode, st.st_ino, next_off); + fill_statx(entry.inode, lazy ? 0 : entry.inode->caps_issued(), &stx); + fill_dirent(&de, entry.name.c_str(), stx.stx_mode, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &st, stmask, next_off); // _next_ offset + int r = cb(p, &de, &stx, next_off); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << next_off - 1 << dec @@ -7549,7 +7549,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy int Client::readdir_r(dir_result_t *d, struct dirent *de) { - return readdirplus_r(d, de, 0, 0); + return readdirplus_r(d, de, 0, 0, 0); } /* @@ -7563,13 +7563,12 @@ int Client::readdir_r(dir_result_t *d, struct dirent *de) struct single_readdir { struct dirent *de; - struct stat *st; - int *stmask; + struct ceph_statx *stx; bool full; }; -static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st, - int stmask, off_t off) +static int _readdir_single_dirent_cb(void *p, struct dirent *de, + struct ceph_statx *stx, off_t off) { single_readdir *c = static_cast(p); @@ -7577,10 +7576,8 @@ static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st return -1; // already filled this dirent *c->de = *de; - if (c->st) - *c->st = *st; - if (c->stmask) - *c->stmask = stmask; + if (c->stx) + *c->stx = *stx; c->full = true; return 1; } @@ -7588,13 +7585,10 @@ static int _readdir_single_dirent_cb(void *p, struct dirent *de, struct stat *st struct dirent *Client::readdir(dir_result_t *d) { int ret; - static int stmask; static struct dirent de; - static struct stat st; single_readdir sr; sr.de = &de; - sr.st = &st; - sr.stmask = &stmask; + sr.stx = NULL; sr.full = false; // our callback fills the dirent and sets sr.full=true on first @@ -7610,17 +7604,19 @@ struct dirent *Client::readdir(dir_result_t *d) return (dirent *) NULL; } -int Client::readdirplus_r(dir_result_t *d, struct dirent *de, struct stat *st, int *stmask) +int Client::readdirplus_r(dir_result_t *d, struct dirent *de, + struct ceph_statx *stx, unsigned want, + unsigned flags) { single_readdir sr; sr.de = de; - sr.st = st; - sr.stmask = stmask; + sr.stx = stx; sr.full = false; // our callback fills the dirent and sets sr.full=true on first // call, and returns -1 the second time around. - int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr); + int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, + flags & AT_NO_ATTR_SYNC); if (r < -1) return r; if (sr.full) @@ -7637,7 +7633,8 @@ struct getdents_result { bool fullent; }; -static int _readdir_getdent_cb(void *p, struct dirent *de, struct stat *st, int stmask, off_t off) +static int _readdir_getdent_cb(void *p, struct dirent *de, + struct ceph_statx *stx, off_t off) { struct getdents_result *c = static_cast(p); @@ -7689,7 +7686,7 @@ struct getdir_result { int num; }; -static int _getdir_cb(void *p, struct dirent *de, struct stat *st, int stmask, off_t off) +static int _getdir_cb(void *p, struct dirent *de, struct ceph_statx *stx, off_t off) { getdir_result *r = static_cast(p); diff --git a/src/client/Client.h b/src/client/Client.h index b19f41434bd2f..05a9af8029ade 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -719,7 +719,7 @@ class Client : public Dispatcher, public md_config_obs_t { void fill_dirent(struct dirent *de, const char *name, int type, uint64_t ino, loff_t next_off); // some readdir helpers - typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct stat *st, int stmask, off_t off); + typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct ceph_statx *stx, off_t off); int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms); void _readdir_drop_dirp_buffer(dir_result_t *dirp); @@ -956,7 +956,7 @@ class Client : public Dispatcher, public md_config_obs_t { struct dirent * readdir(dir_result_t *d); int readdir_r(dir_result_t *dirp, struct dirent *de); - int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct stat *st, int *stmask); + int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, unsigned flags); int getdir(const char *relpath, list& names, const UserPerm& perms); // get the whole dir at once. diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index f63f9274af6bc..9d6890041d893 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -32,6 +32,7 @@ #include "ioctl.h" #include "common/config.h" #include "include/assert.h" +#include "include/cephfs/ceph_statx.h" #include "fuse_ll.h" #include @@ -678,19 +679,20 @@ struct readdir_context { /* * return 0 on success, -1 if out of space */ -static int fuse_ll_add_dirent(void *p, struct dirent *de, struct stat *st, - int stmask, off_t next_off) +static int fuse_ll_add_dirent(void *p, struct dirent *de, + struct ceph_statx *stx, off_t next_off) { struct readdir_context *c = (struct readdir_context *)p; CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(c->req); - st->st_ino = cfuse->make_fake_ino(de->d_ino, c->snap); - st->st_mode = DTTOIF(de->d_type); - st->st_rdev = new_encode_dev(st->st_rdev); + struct stat st; + st.st_ino = cfuse->make_fake_ino(stx->stx_ino, c->snap); + st.st_mode = stx->stx_mode; + st.st_rdev = new_encode_dev(stx->stx_rdev); size_t room = c->size - c->pos; size_t entrysize = fuse_add_direntry(c->req, c->buf + c->pos, room, - de->d_name, st, next_off); + de->d_name, &st, next_off); if (entrysize > room) return -ENOSPC; diff --git a/src/client/hypertable/CephBroker.cc b/src/client/hypertable/CephBroker.cc index 74766c063bf08..6c8ce64de7c07 100644 --- a/src/client/hypertable/CephBroker.cc +++ b/src/client/hypertable/CephBroker.cc @@ -384,17 +384,17 @@ void CephBroker::rmdir(ResponseCallback *cb, const char *dname) { int CephBroker::rmdir_recursive(const char *directory) { struct ceph_dir_result *dirp; struct dirent de; - struct stat st; + struct ceph_statx stx; int r; if ((r = ceph_opendir(cmount, directory, &dirp)) < 0) return r; //failed to open - while ((r = ceph_readdirplus_r(cmount, dirp, &de, &st, 0)) > 0) { + while ((r = ceph_readdirplus_r(cmount, dirp, &de, &stx, CEPH_STATX_INO, AT_NO_ATTR_SYNC)) > 0) { String new_dir = de.d_name; if(!(new_dir.compare(".")==0 || new_dir.compare("..")==0)) { new_dir = directory; new_dir += '/'; new_dir += de.d_name; - if (S_ISDIR(st.st_mode)) { //it's a dir, clear it out... + if (S_ISDIR(stx.stx_mode)) { //it's a dir, clear it out... if((r=rmdir_recursive(new_dir.c_str())) < 0) return r; } else { //delete this file if((r=ceph_unlink(cmount, new_dir.c_str())) < 0) return r; diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index f54302a65e228..13078412032a1 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -480,13 +480,14 @@ int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, * @param dirp the directory stream pointer from an opendir holding the state of the * next entry to return. * @param de the directory entry pointer filled in with the next directory entry of the dirp state. - * @param st the stats of the file/directory of the entry returned - * @param stmask a mask that gets filled in with the stats fields that are being set in the st parameter. + * @param stx the stats of the file/directory of the entry returned + * @param want mask showing desired inode attrs for returned entry + * @param flags bitmask of flags to use when filling out attributes * @returns 1 if the next entry was filled in, 0 if the end of the directory stream was reached, * and a negative error code on failure. */ int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de, - struct stat *st, int *stmask); + struct ceph_statx *stx, unsigned want, unsigned flags); /** * Gets multiple directory entries. diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 0b4934704a041..7b7e7c517dc04 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -517,11 +517,12 @@ extern "C" int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_re } extern "C" int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, - struct dirent *de, struct stat *st, int *stmask) + struct dirent *de, struct ceph_statx *stx, unsigned want, + unsigned flags) { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->readdirplus_r(reinterpret_cast(dirp), de, st, stmask); + return cmount->get_client()->readdirplus_r(reinterpret_cast(dirp), de, stx, want, flags); } extern "C" int ceph_getdents(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index bcadc73d3f4d4..5a38cf8c7dc1e 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -424,9 +424,9 @@ TEST(LibCephFS, DirLs) { found.clear(); while (true) { struct dirent rdent; - struct stat st; - int stmask; - int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &st, &stmask); + struct ceph_statx stx; + int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &stx, + CEPH_STATX_SIZE, AT_NO_ATTR_SYNC); if (len == 0) break; ASSERT_EQ(len, 1); @@ -434,8 +434,9 @@ TEST(LibCephFS, DirLs) { found.push_back(name); int size; sscanf(name, "dirf%d", &size); - ASSERT_EQ(st.st_size, size); - ASSERT_EQ(st.st_ino, rdent.d_ino); + ASSERT_TRUE(stx.stx_mask & CEPH_STATX_SIZE); + ASSERT_EQ(stx.stx_size, (size_t)size); + ASSERT_EQ(stx.stx_ino, rdent.d_ino); //ASSERT_EQ(st.st_mode, (mode_t)0666); } ASSERT_EQ(found, entries); @@ -1136,10 +1137,8 @@ TEST(LibCephFS, UseUnmounted) { struct dirent rdent; EXPECT_EQ(-ENOTCONN, ceph_readdir_r(cmount, dirp, &rdent)); - int stmask; struct ceph_statx stx; - struct stat st; - EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &st, &stmask)); + EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &stx, 0, 0)); EXPECT_EQ(-ENOTCONN, ceph_getdents(cmount, dirp, NULL, 0)); EXPECT_EQ(-ENOTCONN, ceph_getdnames(cmount, dirp, NULL, 0)); EXPECT_EQ(-ENOTCONN, ceph_telldir(cmount, dirp)); From f7028e48936cb70f623fe7ba408708a403e60270 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 26/31] client: pass want and flags to readdir_r_cb ...so we can ensure that we have the necessary caps when filling out the ceph_statx for each dentry's inode. In order to only do this when completely necessary, we have want default to 0 and the flags default to AT_NO_ATTR_SYNC. The only codepath where we pass in a non-default set of args there is ceph_readdirplus_r as it's the only codepath that cares about fields in the ceph_statx that aren't immutable. For now, since we have no support for requesting caps during a readdir call, we simply issue getattrs prior to calling fill_statx. If we already have the necessary caps, or are doing a lazy statx then this becomes a no-op. Note too that I _think_ the MDS will recall caps on the entries when satisfying a readdir, so we avoid calling getattr when we're populating the ceph_statx out of a just-acquired readdir response. Signed-off-by: Jeff Layton --- src/client/Client.cc | 52 +++++++++++++++++++++++++++++++++----------- src/client/Client.h | 6 +++-- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 9667ecd0e2537..44085c201b553 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7324,7 +7324,7 @@ struct dentry_off_lt { } }; -int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy) +int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps) { assert(client_lock.is_locked()); ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino @@ -7360,9 +7360,13 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, b continue; } + int r = _getattr(dn->inode, caps, dirp->perms); + if (r < 0) + return r; + struct ceph_statx stx; struct dirent de; - fill_statx(dn->inode, lazy ? 0 : dn->inode->caps_issued(), &stx); + fill_statx(dn->inode, caps, &stx); uint64_t next_off = dn->offset + 1; ++pd; @@ -7374,7 +7378,7 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, b dn_name = dn->name; // fill in name while we have lock client_lock.Unlock(); - int r = cb(p, &de, &stx, next_off); // _next_ offset + r = cb(p, &de, &stx, next_off); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec << " = " << r << dendl; @@ -7397,8 +7401,11 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, b return 0; } -int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy) +int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, + unsigned want, unsigned flags) { + int caps = statx_to_mask(flags, want); + Mutex::Locker lock(client_lock); dir_result_t *dirp = static_cast(d); @@ -7422,11 +7429,16 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy assert(diri->dn_set.size() < 2); // can't have multiple hard-links to a dir uint64_t next_off = 1; - fill_statx(diri, lazy ? 0 : diri->caps_issued(), &stx); + int r; + r = _getattr(diri, caps, dirp->perms); + if (r < 0) + return r; + + fill_statx(diri, caps, &stx); fill_dirent(&de, ".", S_IFDIR, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &stx, next_off); + r = cb(p, &de, &stx, next_off); client_lock.Lock(); if (r < 0) return r; @@ -7444,11 +7456,16 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy else in = diri->get_first_parent()->inode; - fill_statx(in, lazy ? 0 : in->caps_issued(), &stx); + int r; + r = _getattr(diri, caps, dirp->perms); + if (r < 0) + return r; + + fill_statx(in, caps, &stx); fill_dirent(&de, "..", S_IFDIR, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &stx, next_off); + r = cb(p, &de, &stx, next_off); client_lock.Lock(); if (r < 0) return r; @@ -7467,7 +7484,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy if (dirp->inode->snapid != CEPH_SNAPDIR && dirp->inode->is_complete_and_ordered() && dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) { - int err = _readdir_cache_cb(dirp, cb, p, lazy); + int err = _readdir_cache_cb(dirp, cb, p, caps); if (err != -EAGAIN) return err; } @@ -7476,12 +7493,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy if (dirp->at_end()) return 0; + bool check_caps = true; if (!dirp->is_cached()) { int r = _readdir_get_frag(dirp); if (r) return r; // _readdir_get_frag () may updates dirp->offset if the replied dirfrag is // different than the requested one. (our dirfragtree was outdated) + check_caps = false; } frag_t fg = dirp->buffer_frag; @@ -7495,11 +7514,19 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, bool lazy dir_result_t::dentry &entry = *it; uint64_t next_off = entry.offset + 1; - fill_statx(entry.inode, lazy ? 0 : entry.inode->caps_issued(), &stx); + + int r; + if (check_caps) { + r = _getattr(entry.inode, caps, dirp->perms); + if (r < 0) + return r; + } + + fill_statx(entry.inode, caps, &stx); fill_dirent(&de, entry.name.c_str(), stx.stx_mode, stx.stx_ino, next_off); client_lock.Unlock(); - int r = cb(p, &de, &stx, next_off); // _next_ offset + r = cb(p, &de, &stx, next_off); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << next_off - 1 << dec @@ -7615,8 +7642,7 @@ int Client::readdirplus_r(dir_result_t *d, struct dirent *de, // our callback fills the dirent and sets sr.full=true on first // call, and returns -1 the second time around. - int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, - flags & AT_NO_ATTR_SYNC); + int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, want, flags); if (r < -1) return r; if (sr.full) diff --git a/src/client/Client.h b/src/client/Client.h index 05a9af8029ade..907fd4864c98d 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -48,6 +48,7 @@ using std::fstream; #include "InodeRef.h" #include "UserPerm.h" +#include "include/cephfs/ceph_statx.h" class FSMap; class FSMapUser; @@ -727,7 +728,7 @@ class Client : public Dispatcher, public md_config_obs_t { void _readdir_next_frag(dir_result_t *dirp); void _readdir_rechoose_frag(dir_result_t *dirp); int _readdir_get_frag(dir_result_t *dirp); - int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy); + int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps); void _closedir(dir_result_t *dirp); // other helpers @@ -952,7 +953,8 @@ class Client : public Dispatcher, public md_config_obs_t { * Returns 0 if it reached the end of the directory. * If @a cb returns a negative error code, stop and return that. */ - int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, bool lazy=true); + int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, + unsigned want=0, unsigned flags=AT_NO_ATTR_SYNC); struct dirent * readdir(dir_result_t *d); int readdir_r(dir_result_t *dirp, struct dirent *de); From 641173fd5da8b66663842ec191bd7d7993a2a385 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 27/31] client: add an optional Inode ** parm to ceph_readdirplus_r Ganesha needs an inode reference in addition to the attributes when it calls readdirplus. Other callers however don't need an inode reference. We could just take one universally and pass it to the callback, but most callers don't need that reference and would need to put it in the callback. That's cumbersome and mutex-thrashy. So, we need to fix the readdir engine to only conditionally take this extra reference, when the callback will actually use it. Add a bool to readdir_r_cb that defaults to false and indicates that the caller wants an inode reference for each dentry returned. When that bool is true we'll pass a pointer to the inode to the callback after taking a reference. Otherwise, NULL is passed to the callback. Next, add a return double pointer arg to ceph_readdirplus_r that indicates whether the caller wants an inode reference and where to put the pointer to the inode. Almost all callers will set that to NULL, but ganesha can set it to a non-NULL value to get the inode reference that it wants on each call. Signed-off-by: Jeff Layton --- src/client/Client.cc | 57 ++++++++++++++++++++++------- src/client/Client.h | 9 +++-- src/client/fuse_ll.cc | 3 +- src/client/hypertable/CephBroker.cc | 2 +- src/include/cephfs/libcephfs.h | 4 +- src/libcephfs.cc | 4 +- src/test/libcephfs/test.cc | 4 +- 7 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 44085c201b553..c4c2053522506 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7324,7 +7324,8 @@ struct dentry_off_lt { } }; -int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps) +int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, + int caps, bool getref) { assert(client_lock.is_locked()); ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino @@ -7373,12 +7374,17 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, i if (pd == dir->readdir_cache.end()) next_off = dir_result_t::END; + Inode *in = NULL; fill_dirent(&de, dn->name.c_str(), stx.stx_mode, stx.stx_ino, next_off); + if (getref) { + in = dn->inode.get(); + _ll_get(in); + } dn_name = dn->name; // fill in name while we have lock client_lock.Unlock(); - r = cb(p, &de, &stx, next_off); // _next_ offset + r = cb(p, &de, &stx, next_off, in); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec << " = " << r << dendl; @@ -7402,7 +7408,7 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, i } int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, - unsigned want, unsigned flags) + unsigned want, unsigned flags, bool getref) { int caps = statx_to_mask(flags, want); @@ -7437,8 +7443,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, fill_statx(diri, caps, &stx); fill_dirent(&de, ".", S_IFDIR, stx.stx_ino, next_off); + Inode *inode = NULL; + if (getref) { + inode = diri.get(); + _ll_get(inode); + } + client_lock.Unlock(); - r = cb(p, &de, &stx, next_off); + r = cb(p, &de, &stx, next_off, inode); client_lock.Lock(); if (r < 0) return r; @@ -7464,8 +7476,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, fill_statx(in, caps, &stx); fill_dirent(&de, "..", S_IFDIR, stx.stx_ino, next_off); + Inode *inode = NULL; + if (getref) { + inode = in.get(); + _ll_get(inode); + } + client_lock.Unlock(); - r = cb(p, &de, &stx, next_off); + r = cb(p, &de, &stx, next_off, inode); client_lock.Lock(); if (r < 0) return r; @@ -7484,7 +7502,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, if (dirp->inode->snapid != CEPH_SNAPDIR && dirp->inode->is_complete_and_ordered() && dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) { - int err = _readdir_cache_cb(dirp, cb, p, caps); + int err = _readdir_cache_cb(dirp, cb, p, caps, getref); if (err != -EAGAIN) return err; } @@ -7525,8 +7543,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, fill_statx(entry.inode, caps, &stx); fill_dirent(&de, entry.name.c_str(), stx.stx_mode, stx.stx_ino, next_off); + Inode *inode = NULL; + if (getref) { + inode = entry.inode.get(); + _ll_get(inode); + } + client_lock.Unlock(); - r = cb(p, &de, &stx, next_off); // _next_ offset + r = cb(p, &de, &stx, next_off, inode); // _next_ offset client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << next_off - 1 << dec @@ -7576,7 +7600,7 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p, int Client::readdir_r(dir_result_t *d, struct dirent *de) { - return readdirplus_r(d, de, 0, 0, 0); + return readdirplus_r(d, de, 0, 0, 0, NULL); } /* @@ -7591,11 +7615,13 @@ int Client::readdir_r(dir_result_t *d, struct dirent *de) struct single_readdir { struct dirent *de; struct ceph_statx *stx; + Inode *inode; bool full; }; static int _readdir_single_dirent_cb(void *p, struct dirent *de, - struct ceph_statx *stx, off_t off) + struct ceph_statx *stx, off_t off, + Inode *in) { single_readdir *c = static_cast(p); @@ -7605,6 +7631,7 @@ static int _readdir_single_dirent_cb(void *p, struct dirent *de, *c->de = *de; if (c->stx) *c->stx = *stx; + c->inode = in; c->full = true; return 1; } @@ -7616,6 +7643,7 @@ struct dirent *Client::readdir(dir_result_t *d) single_readdir sr; sr.de = &de; sr.stx = NULL; + sr.inode = NULL; sr.full = false; // our callback fills the dirent and sets sr.full=true on first @@ -7633,18 +7661,21 @@ struct dirent *Client::readdir(dir_result_t *d) int Client::readdirplus_r(dir_result_t *d, struct dirent *de, struct ceph_statx *stx, unsigned want, - unsigned flags) + unsigned flags, Inode **out) { single_readdir sr; sr.de = de; sr.stx = stx; + sr.inode = NULL; sr.full = false; // our callback fills the dirent and sets sr.full=true on first // call, and returns -1 the second time around. - int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, want, flags); + int r = readdir_r_cb(d, _readdir_single_dirent_cb, (void *)&sr, want, flags, out); if (r < -1) return r; + if (out) + *out = sr.inode; if (sr.full) return 1; return 0; @@ -7660,7 +7691,7 @@ struct getdents_result { }; static int _readdir_getdent_cb(void *p, struct dirent *de, - struct ceph_statx *stx, off_t off) + struct ceph_statx *stx, off_t off, Inode *in) { struct getdents_result *c = static_cast(p); @@ -7712,7 +7743,7 @@ struct getdir_result { int num; }; -static int _getdir_cb(void *p, struct dirent *de, struct ceph_statx *stx, off_t off) +static int _getdir_cb(void *p, struct dirent *de, struct ceph_statx *stx, off_t off, Inode *in) { getdir_result *r = static_cast(p); diff --git a/src/client/Client.h b/src/client/Client.h index 907fd4864c98d..70f764251bfa4 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -720,7 +720,7 @@ class Client : public Dispatcher, public md_config_obs_t { void fill_dirent(struct dirent *de, const char *name, int type, uint64_t ino, loff_t next_off); // some readdir helpers - typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct ceph_statx *stx, off_t off); + typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct ceph_statx *stx, off_t off, Inode *in); int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms); void _readdir_drop_dirp_buffer(dir_result_t *dirp); @@ -728,7 +728,7 @@ class Client : public Dispatcher, public md_config_obs_t { void _readdir_next_frag(dir_result_t *dirp); void _readdir_rechoose_frag(dir_result_t *dirp); int _readdir_get_frag(dir_result_t *dirp); - int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps); + int _readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, int caps, bool getref); void _closedir(dir_result_t *dirp); // other helpers @@ -954,11 +954,12 @@ class Client : public Dispatcher, public md_config_obs_t { * If @a cb returns a negative error code, stop and return that. */ int readdir_r_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p, - unsigned want=0, unsigned flags=AT_NO_ATTR_SYNC); + unsigned want=0, unsigned flags=AT_NO_ATTR_SYNC, + bool getref=false); struct dirent * readdir(dir_result_t *d); int readdir_r(dir_result_t *dirp, struct dirent *de); - int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, unsigned flags); + int readdirplus_r(dir_result_t *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, unsigned flags, Inode **out); int getdir(const char *relpath, list& names, const UserPerm& perms); // get the whole dir at once. diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 9d6890041d893..8b3695417d9df 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -680,7 +680,8 @@ struct readdir_context { * return 0 on success, -1 if out of space */ static int fuse_ll_add_dirent(void *p, struct dirent *de, - struct ceph_statx *stx, off_t next_off) + struct ceph_statx *stx, off_t next_off, + Inode *in) { struct readdir_context *c = (struct readdir_context *)p; CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(c->req); diff --git a/src/client/hypertable/CephBroker.cc b/src/client/hypertable/CephBroker.cc index 6c8ce64de7c07..77f6e083419ff 100644 --- a/src/client/hypertable/CephBroker.cc +++ b/src/client/hypertable/CephBroker.cc @@ -388,7 +388,7 @@ int CephBroker::rmdir_recursive(const char *directory) { int r; if ((r = ceph_opendir(cmount, directory, &dirp)) < 0) return r; //failed to open - while ((r = ceph_readdirplus_r(cmount, dirp, &de, &stx, CEPH_STATX_INO, AT_NO_ATTR_SYNC)) > 0) { + while ((r = ceph_readdirplus_r(cmount, dirp, &de, &stx, CEPH_STATX_INO, AT_NO_ATTR_SYNC, NULL)) > 0) { String new_dir = de.d_name; if(!(new_dir.compare(".")==0 || new_dir.compare("..")==0)) { new_dir = directory; diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 13078412032a1..cacdab98d451a 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -483,11 +483,13 @@ int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, * @param stx the stats of the file/directory of the entry returned * @param want mask showing desired inode attrs for returned entry * @param flags bitmask of flags to use when filling out attributes + * @param out optional returned Inode argument. If non-NULL, then a reference will be taken on + * the inode and the pointer set on success. * @returns 1 if the next entry was filled in, 0 if the end of the directory stream was reached, * and a negative error code on failure. */ int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de, - struct ceph_statx *stx, unsigned want, unsigned flags); + struct ceph_statx *stx, unsigned want, unsigned flags, struct Inode **out); /** * Gets multiple directory entries. diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 7b7e7c517dc04..288f6a7c80e69 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -518,11 +518,11 @@ extern "C" int ceph_readdir_r(struct ceph_mount_info *cmount, struct ceph_dir_re extern "C" int ceph_readdirplus_r(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, struct dirent *de, struct ceph_statx *stx, unsigned want, - unsigned flags) + unsigned flags, struct Inode **out) { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->readdirplus_r(reinterpret_cast(dirp), de, stx, want, flags); + return cmount->get_client()->readdirplus_r(reinterpret_cast(dirp), de, stx, want, flags, out); } extern "C" int ceph_getdents(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp, diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 5a38cf8c7dc1e..e8eaef4ba5279 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -426,7 +426,7 @@ TEST(LibCephFS, DirLs) { struct dirent rdent; struct ceph_statx stx; int len = ceph_readdirplus_r(cmount, ls_dir, &rdent, &stx, - CEPH_STATX_SIZE, AT_NO_ATTR_SYNC); + CEPH_STATX_SIZE, AT_NO_ATTR_SYNC, NULL); if (len == 0) break; ASSERT_EQ(len, 1); @@ -1138,7 +1138,7 @@ TEST(LibCephFS, UseUnmounted) { EXPECT_EQ(-ENOTCONN, ceph_readdir_r(cmount, dirp, &rdent)); struct ceph_statx stx; - EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &stx, 0, 0)); + EXPECT_EQ(-ENOTCONN, ceph_readdirplus_r(cmount, dirp, &rdent, &stx, 0, 0, NULL)); EXPECT_EQ(-ENOTCONN, ceph_getdents(cmount, dirp, NULL, 0)); EXPECT_EQ(-ENOTCONN, ceph_getdnames(cmount, dirp, NULL, 0)); EXPECT_EQ(-ENOTCONN, ceph_telldir(cmount, dirp)); From 547ce092f311e8443dddce8e94877000fa1fac72 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 28/31] client: better debugging for size changes Signed-off-by: Jeff Layton --- src/client/Client.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index c4c2053522506..1665e3daa9674 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6568,10 +6568,12 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask, CEPH_CAP_FILE_WR; } if (mask & CEPH_SETATTR_SIZE) { - if ((unsigned long)stx->stx_size < mdsmap->get_max_filesize()) + if ((unsigned long)stx->stx_size < mdsmap->get_max_filesize()) { req->head.args.setattr.size = stx->stx_size; - else { //too big! + ldout(cct,10) << "changing size to " << stx->stx_size << dendl; + } else { //too big! put_request(req); + ldout(cct,10) << "unable to set size to " << stx->stx_size << ". Too large!" << dendl; return -EFBIG; } req->inode_drop |= CEPH_CAP_AUTH_SHARED | CEPH_CAP_FILE_RD | From 29961914a439453048ee27ffe9145bd2224b487d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 29/31] libcephfs: move to SOVERSION 2.0.0 The new libcephfs API is incompatible with the old. Move to SOVERSION 2.0.0 so that any programs built against the old headers will fail at load time. Signed-off-by: Jeff Layton --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 739d1485178c7..c3685c20ea444 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -771,8 +771,8 @@ if(WITH_LIBCEPHFS) endforeach() set_target_properties(cephfs PROPERTIES OUTPUT_NAME cephfs - VERSION 1.0.0 - SOVERSION 1 + VERSION 2.0.0 + SOVERSION 2 LINK_FLAGS ${CEPHFS_LINK_FLAGS}) endif(ENABLE_SHARED) install(TARGETS cephfs DESTINATION ${CMAKE_INSTALL_LIBDIR}) From 939f5bd1c2b4a5b150587a71d20c890d6b230fab Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 30/31] rpm: libcephfs1 -> libcephfs2 package rename Signed-off-by: Jeff Layton --- ceph.spec.in | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ceph.spec.in b/ceph.spec.in index 71d3720a1aca0..388fafab91e87 100644 --- a/ceph.spec.in +++ b/ceph.spec.in @@ -218,7 +218,7 @@ Group: System Environment/Base Requires: ceph-common = %{epoch}:%{version}-%{release} Requires: librbd1 = %{epoch}:%{version}-%{release} Requires: librados2 = %{epoch}:%{version}-%{release} -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} Requires: librgw2 = %{epoch}:%{version}-%{release} %if 0%{with selinux} Requires: ceph-selinux = %{epoch}:%{version}-%{release} @@ -251,7 +251,7 @@ Summary: Ceph Common Group: System Environment/Base Requires: librbd1 = %{epoch}:%{version}-%{release} Requires: librados2 = %{epoch}:%{version}-%{release} -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} Requires: python-rados = %{epoch}:%{version}-%{release} Requires: python-rbd = %{epoch}:%{version}-%{release} Requires: python-cephfs = %{epoch}:%{version}-%{release} @@ -521,7 +521,7 @@ Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release} This package contains Python 3 libraries for interacting with Cephs RADOS block device. -%package -n libcephfs1 +%package -n libcephfs2 Summary: Ceph distributed file system client library Group: System Environment/Libraries License: LGPL-2.0 @@ -529,7 +529,7 @@ License: LGPL-2.0 Obsoletes: ceph-libs < %{epoch}:%{version}-%{release} Obsoletes: ceph-libcephfs %endif -%description -n libcephfs1 +%description -n libcephfs2 Ceph is a distributed network file system designed to provide excellent performance, reliability, and scalability. This is a shared library allowing applications to access a Ceph distributed file system via a @@ -539,11 +539,11 @@ POSIX-like interface. Summary: Ceph distributed file system headers Group: Development/Libraries License: LGPL-2.0 -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} Requires: librados-devel = %{epoch}:%{version}-%{release} Obsoletes: ceph-devel < %{epoch}:%{version}-%{release} -Provides: libcephfs1-devel = %{epoch}:%{version}-%{release} -Obsoletes: libcephfs1-devel < %{epoch}:%{version}-%{release} +Provides: libcephfs2-devel = %{epoch}:%{version}-%{release} +Obsoletes: libcephfs2-devel < %{epoch}:%{version}-%{release} %description -n libcephfs-devel This package contains libraries and headers needed to develop programs that use Cephs distributed file system. @@ -552,7 +552,7 @@ that use Cephs distributed file system. Summary: Python 2 libraries for Ceph distributed file system Group: System Environment/Libraries License: LGPL-2.0 -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} Requires: python-rados = %{epoch}:%{version}-%{release} Obsoletes: python-ceph < %{epoch}:%{version}-%{release} %description -n python-cephfs @@ -563,7 +563,7 @@ file system. Summary: Python 3 libraries for Ceph distributed file system Group: System Environment/Libraries License: LGPL-2.0 -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} Requires: python%{python3_pkgversion}-rados = %{epoch}:%{version}-%{release} %description -n python%{python3_pkgversion}-cephfs This package contains Python 3 libraries for interacting with Cephs distributed @@ -597,7 +597,7 @@ Summary: Java Native Interface library for CephFS Java bindings Group: System Environment/Libraries License: LGPL-2.0 Requires: java -Requires: libcephfs1 = %{epoch}:%{version}-%{release} +Requires: libcephfs2 = %{epoch}:%{version}-%{release} %description -n libcephfs_jni1 This package contains the Java Native Interface library for CephFS Java bindings. @@ -1432,13 +1432,13 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1 %{python3_sitearch}/rbd.cpython*.so %{python3_sitearch}/rbd-*.egg-info -%files -n libcephfs1 +%files -n libcephfs2 %defattr(-,root,root,-) %{_libdir}/libcephfs.so.* -%post -n libcephfs1 -p /sbin/ldconfig +%post -n libcephfs2 -p /sbin/ldconfig -%postun -n libcephfs1 -p /sbin/ldconfig +%postun -n libcephfs2 -p /sbin/ldconfig %files -n libcephfs-devel %defattr(-,root,root,-) From c078dc0daa9c50621f7252559a97bfb191244ca1 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 24 Oct 2016 10:03:01 -0400 Subject: [PATCH 31/31] dpkg: libcephfs1 -> libcephfs2 package rename Signed-off-by: Jeff Layton --- debian/.gitignore | 4 ++-- debian/control | 24 +++++++++---------- ...{libcephfs1.install => libcephfs2.install} | 0 debian/rules | 2 +- qa/qa_scripts/cephscrub.sh | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) rename debian/{libcephfs1.install => libcephfs2.install} (100%) diff --git a/debian/.gitignore b/debian/.gitignore index 35789301f40c9..32ca866d7536d 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -21,9 +21,9 @@ /*.debhelper /ceph /files -/libcephfs1-dbg +/libcephfs2-dbg /libcephfs-dev -/libcephfs1 +/libcephfs2 /librados2-dbg /librados-dev /librados2 diff --git a/debian/control b/debian/control index 822606ef7fe04..1296bb41d897b 100644 --- a/debian/control +++ b/debian/control @@ -121,7 +121,7 @@ Depends: ceph-base (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Recommends: ceph-fuse (= ${binary:Version}), - libcephfs1 (= ${binary:Version}) + libcephfs2 (= ${binary:Version}) Replaces: ceph (<< 0.93-417) Breaks: ceph (<< 0.93-417) Description: metadata server for the ceph distributed file system @@ -517,7 +517,7 @@ Description: RADOS block device client library (development files) This package contains development files needed for building applications that link against librbd1. -Package: libcephfs1 +Package: libcephfs2 Conflicts: libceph, libceph1, libcephfs Replaces: libceph, libceph1, libcephfs Architecture: linux-any @@ -530,28 +530,28 @@ Description: Ceph distributed file system client library shared library allowing applications to access a Ceph distributed file system via a POSIX-like interface. -Package: libcephfs1-dbg +Package: libcephfs2-dbg Architecture: linux-any Section: debug Priority: extra -Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends} +Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends} Conflicts: libceph1-dbg Replaces: libceph1-dbg -Description: debugging symbols for libcephfs1 +Description: debugging symbols for libcephfs2 Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, block and file system storage. This is a shared library allowing applications to access a Ceph distributed file system via a POSIX-like interface. . - This package contains debugging symbols for libcephfs1. + This package contains debugging symbols for libcephfs2. Package: libcephfs-dev Architecture: linux-any Section: libdevel -Depends: libcephfs1 (= ${binary:Version}), ${misc:Depends} -Conflicts: libceph-dev, libceph1-dev, libcephfs1-dev -Replaces: libceph-dev, libceph1-dev, libcephfs1-dev +Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends} +Conflicts: libceph-dev, libceph1-dev, libcephfs2-dev +Replaces: libceph-dev, libceph1-dev, libcephfs2-dev Description: Ceph distributed file system client library (development files) Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, @@ -727,7 +727,7 @@ Description: Python 3 libraries for the Ceph librbd library Package: python-cephfs Architecture: linux-any Section: python -Depends: libcephfs1 (= ${binary:Version}), +Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}, ${python:Depends} @@ -744,7 +744,7 @@ Description: Python 2 libraries for the Ceph libcephfs library Package: python3-cephfs Architecture: linux-any Section: python -Depends: libcephfs1 (= ${binary:Version}), +Depends: libcephfs2 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}, ${python3:Depends} @@ -777,6 +777,6 @@ Description: Java libraries for the Ceph File System Package: libcephfs-jni Architecture: linux-any Section: java -Depends: libcephfs1 (= ${binary:Version}), ${java:Depends}, +Depends: libcephfs2 (= ${binary:Version}), ${java:Depends}, ${misc:Depends}, ${shlibs:Depends} Description: Java Native Interface library for CephFS Java bindings diff --git a/debian/libcephfs1.install b/debian/libcephfs2.install similarity index 100% rename from debian/libcephfs1.install rename to debian/libcephfs2.install diff --git a/debian/rules b/debian/rules index 1fa764ed82d06..95598057b7411 100755 --- a/debian/rules +++ b/debian/rules @@ -133,7 +133,7 @@ override_dh_strip: dh_strip -plibrados2 --dbg-package=librados2-dbg dh_strip -plibradosstriper1 --dbg-package=libradosstriper1-dbg dh_strip -plibrbd1 --dbg-package=librbd1-dbg - dh_strip -plibcephfs1 --dbg-package=libcephfs1-dbg + dh_strip -plibcephfs2 --dbg-package=libcephfs2-dbg dh_strip -plibrgw2 --dbg-package=librgw2-dbg dh_strip -pradosgw --dbg-package=radosgw-dbg dh_strip -pceph-test --dbg-package=ceph-test-dbg diff --git a/qa/qa_scripts/cephscrub.sh b/qa/qa_scripts/cephscrub.sh index 216d655f1cf25..331d5ce32d813 100755 --- a/qa/qa_scripts/cephscrub.sh +++ b/qa/qa_scripts/cephscrub.sh @@ -19,8 +19,8 @@ sudo apt-get -y purge librados-dev sudo apt-get -y purge librbd1 sudo apt-get -y purge librbd1-dbg sudo apt-get -y purge librbd-dev -sudo apt-get -y purge libcephfs1 -sudo apt-get -y purge libcephfs1-dbg +sudo apt-get -y purge libcephfs2 +sudo apt-get -y purge libcephfs2-dbg sudo apt-get -y purge libcephfs-dev sudo apt-get -y purge radosgw sudo apt-get -y purge radosgw-dbg