]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client/libcephfs: Add lchmod
authorKotresh HR <khiremat@redhat.com>
Thu, 18 Mar 2021 12:51:05 +0000 (18:21 +0530)
committerNathan Cutler <ncutler@suse.com>
Tue, 13 Apr 2021 13:46:20 +0000 (15:46 +0200)
Fixes: https://tracker.ceph.com/issues/49882
Signed-off-by: Kotresh HR <khiremat@redhat.com>
(cherry picked from commit bb1fd87e3bc45b20f377438cddde6c6307299a29)

src/include/cephfs/libcephfs.h
src/libcephfs.cc
src/test/libcephfs/test.cc

index c1668769f3fc5b5f83ec66115b2a8ebdceee2ba3..1608ac7cf9b38e3db66e503e8995727bd58944ba 100755 (executable)
@@ -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.
  *
index a48e83163fea333db4603cfd0d1b2ba214a50746..6d18556449465dd2de231e34acbff961edace5c9 100755 (executable)
@@ -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())
index fb7292e342b2213035de703dec4c50d3e7e102bb..857d5440818101b896e7d3ad7a6e16fd70a30951 100644 (file)
@@ -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);