Commit 9172abbc authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Al Viro

btrfs: Use xattr handler infrastructure

Use the VFS xattr handler infrastructure and get rid of similar code in
the filesystem.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 98e9cb57
...@@ -9994,7 +9994,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { ...@@ -9994,7 +9994,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
.setattr = btrfs_setattr, .setattr = btrfs_setattr,
.mknod = btrfs_mknod, .mknod = btrfs_mknod,
.setxattr = btrfs_setxattr, .setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr, .getxattr = generic_getxattr,
.listxattr = btrfs_listxattr, .listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr, .removexattr = btrfs_removexattr,
.permission = btrfs_permission, .permission = btrfs_permission,
...@@ -10071,7 +10071,7 @@ static const struct inode_operations btrfs_file_inode_operations = { ...@@ -10071,7 +10071,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
.getattr = btrfs_getattr, .getattr = btrfs_getattr,
.setattr = btrfs_setattr, .setattr = btrfs_setattr,
.setxattr = btrfs_setxattr, .setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr, .getxattr = generic_getxattr,
.listxattr = btrfs_listxattr, .listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr, .removexattr = btrfs_removexattr,
.permission = btrfs_permission, .permission = btrfs_permission,
...@@ -10085,7 +10085,7 @@ static const struct inode_operations btrfs_special_inode_operations = { ...@@ -10085,7 +10085,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
.setattr = btrfs_setattr, .setattr = btrfs_setattr,
.permission = btrfs_permission, .permission = btrfs_permission,
.setxattr = btrfs_setxattr, .setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr, .getxattr = generic_getxattr,
.listxattr = btrfs_listxattr, .listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr, .removexattr = btrfs_removexattr,
.get_acl = btrfs_get_acl, .get_acl = btrfs_get_acl,
...@@ -10100,7 +10100,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { ...@@ -10100,7 +10100,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
.setattr = btrfs_setattr, .setattr = btrfs_setattr,
.permission = btrfs_permission, .permission = btrfs_permission,
.setxattr = btrfs_setxattr, .setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr, .getxattr = generic_getxattr,
.listxattr = btrfs_listxattr, .listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr, .removexattr = btrfs_removexattr,
.update_time = btrfs_update_time, .update_time = btrfs_update_time,
......
...@@ -351,137 +351,89 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -351,137 +351,89 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
return ret; return ret;
} }
/* static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
* List of handlers for synthetic system.* attributes. All real ondisk struct dentry *dentry, const char *name,
* attributes are handled directly. void *buffer, size_t size)
*/
const struct xattr_handler *btrfs_xattr_handlers[] = {
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
NULL,
};
/*
* Check if the attribute is in a supported namespace.
*
* This is applied after the check for the synthetic attributes in the system
* namespace.
*/
static int btrfs_is_valid_xattr(const char *name)
{ {
int len = strlen(name); struct inode *inode = d_inode(dentry);
int prefixlen = 0;
if (!strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN))
prefixlen = XATTR_SECURITY_PREFIX_LEN;
else if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
prefixlen = XATTR_SYSTEM_PREFIX_LEN;
else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
prefixlen = XATTR_TRUSTED_PREFIX_LEN;
else if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
prefixlen = XATTR_USER_PREFIX_LEN;
else if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
prefixlen = XATTR_BTRFS_PREFIX_LEN;
else
return -EOPNOTSUPP;
/*
* The name cannot consist of just prefix
*/
if (len <= prefixlen)
return -EINVAL;
return 0; name = xattr_full_name(handler, name);
return __btrfs_getxattr(inode, name, buffer, size);
} }
ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
void *buffer, size_t size) struct dentry *dentry, const char *name,
const void *buffer, size_t size,
int flags)
{ {
int ret; struct inode *inode = d_inode(dentry);
/* name = xattr_full_name(handler, name);
* If this is a request for a synthetic attribute in the system.* return __btrfs_setxattr(NULL, inode, name, buffer, size, flags);
* namespace use the generic infrastructure to resolve a handler }
* for it via sb->s_xattr.
*/
if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return generic_getxattr(dentry, name, buffer, size);
ret = btrfs_is_valid_xattr(name); static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
if (ret) struct dentry *dentry,
return ret; const char *name, const void *value,
return __btrfs_getxattr(d_inode(dentry), name, buffer, size); size_t size, int flags)
{
name = xattr_full_name(handler, name);
return btrfs_set_prop(d_inode(dentry), name, value, size, flags);
} }
static const struct xattr_handler btrfs_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = btrfs_xattr_handler_get,
.set = btrfs_xattr_handler_set,
};
static const struct xattr_handler btrfs_trusted_xattr_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.get = btrfs_xattr_handler_get,
.set = btrfs_xattr_handler_set,
};
static const struct xattr_handler btrfs_user_xattr_handler = {
.prefix = XATTR_USER_PREFIX,
.get = btrfs_xattr_handler_get,
.set = btrfs_xattr_handler_set,
};
static const struct xattr_handler btrfs_btrfs_xattr_handler = {
.prefix = XATTR_BTRFS_PREFIX,
.get = btrfs_xattr_handler_get,
.set = btrfs_xattr_handler_set_prop,
};
const struct xattr_handler *btrfs_xattr_handlers[] = {
&btrfs_security_xattr_handler,
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&btrfs_trusted_xattr_handler,
&btrfs_user_xattr_handler,
&btrfs_btrfs_xattr_handler,
NULL,
};
int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root;
int ret;
/*
* The permission on security.* and system.* is not checked
* in permission().
*/
if (btrfs_root_readonly(root)) if (btrfs_root_readonly(root))
return -EROFS; return -EROFS;
/*
* If this is a request for a synthetic attribute in the system.*
* namespace use the generic infrastructure to resolve a handler
* for it via sb->s_xattr.
*/
if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return generic_setxattr(dentry, name, value, size, flags); return generic_setxattr(dentry, name, value, size, flags);
ret = btrfs_is_valid_xattr(name);
if (ret)
return ret;
if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
return btrfs_set_prop(d_inode(dentry), name,
value, size, flags);
if (size == 0)
value = ""; /* empty EA, do not remove */
return __btrfs_setxattr(NULL, d_inode(dentry), name, value, size,
flags);
} }
int btrfs_removexattr(struct dentry *dentry, const char *name) int btrfs_removexattr(struct dentry *dentry, const char *name)
{ {
struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root;
int ret;
/*
* The permission on security.* and system.* is not checked
* in permission().
*/
if (btrfs_root_readonly(root)) if (btrfs_root_readonly(root))
return -EROFS; return -EROFS;
/*
* If this is a request for a synthetic attribute in the system.*
* namespace use the generic infrastructure to resolve a handler
* for it via sb->s_xattr.
*/
if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return generic_removexattr(dentry, name); return generic_removexattr(dentry, name);
ret = btrfs_is_valid_xattr(name);
if (ret)
return ret;
if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN))
return btrfs_set_prop(d_inode(dentry), name,
NULL, 0, XATTR_REPLACE);
return __btrfs_setxattr(NULL, d_inode(dentry), name, NULL, 0,
XATTR_REPLACE);
} }
static int btrfs_initxattrs(struct inode *inode, static int btrfs_initxattrs(struct inode *inode,
......
...@@ -28,8 +28,6 @@ extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, ...@@ -28,8 +28,6 @@ extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
extern int __btrfs_setxattr(struct btrfs_trans_handle *trans, extern int __btrfs_setxattr(struct btrfs_trans_handle *trans,
struct inode *inode, const char *name, struct inode *inode, const char *name,
const void *value, size_t size, int flags); const void *value, size_t size, int flags);
extern ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
void *buffer, size_t size);
extern int btrfs_setxattr(struct dentry *dentry, const char *name, extern int btrfs_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags); const void *value, size_t size, int flags);
extern int btrfs_removexattr(struct dentry *dentry, const char *name); extern int btrfs_removexattr(struct dentry *dentry, const char *name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment