]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: Support for fchown
authorSam Lang <sam.lang@inktank.com>
Fri, 19 Oct 2012 14:23:10 +0000 (09:23 -0500)
committerSage Weil <sage@inktank.com>
Sun, 4 Nov 2012 12:25:31 +0000 (04:25 -0800)
Implement fchown in libcephfs and client,
which is needed by the samba vfs module.

Signed-off-by: Sam Lang <sam.lang@inktank.com>
src/client/Client.cc
src/client/Client.h
src/include/cephfs/libcephfs.h
src/libcephfs.cc
src/test/libcephfs/test.cc

index 7ba8a992b594e3cd31be541e4db3556913ac18d4..fda5b21f2114e3bfc6dfe0641d116565c6832b0c 100644 (file)
@@ -4254,6 +4254,21 @@ int Client::chown(const char *relpath, uid_t uid, gid_t gid)
   return _setattr(in, &attr, CEPH_SETATTR_UID|CEPH_SETATTR_GID);
 }
 
+int Client::fchown(int fd, uid_t uid, gid_t gid)
+{
+  Mutex::Locker lock(client_lock);
+  tout(cct) << "fchown" << std::endl;
+  tout(cct) << fd << std::endl;
+  tout(cct) << uid << std::endl;
+  tout(cct) << gid << std::endl;
+  assert(fd_map.count(fd));
+  Fh *f = fd_map[fd];
+  struct stat attr;
+  attr.st_uid = uid;
+  attr.st_gid = gid;
+  return _setattr(f->inode, &attr, CEPH_SETATTR_UID|CEPH_SETATTR_GID);
+}
+
 int Client::lchown(const char *relpath, uid_t uid, gid_t gid)
 {
   Mutex::Locker lock(client_lock);
index 89184f3abb2092b097c916b7037888d55819e904..8edf9f550f6a91443afdec61d975b2cd924b8cca 100644 (file)
@@ -591,6 +591,7 @@ public:
   int chmod(const char *path, mode_t mode);
   int fchmod(int fd, mode_t mode);
   int chown(const char *path, uid_t uid, gid_t gid);
+  int fchown(int fd, uid_t uid, gid_t gid);
   int lchown(const char *path, uid_t uid, gid_t gid);
   int utime(const char *path, struct utimbuf *buf);
   int truncate(const char *path, loff_t size);
index 4776a71109345be98790c98a1694b1b6534d80eb..3ebbac13226873b15f8ae73da665f6b002fdf71c 100644 (file)
@@ -532,6 +532,17 @@ int ceph_fchmod(struct ceph_mount_info *cmount, int fd, mode_t mode);
  */
 int ceph_chown(struct ceph_mount_info *cmount, const char *path, uid_t uid, gid_t gid);
 
+/**
+ * Change the ownership of a file from an open file descriptor.
+ *
+ * @param cmount the ceph mount handle to use for performing the chown.
+ * @param path the path of the file/directory to change the ownership of.
+ * @param uid the user id to set on the file/directory.
+ * @param gid the group id to set on the file/directory.
+ * @returns 0 on success or negative error code on failure.
+ */
+int ceph_fchown(struct ceph_mount_info *cmount, int fd, uid_t uid, gid_t gid);
+
 /**
  * Change the ownership of a file/directory, don't follow symlinks.
  * 
index fb6274f024c64cf07e51900bf650c24df762ca57..f23b959c9b1a2d1a842c45715f2bee406211d2a3 100644 (file)
@@ -565,6 +565,11 @@ extern "C" int ceph_chown(struct ceph_mount_info *cmount, const char *path,
     return -ENOTCONN;
   return cmount->get_client()->chown(path, uid, gid);
 }
+extern "C" int ceph_fchown(struct ceph_mount_info *cmount, int fd,
+                          uid_t uid, gid_t gid)
+{
+  return cmount->get_client()->fchown(fd, uid, gid);
+}
 extern "C" int ceph_lchown(struct ceph_mount_info *cmount, const char *path,
                           uid_t uid, gid_t gid)
 {
index 154c81a5c082ef538e1428637093aeb2b1c04eee..1d4b45e15a7ae2fc2a964b05030b2d2b0d6bf641 100644 (file)
@@ -516,6 +516,31 @@ TEST(LibCephFS, Fchmod) {
   ceph_shutdown(cmount);
 }
 
+TEST(LibCephFS, Fchown) {
+  struct ceph_mount_info *cmount;
+  ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+  ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+  ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+
+  char test_file[256];
+  sprintf(test_file, "test_fchown_%d", getpid());
+
+  int fd = ceph_open(cmount, test_file, O_CREAT|O_RDWR, 0666);
+  ASSERT_GT(fd, 0);
+
+  // set perms to readable and writeable only by owner
+  ASSERT_EQ(ceph_fchmod(cmount, fd, 0600), 0);
+
+  // change ownership to nobody -- we assume nobody exists and id is always 65534
+  ASSERT_EQ(ceph_fchown(cmount, fd, 65534, 65534), 0);
+
+  ceph_close(cmount, fd);
+
+  fd = ceph_open(cmount, test_file, O_RDWR, 0);
+  ASSERT_EQ(fd, -EACCES);
+  ceph_shutdown(cmount);
+}
+
 TEST(LibCephFS, Symlinks) {
   struct ceph_mount_info *cmount;
   ASSERT_EQ(ceph_create(&cmount, NULL), 0);