summaryrefslogtreecommitdiff
path: root/fs/ceph/xattr.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-04-14 00:30:17 +0200
committerAl Viro <viro@zeniv.linux.org.uk>2016-04-23 15:41:30 -0400
commit2cdeb1e472cf03dec4dc614623fd2e6bd8e5f271 (patch)
tree1a06b9392263f237d670f19bace3945107efd3a0 /fs/ceph/xattr.c
parenta26feccaba296bd0ae410eabce79cb3443c8a701 (diff)
ceph: Switch to generic xattr handlers
Add a catch-all xattr handler at the end of ceph_xattr_handlers. Check for valid attribute names there, and remove those checks from __ceph_{get,set,remove}xattr instead. No "system.*" xattrs need to be handled by the catch-all handler anymore. The set xattr handler is called with a NULL value to indicate that the attribute should be removed; __ceph_setxattr already handles that case correctly (ceph_set_acl could already calling __ceph_setxattr with a NULL value). Move the check for snapshots from ceph_{set,remove}xattr into __ceph_{set,remove}xattr. With that, ceph_{get,set,remove}xattr can be replaced with the generic iops. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ceph/xattr.c')
-rw-r--r--fs/ceph/xattr.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 248e32e3ae7d..8966e9d96bdb 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -16,6 +16,8 @@
static int __remove_xattr(struct ceph_inode_info *ci,
struct ceph_inode_xattr *xattr);
+const struct xattr_handler ceph_other_xattr_handler;
+
/*
* List of handlers for synthetic system.* attributes. Other
* attributes are handled directly.
@@ -25,6 +27,7 @@ const struct xattr_handler *ceph_xattr_handlers[] = {
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
+ &ceph_other_xattr_handler,
NULL,
};
@@ -33,7 +36,6 @@ static bool ceph_is_valid_xattr(const char *name)
return !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) ||
!strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN) ||
- !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) ||
!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
}
@@ -740,9 +742,6 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
int req_mask;
int err;
- if (!ceph_is_valid_xattr(name))
- return -ENODATA;
-
/* let's see if a virtual xattr was requested */
vxattr = ceph_match_vxattr(inode, name);
if (vxattr) {
@@ -804,15 +803,6 @@ out:
return err;
}
-ssize_t ceph_getxattr(struct dentry *dentry, struct inode *inode,
- const char *name, void *value, size_t size)
-{
- if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
- return generic_getxattr(dentry, inode, name, value, size);
-
- return __ceph_getxattr(inode, name, value, size);
-}
-
ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
{
struct inode *inode = d_inode(dentry);
@@ -956,8 +946,8 @@ int __ceph_setxattr(struct inode *inode, const char *name,
int required_blob_size;
bool lock_snap_rwsem = false;
- if (!ceph_is_valid_xattr(name))
- return -EOPNOTSUPP;
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
vxattr = ceph_match_vxattr(inode, name);
if (vxattr && vxattr->readonly)
@@ -1064,21 +1054,6 @@ out:
return err;
}
-int ceph_setxattr(struct dentry *dentry, const char *name,
- const void *value, size_t size, int flags)
-{
- if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP)
- return -EROFS;
-
- if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
- return generic_setxattr(dentry, name, value, size, flags);
-
- if (size == 0)
- value = ""; /* empty EA, do not remove */
-
- return __ceph_setxattr(d_inode(dentry), name, value, size, flags);
-}
-
static int ceph_send_removexattr(struct inode *inode, const char *name)
{
struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
@@ -1115,8 +1090,8 @@ static int __ceph_removexattr(struct inode *inode, const char *name)
int dirty;
bool lock_snap_rwsem = false;
- if (!ceph_is_valid_xattr(name))
- return -EOPNOTSUPP;
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
vxattr = ceph_match_vxattr(inode, name);
if (vxattr && vxattr->readonly)
@@ -1192,17 +1167,30 @@ do_sync_unlocked:
return err;
}
-int ceph_removexattr(struct dentry *dentry, const char *name)
+static int ceph_get_xattr_handler(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *name, void *value, size_t size)
{
- if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP)
- return -EROFS;
-
- if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
- return generic_removexattr(dentry, name);
+ if (!ceph_is_valid_xattr(name))
+ return -EOPNOTSUPP;
+ return __ceph_getxattr(inode, name, value, size);
+}
- return __ceph_removexattr(d_inode(dentry), name);
+static int ceph_set_xattr_handler(const struct xattr_handler *handler,
+ struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ if (!ceph_is_valid_xattr(name))
+ return -EOPNOTSUPP;
+ return __ceph_setxattr(d_inode(dentry), name, value, size, flags);
}
+const struct xattr_handler ceph_other_xattr_handler = {
+ .prefix = "", /* match any name => handlers called with full name */
+ .get = ceph_get_xattr_handler,
+ .set = ceph_set_xattr_handler,
+};
+
#ifdef CONFIG_SECURITY
bool ceph_security_xattr_wanted(struct inode *in)
{