summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Watkins <noahwatkins@gmail.com>2013-07-20 18:41:40 -0700
committerNoah Watkins <noahwatkins@gmail.com>2013-07-20 18:41:40 -0700
commiteb35b16078f6b4b86d4131333f8051db3ad09d8a (patch)
tree02433ee6492f6a2542cc8fa64d12ad967720e944
parent2b14beb1b71574dd182028b4f8da456a9794e71e (diff)
downloadceph-eb35b16078f6b4b86d4131333f8051db3ad09d8a.tar.gz
fuse: support get/set xattr on OSX
On OSX, the fuse get/set xattr interfaces takes a positional argument that specifies an offset within the xattr. According to the OSX docs only the 'resource fork' extended attribute will make use of this feature and that all other attributes should set this to zero. Ceph doesn't currently support xattr offsets (at the API level at least). Therefore Ceph will return ENOTSUP if a non-zero positional argument is used. Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
-rw-r--r--src/client/fuse_ll.cc48
-rw-r--r--src/rbd_fuse/rbd-fuse.c49
2 files changed, 88 insertions, 9 deletions
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc
index ce0c6de1260..b8ac4b96b4a 100644
--- a/src/client/fuse_ll.cc
+++ b/src/client/fuse_ll.cc
@@ -151,15 +151,35 @@ static void fuse_ll_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
// XATTRS
-static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags)
+static void __fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags, uint32_t position)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
+
+ if (position) {
+ fuse_reply_err(req, -ENOTSUP);
+ return;
+ }
+
int r = cfuse->client->ll_setxattr(cfuse->fino_vino(ino), name, value, size, flags, ctx->uid, ctx->gid);
fuse_reply_err(req, -r);
}
+#ifdef __APPLE__
+static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags, uint32_t position)
+{
+ __fuse_ll_setxattr(req, ino, name, value, size, flags, position);
+}
+#else
+static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ const char *value, size_t size, int flags)
+{
+ __fuse_ll_setxattr(req, ino, name, value, size, flags, 0);
+}
+#endif
+
static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
@@ -174,11 +194,17 @@ static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
fuse_reply_err(req, -r);
}
-static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size)
+static void __fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size, uint32_t position)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
+
+ if (position) {
+ fuse_reply_err(req, -ENOTSUP);
+ return;
+ }
+
char buf[size];
int r = cfuse->client->ll_getxattr(cfuse->fino_vino(ino), name, buf, size, ctx->uid, ctx->gid);
if (size == 0 && r >= 0)
@@ -189,6 +215,20 @@ static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
fuse_reply_err(req, -r);
}
+#ifdef __APPLE__
+static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size, uint32_t position)
+{
+ __fuse_ll_getxattr(req, ino, name, size, position);
+}
+#else
+static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
+ size_t size)
+{
+ __fuse_ll_getxattr(req, ino, name, size, 0);
+}
+#endif
+
static void fuse_ll_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
diff --git a/src/rbd_fuse/rbd-fuse.c b/src/rbd_fuse/rbd-fuse.c
index 5a4bfe2702c..1d098288a5d 100644
--- a/src/rbd_fuse/rbd-fuse.c
+++ b/src/rbd_fuse/rbd-fuse.c
@@ -548,14 +548,17 @@ struct rbdfuse_attr {
{ NULL }
};
-int
-rbdfs_setxattr(const char *path, const char *name, const char *value,
- size_t size, int flags)
+static int
+__rbdfs_setxattr(const char *path, const char *name, const char *value,
+ size_t size, int flags, uint32_t position)
{
struct rbdfuse_attr *ap;
if (strcmp(path, "/") != 0)
return -EINVAL;
+ if (position)
+ return -ENOTSUP;
+
for (ap = attrs; ap->attrname != NULL; ap++) {
if (strcmp(name, ap->attrname) == 0) {
*ap->attrvalp = strtoull(value, NULL, 0);
@@ -567,15 +570,35 @@ rbdfs_setxattr(const char *path, const char *name, const char *value,
return -EINVAL;
}
+#ifdef __APPLE__
int
-rbdfs_getxattr(const char *path, const char *name, char *value,
- size_t size)
+rbdfs_setxattr(const char *path, const char *name, const char *value,
+ size_t size, int flags, uint32_t position)
+{
+ return __rbdfs_setxattr(path, name, value, size, flags, position);
+}
+#else
+int
+rbdfs_setxattr(const char *path, const char *name, const char *value,
+ size_t size, int flags)
+{
+ return __rbdfs_setxattr(path, name, value, size, flags, 0);
+}
+#endif
+
+
+static int
+__rbdfs_getxattr(const char *path, const char *name, char *value,
+ size_t size, uint32_t position)
{
struct rbdfuse_attr *ap;
char buf[128];
// allow gets on other files; ls likes to ask for things like
// security.*
+ if (position)
+ return -ENOTSUP;
+
for (ap = attrs; ap->attrname != NULL; ap++) {
if (strcmp(name, ap->attrname) == 0) {
sprintf(buf, "%"PRIu64, *ap->attrvalp);
@@ -588,6 +611,22 @@ rbdfs_getxattr(const char *path, const char *name, char *value,
return 0;
}
+#ifdef __APPLE__
+int
+rbdfs_getxattr(const char *path, const char *name, char *value,
+ size_t size, uint32_t position)
+{
+ return __rbdfs_getxattr(path, name, value, size, position);
+}
+#else
+int
+rbdfs_getxattr(const char *path, const char *name, char *value,
+ size_t size)
+{
+ return __rbdfs_getxattr(path, name, value, size, 0);
+}
+#endif
+
int
rbdfs_listxattr(const char *path, char *list, size_t len)
{