From: Sam Lang Date: Fri, 19 Oct 2012 14:23:10 +0000 (-0500) Subject: client: Support for fchown X-Git-Tag: v0.55~130^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6f7a632aaadaed4566ef031f2ec7f7e5c9e15e06;p=ceph.git client: Support for fchown Implement fchown in libcephfs and client, which is needed by the samba vfs module. Signed-off-by: Sam Lang --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 7ba8a992b594e..fda5b21f2114e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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); diff --git a/src/client/Client.h b/src/client/Client.h index 89184f3abb209..8edf9f550f6a9 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 4776a71109345..3ebbac1322687 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -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. * diff --git a/src/libcephfs.cc b/src/libcephfs.cc index fb6274f024c64..f23b959c9b1a2 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -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) { diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 154c81a5c082e..1d4b45e15a7ae 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -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);