From b214671472801702d5f1a687a3618826d0646b5f Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Thu, 18 Mar 2021 18:21:05 +0530 Subject: [PATCH] client/libcephfs: Add lchmod Fixes: https://tracker.ceph.com/issues/49882 Signed-off-by: Kotresh HR (cherry picked from commit bb1fd87e3bc45b20f377438cddde6c6307299a29) --- src/include/cephfs/libcephfs.h | 11 +++++++++ src/libcephfs.cc | 6 +++++ src/test/libcephfs/test.cc | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index c1668769f3fc5..1608ac7cf9b38 100755 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -789,6 +789,17 @@ int ceph_fsetattrx(struct ceph_mount_info *cmount, int fd, struct ceph_statx *st */ int ceph_chmod(struct ceph_mount_info *cmount, const char *path, mode_t mode); +/** + * Change the mode bits (permissions) of a file/directory. If the path is a + * symbolic link, it's not de-referenced. + * + * @param cmount the ceph mount handle to use for performing the chmod. + * @param path the path of file/directory to change the mode bits on. + * @param mode the new permissions to set. + * @returns 0 on success or a negative error code on failure. + */ +int ceph_lchmod(struct ceph_mount_info *cmount, const char *path, mode_t mode); + /** * Change the mode bits (permissions) of an open file. * diff --git a/src/libcephfs.cc b/src/libcephfs.cc index a48e83163fea3..6d18556449465 100755 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -883,6 +883,12 @@ extern "C" int ceph_chmod(struct ceph_mount_info *cmount, const char *path, mode return -ENOTCONN; return cmount->get_client()->chmod(path, mode, cmount->default_perms); } +extern "C" int ceph_lchmod(struct ceph_mount_info *cmount, const char *path, mode_t mode) +{ + if (!cmount->is_mounted()) + return -ENOTCONN; + return cmount->get_client()->lchmod(path, mode, cmount->default_perms); +} extern "C" int ceph_fchmod(struct ceph_mount_info *cmount, int fd, mode_t mode) { if (!cmount->is_mounted()) diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index fb7292e342b22..857d544081810 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -813,6 +813,47 @@ TEST(LibCephFS, Fchmod) { ceph_shutdown(cmount); } +TEST(LibCephFS, Lchmod) { + struct ceph_mount_info *cmount; + ASSERT_EQ(ceph_create(&cmount, NULL), 0); + ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0); + ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL)); + ASSERT_EQ(ceph_mount(cmount, NULL), 0); + + char test_file[256]; + sprintf(test_file, "test_perms_lchmod_%d", getpid()); + + int fd = ceph_open(cmount, test_file, O_CREAT|O_RDWR, 0666); + ASSERT_GT(fd, 0); + + // write some stuff + const char *bytes = "foobarbaz"; + ASSERT_EQ(ceph_write(cmount, fd, bytes, strlen(bytes), 0), (int)strlen(bytes)); + ceph_close(cmount, fd); + + // Create symlink + char test_symlink[256]; + sprintf(test_symlink, "test_lchmod_sym_%d", getpid()); + ASSERT_EQ(ceph_symlink(cmount, test_file, test_symlink), 0); + + // get symlink stat - lstat + struct ceph_statx stx_orig1; + ASSERT_EQ(ceph_statx(cmount, test_symlink, &stx_orig1, CEPH_STATX_ALL_STATS, AT_SYMLINK_NOFOLLOW), 0); + + // Change mode on symlink file + ASSERT_EQ(ceph_lchmod(cmount, test_symlink, 0400), 0); + struct ceph_statx stx_orig2; + ASSERT_EQ(ceph_statx(cmount, test_symlink, &stx_orig2, CEPH_STATX_ALL_STATS, AT_SYMLINK_NOFOLLOW), 0); + + // Compare modes + ASSERT_NE(stx_orig1.stx_mode, stx_orig2.stx_mode); + static const int permbits = S_IRWXU|S_IRWXG|S_IRWXO; + ASSERT_EQ(permbits&stx_orig1.stx_mode, 0777); + ASSERT_EQ(permbits&stx_orig2.stx_mode, 0400); + + ceph_shutdown(cmount); +} + TEST(LibCephFS, Fchown) { struct ceph_mount_info *cmount; ASSERT_EQ(ceph_create(&cmount, NULL), 0); -- 2.39.5