From 9b0c88bf130fec8e90561a4ee4a538a1f8eb4b8c Mon Sep 17 00:00:00 2001 From: Sam Lang Date: Wed, 10 Oct 2012 10:16:53 -0500 Subject: [PATCH] client: Implement stat and correct lstat lstat is meant to not follow symbolic links in the given path, whereas stat does. This adds a stat function to Client and libcephfs and changes the behavior of lstat to not follow symlinks. Signed-off-by: Sam Lang --- src/client/Client.cc | 25 ++++++++++++++++++++++++- src/client/Client.h | 1 + src/include/cephfs/libcephfs.h | 10 ++++++++++ src/libcephfs.cc | 6 ++++++ src/test/libcephfs/test.cc | 3 ++- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index a718a0cad66a6..89c5ed09961ee 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4103,6 +4103,28 @@ int Client::setattr(const char *relpath, struct stat *attr, int mask) return _setattr(in, attr, mask); } +int Client::stat(const char *relpath, struct stat *stbuf, + frag_info_t *dirstat, int mask) +{ + ldout(cct, 3) << "stat enter (relpath" << relpath << " mask " << mask << ")" << dendl; + Mutex::Locker lock(client_lock); + tout(cct) << "stat" << std::endl; + tout(cct) << relpath << std::endl; + filepath path(relpath); + Inode *in; + int r = path_walk(path, &in); + if (r < 0) + return r; + r = _getattr(in, mask); + if (r < 0) { + ldout(cct, 3) << "stat exit on error!" << dendl; + return r; + } + fill_stat(in, stbuf, dirstat); + ldout(cct, 3) << "stat exit (relpath" << relpath << " mask " << mask << ")" << dendl; + return r; +} + int Client::lstat(const char *relpath, struct stat *stbuf, frag_info_t *dirstat, int mask) { @@ -4112,7 +4134,8 @@ int Client::lstat(const char *relpath, struct stat *stbuf, tout(cct) << relpath << std::endl; filepath path(relpath); Inode *in; - int r = path_walk(path, &in); + // don't follow symlinks + int r = path_walk(path, &in, false); if (r < 0) return r; r = _getattr(in, mask); diff --git a/src/client/Client.h b/src/client/Client.h index d4f61d6ed0afb..61bb2a9d536e0 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -583,6 +583,7 @@ public: int symlink(const char *existing, const char *newname); // inode stuff + int stat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); int lstat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0, int mask=CEPH_STAT_CAP_INODE_ALL); int lstatlite(const char *path, struct statlite *buf); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index e0048b9e692b4..240fbf266d525 100644 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -450,6 +450,16 @@ int ceph_rename(struct ceph_mount_info *cmount, const char *from, const char *to * @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 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); /** diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 8e1020e85e070..9828a7839b9e1 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -392,6 +392,12 @@ extern "C" int ceph_symlink(struct ceph_mount_info *cmount, const char *existing } // inode stuff +extern "C" int ceph_stat(struct ceph_mount_info *cmount, const char *path, + struct stat *stbuf) +{ + return cmount->get_client()->stat(path, stbuf); +} + extern "C" int ceph_lstat(struct ceph_mount_info *cmount, const char *path, struct stat *stbuf) { diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 77aa0cd59886d..aba593a57c87d 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -96,7 +97,7 @@ TEST(LibCephFS, Dir_ls) { ASSERT_EQ(ceph_mkdir(cmount, foostr, 0777), 0); struct stat stbuf; - ASSERT_EQ(ceph_lstat(cmount, foostr, &stbuf), 0); + ASSERT_EQ(ceph_stat(cmount, foostr, &stbuf), 0); ASSERT_NE(S_ISDIR(stbuf.st_mode), 0); char barstr[256]; -- 2.39.5