summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/Client.cc24
-rw-r--r--src/client/Client.h4
-rw-r--r--src/client/fuse_ll.cc12
-rw-r--r--src/include/cephfs/libcephfs.h2
-rw-r--r--src/libcephfs.cc5
5 files changed, 24 insertions, 23 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 8b9185165f1..c40c75560aa 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -4349,13 +4349,18 @@ int Client::readlink(const char *relpath, char *buf, loff_t size)
int r = path_walk(path, &in, false);
if (r < 0)
return r;
-
+
+ return _readlink(in, buf, size);
+}
+
+int Client::_readlink(Inode *in, char *buf, size_t size)
+{
if (!in->is_symlink())
return -EINVAL;
// copy into buf (at most size bytes)
- r = in->symlink.length();
- if (r > size)
+ int r = in->symlink.length();
+ if (r > (int)size)
r = size;
memcpy(buf, in->symlink.c_str(), r);
return r;
@@ -7016,7 +7021,7 @@ int Client::ll_removexattr(Inode *in, const char *name, int uid, int gid)
}
-int Client::ll_readlink(Inode *in, const char **value, int uid, int gid)
+int Client::ll_readlink(Inode *in, char *buf, size_t buflen, int uid, int gid)
{
Mutex::Locker lock(client_lock);
@@ -7032,15 +7037,8 @@ int Client::ll_readlink(Inode *in, const char **value, int uid, int gid)
++dn;
}
- int r = 0;
- if (in->is_symlink()) {
- *value = in->symlink.c_str();
- } else {
- *value = "";
- r = -EINVAL;
- }
- ldout(cct, 3) << "ll_readlink " << vino << " = " << r << " (" << *value
- << ")" << dendl;
+ int r = _readlink(in, buf, buflen);
+ ldout(cct, 3) << "ll_readlink " << vino << " = " << r << dendl;
return r;
}
diff --git a/src/client/Client.h b/src/client/Client.h
index baeb8d5ebdb..f7302338584 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -555,6 +555,7 @@ private:
int _mknod(Inode *dir, const char *name, mode_t mode, dev_t rdev, int uid=-1, int gid=-1, Inode **inp = 0);
int _setattr(Inode *in, struct stat *attr, int mask, int uid=-1, int gid=-1, Inode **inp = 0);
int _getattr(Inode *in, int mask, int uid=-1, int gid=-1, bool force=false);
+ int _readlink(Inode *in, char *buf, size_t size);
int _getxattr(Inode *in, const char *name, void *value, size_t len, int uid=-1, int gid=-1);
int _listxattr(Inode *in, char *names, size_t len, int uid=-1, int gid=-1);
int _setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid=-1, int gid=-1);
@@ -638,6 +639,7 @@ public:
// symlinks
int readlink(const char *path, char *buf, loff_t size);
+
int symlink(const char *existing, const char *newname);
// inode stuff
@@ -740,7 +742,7 @@ public:
int ll_listxattr(Inode *in, char *list, size_t size, int uid=-1, int gid=-1);
int ll_opendir(Inode *in, dir_result_t **dirpp, int uid = -1, int gid = -1);
int ll_releasedir(dir_result_t* dirp);
- int ll_readlink(Inode *in, const char **value, int uid = -1, int gid = -1);
+ int ll_readlink(Inode *in, char *buf, size_t bufsize, int uid = -1, int gid = -1);
int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev,
struct stat *attr, Inode **out, int uid = -1, int gid = -1);
int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr,
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc
index 97a11f187fe..57aca0585b1 100644
--- a/src/client/fuse_ll.cc
+++ b/src/client/fuse_ll.cc
@@ -258,13 +258,15 @@ static void fuse_ll_readlink(fuse_req_t req, fuse_ino_t ino)
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
- const char *value;
+ char buf[PATH_MAX + 1]; // leave room for a null terminator
- int r = cfuse->client->ll_readlink(in, &value, ctx->uid, ctx->gid);
- if (r == 0)
- fuse_reply_readlink(req, value);
- else
+ int r = cfuse->client->ll_readlink(in, buf, sizeof(buf) - 1, ctx->uid, ctx->gid);
+ if (r >= 0) {
+ buf[r] = '\0';
+ fuse_reply_readlink(req, buf);
+ } else {
fuse_reply_err(req, -r);
+ }
cfuse->iput(in); // iput required
}
diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h
index c45c19d8c96..bf8634ff0f2 100644
--- a/src/include/cephfs/libcephfs.h
+++ b/src/include/cephfs/libcephfs.h
@@ -1291,7 +1291,7 @@ int ceph_ll_unlink(struct ceph_mount_info *cmount, struct Inode *in,
int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in,
struct statvfs *stbuf);
int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in,
- char **value, int uid, int gid);
+ char *buf, size_t bufsize, int uid, int gid);
int ceph_ll_symlink(struct ceph_mount_info *cmount, struct Inode *parent,
const char *name, const char *value, struct stat *attr,
struct Inode **in, int uid, int gid);
diff --git a/src/libcephfs.cc b/src/libcephfs.cc
index 97a51aec3c6..5f346703878 100644
--- a/src/libcephfs.cc
+++ b/src/libcephfs.cc
@@ -1374,11 +1374,10 @@ extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
}
extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount,
- Inode *in, char **value, int uid,
+ Inode *in, char *buf, size_t bufsiz, int uid,
int gid)
{
- return (cmount->get_client()->ll_readlink(in, (const char**) value,
- uid, gid));
+ return (cmount->get_client()->ll_readlink(in, buf, bufsiz, uid, gid));
}
extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,