summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Watkins <noahwatkins@gmail.com>2013-07-20 18:41:40 -0700
committerNoah Watkins <noahwatkins@gmail.com>2013-09-17 10:22:53 -0700
commit2b55b52024c1e71e2dc8b4fa67c89dc33a58f2eb (patch)
tree8acd5abf5e8099e384f7d76beaa00eb674e1ef98
parent416183546e83fd8d1a8b501b68503fe2daf56938 (diff)
downloadceph-2b55b52024c1e71e2dc8b4fa67c89dc33a58f2eb.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 6bf5ea3d34f..e7013cda83a 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 eea6edb9eb8..2ae8c57e07e 100644
--- a/src/rbd_fuse/rbd-fuse.c
+++ b/src/rbd_fuse/rbd-fuse.c
@@ -549,14 +549,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);
@@ -568,15 +571,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);
@@ -589,6 +612,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)
{