提交 ddf1d623 编写于 作者: L Linus Torvalds

Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs xattr updates from Al Viro:
 "Andreas' xattr cleanup series.

  It's a followup to his xattr work that went in last cycle; -0.5KLoC"

* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  xattr handlers: Simplify list operation
  ocfs2: Replace list xattr handler operations
  nfs: Move call to security_inode_listsecurity into nfs_listxattr
  xfs: Change how listxattr generates synthetic attributes
  tmpfs: listxattr should include POSIX ACL xattrs
  tmpfs: Use xattr handler infrastructure
  btrfs: Use xattr handler infrastructure
  vfs: Distinguish between full xattr names and proper prefixes
  posix acls: Remove duplicate xattr name definitions
  gfs2: Remove gfs2_xattr_acl_chmod
  vfs: Remove vfs_xattr_cmp
...@@ -60,10 +60,10 @@ ...@@ -60,10 +60,10 @@
static static
int get_xattr_type(const char *name) int get_xattr_type(const char *name)
{ {
if (!strcmp(name, POSIX_ACL_XATTR_ACCESS)) if (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS))
return XATTR_ACL_ACCESS_T; return XATTR_ACL_ACCESS_T;
if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT)) if (!strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT))
return XATTR_ACL_DEFAULT_T; return XATTR_ACL_DEFAULT_T;
if (!strncmp(name, XATTR_USER_PREFIX, if (!strncmp(name, XATTR_USER_PREFIX,
......
...@@ -67,8 +67,8 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) ...@@ -67,8 +67,8 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
return 0; return 0;
} }
/* get the default/access acl values and cache them */ /* get the default/access acl values and cache them */
dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT); dacl = __v9fs_get_acl(fid, XATTR_NAME_POSIX_ACL_DEFAULT);
pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS); pacl = __v9fs_get_acl(fid, XATTR_NAME_POSIX_ACL_ACCESS);
if (!IS_ERR(dacl) && !IS_ERR(pacl)) { if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl); set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
...@@ -133,10 +133,10 @@ static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl) ...@@ -133,10 +133,10 @@ static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
goto err_free_out; goto err_free_out;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
BUG(); BUG();
...@@ -220,15 +220,12 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler, ...@@ -220,15 +220,12 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
struct posix_acl *acl; struct posix_acl *acl;
int error; int error;
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry); v9ses = v9fs_dentry2v9ses(dentry);
/* /*
* We allow set/get/list of acl when access=client is not specified * We allow set/get/list of acl when access=client is not specified
*/ */
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_xattr_get(dentry, handler->prefix, buffer, size); return v9fs_xattr_get(dentry, handler->name, buffer, size);
acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags); acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
if (IS_ERR(acl)) if (IS_ERR(acl))
...@@ -250,16 +247,13 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, ...@@ -250,16 +247,13 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry); v9ses = v9fs_dentry2v9ses(dentry);
/* /*
* set the attribute on the remote. Without even looking at the * set the attribute on the remote. Without even looking at the
* xattr value. We leave it to the server to validate * xattr value. We leave it to the server to validate
*/ */
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_xattr_set(dentry, handler->prefix, value, size, return v9fs_xattr_set(dentry, handler->name, value, size,
flags); flags);
if (S_ISLNK(inode->i_mode)) if (S_ISLNK(inode->i_mode))
...@@ -319,7 +313,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, ...@@ -319,7 +313,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
default: default:
BUG(); BUG();
} }
retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags); retval = v9fs_xattr_set(dentry, handler->name, value, size, flags);
if (!retval) if (!retval)
set_cached_acl(inode, handler->flags, acl); set_cached_acl(inode, handler->flags, acl);
err_out: err_out:
...@@ -328,14 +322,14 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, ...@@ -328,14 +322,14 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
} }
const struct xattr_handler v9fs_xattr_acl_access_handler = { const struct xattr_handler v9fs_xattr_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS, .name = XATTR_NAME_POSIX_ACL_ACCESS,
.flags = ACL_TYPE_ACCESS, .flags = ACL_TYPE_ACCESS,
.get = v9fs_xattr_get_acl, .get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl, .set = v9fs_xattr_set_acl,
}; };
const struct xattr_handler v9fs_xattr_acl_default_handler = { const struct xattr_handler v9fs_xattr_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT, .name = XATTR_NAME_POSIX_ACL_DEFAULT,
.flags = ACL_TYPE_DEFAULT, .flags = ACL_TYPE_DEFAULT,
.get = v9fs_xattr_get_acl, .get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl, .set = v9fs_xattr_set_acl,
......
...@@ -143,8 +143,6 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler, ...@@ -143,8 +143,6 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
{ {
const char *full_name = xattr_full_name(handler, name); const char *full_name = xattr_full_name(handler, name);
if (strcmp(name, "") == 0)
return -EINVAL;
return v9fs_xattr_get(dentry, full_name, buffer, size); return v9fs_xattr_get(dentry, full_name, buffer, size);
} }
...@@ -154,8 +152,6 @@ static int v9fs_xattr_handler_set(const struct xattr_handler *handler, ...@@ -154,8 +152,6 @@ static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
{ {
const char *full_name = xattr_full_name(handler, name); const char *full_name = xattr_full_name(handler, name);
if (strcmp(name, "") == 0)
return -EINVAL;
return v9fs_xattr_set(dentry, full_name, value, size, flags); return v9fs_xattr_set(dentry, full_name, value, size, flags);
} }
......
...@@ -37,10 +37,10 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) ...@@ -37,10 +37,10 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
BUG(); BUG();
...@@ -81,7 +81,7 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans, ...@@ -81,7 +81,7 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) { if (acl) {
ret = posix_acl_equiv_mode(acl, &inode->i_mode); ret = posix_acl_equiv_mode(acl, &inode->i_mode);
if (ret < 0) if (ret < 0)
...@@ -94,7 +94,7 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans, ...@@ -94,7 +94,7 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EINVAL : 0; return acl ? -EINVAL : 0;
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -3550,10 +3550,10 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf, ...@@ -3550,10 +3550,10 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf,
int scanned = 0; int scanned = 0;
if (!xattr_access) { if (!xattr_access) {
xattr_access = btrfs_name_hash(POSIX_ACL_XATTR_ACCESS, xattr_access = btrfs_name_hash(XATTR_NAME_POSIX_ACL_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS)); strlen(XATTR_NAME_POSIX_ACL_ACCESS));
xattr_default = btrfs_name_hash(POSIX_ACL_XATTR_DEFAULT, xattr_default = btrfs_name_hash(XATTR_NAME_POSIX_ACL_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT)); strlen(XATTR_NAME_POSIX_ACL_DEFAULT));
} }
slot++; slot++;
...@@ -9996,7 +9996,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { ...@@ -9996,7 +9996,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,
...@@ -10073,7 +10073,7 @@ static const struct inode_operations btrfs_file_inode_operations = { ...@@ -10073,7 +10073,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,
...@@ -10087,7 +10087,7 @@ static const struct inode_operations btrfs_special_inode_operations = { ...@@ -10087,7 +10087,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,
...@@ -10101,7 +10101,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { ...@@ -10101,7 +10101,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;
return generic_setxattr(dentry, name, value, size, flags);
/*
* 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);
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;
return generic_removexattr(dentry, name);
/*
* 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);
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);
......
...@@ -49,10 +49,10 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type) ...@@ -49,10 +49,10 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
BUG(); BUG();
...@@ -92,7 +92,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) ...@@ -92,7 +92,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) { if (acl) {
ret = posix_acl_equiv_mode(acl, &new_mode); ret = posix_acl_equiv_mode(acl, &new_mode);
if (ret < 0) if (ret < 0)
...@@ -106,7 +106,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) ...@@ -106,7 +106,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
ret = acl ? -EINVAL : 0; ret = acl ? -EINVAL : 0;
goto out; goto out;
} }
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
...@@ -202,11 +202,11 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode, ...@@ -202,11 +202,11 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
ceph_pagelist_encode_32(pagelist, acl && default_acl ? 2 : 1); ceph_pagelist_encode_32(pagelist, acl && default_acl ? 2 : 1);
if (acl) { if (acl) {
size_t len = strlen(POSIX_ACL_XATTR_ACCESS); size_t len = strlen(XATTR_NAME_POSIX_ACL_ACCESS);
err = ceph_pagelist_reserve(pagelist, len + val_size1 + 8); err = ceph_pagelist_reserve(pagelist, len + val_size1 + 8);
if (err) if (err)
goto out_err; goto out_err;
ceph_pagelist_encode_string(pagelist, POSIX_ACL_XATTR_ACCESS, ceph_pagelist_encode_string(pagelist, XATTR_NAME_POSIX_ACL_ACCESS,
len); len);
err = posix_acl_to_xattr(&init_user_ns, acl, err = posix_acl_to_xattr(&init_user_ns, acl,
tmp_buf, val_size1); tmp_buf, val_size1);
...@@ -216,12 +216,12 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode, ...@@ -216,12 +216,12 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
ceph_pagelist_append(pagelist, tmp_buf, val_size1); ceph_pagelist_append(pagelist, tmp_buf, val_size1);
} }
if (default_acl) { if (default_acl) {
size_t len = strlen(POSIX_ACL_XATTR_DEFAULT); size_t len = strlen(XATTR_NAME_POSIX_ACL_DEFAULT);
err = ceph_pagelist_reserve(pagelist, len + val_size2 + 8); err = ceph_pagelist_reserve(pagelist, len + val_size2 + 8);
if (err) if (err)
goto out_err; goto out_err;
err = ceph_pagelist_encode_string(pagelist, err = ceph_pagelist_encode_string(pagelist,
POSIX_ACL_XATTR_DEFAULT, len); XATTR_NAME_POSIX_ACL_DEFAULT, len);
err = posix_acl_to_xattr(&init_user_ns, default_acl, err = posix_acl_to_xattr(&init_user_ns, default_acl,
tmp_buf, val_size2); tmp_buf, val_size2);
if (err < 0) if (err < 0)
......
...@@ -190,8 +190,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, ...@@ -190,8 +190,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
#endif /* CONFIG_CIFS_ACL */ #endif /* CONFIG_CIFS_ACL */
} else { } else {
int temp; int temp;
temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS, temp = strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS)); strlen(XATTR_NAME_POSIX_ACL_ACCESS));
if (temp == 0) { if (temp == 0) {
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & MS_POSIXACL) if (sb->s_flags & MS_POSIXACL)
...@@ -203,8 +203,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, ...@@ -203,8 +203,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
#else #else
cifs_dbg(FYI, "set POSIX ACL not supported\n"); cifs_dbg(FYI, "set POSIX ACL not supported\n");
#endif #endif
} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) {
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & MS_POSIXACL) if (sb->s_flags & MS_POSIXACL)
rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
...@@ -292,8 +292,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, ...@@ -292,8 +292,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
full_path, ea_name, ea_value, buf_size, full_path, ea_name, ea_value, buf_size,
cifs_sb->local_nls, cifs_remap(cifs_sb)); cifs_sb->local_nls, cifs_remap(cifs_sb));
} else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS, } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { strlen(XATTR_NAME_POSIX_ACL_ACCESS)) == 0) {
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & MS_POSIXACL) if (sb->s_flags & MS_POSIXACL)
rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
...@@ -303,8 +303,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, ...@@ -303,8 +303,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
#else #else
cifs_dbg(FYI, "Query POSIX ACL not supported yet\n"); cifs_dbg(FYI, "Query POSIX ACL not supported yet\n");
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) {
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & MS_POSIXACL) if (sb->s_flags & MS_POSIXACL)
rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
......
...@@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", ...@@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
const struct xattr_handler *handler = const struct xattr_handler *handler =
ext2_xattr_handler(entry->e_name_index); ext2_xattr_handler(entry->e_name_index);
if (handler) { if (handler && (!handler->list || handler->list(dentry))) {
size_t size = handler->list(handler, dentry, buffer, const char *prefix = handler->prefix ?: handler->name;
rest, entry->e_name, size_t prefix_len = strlen(prefix);
entry->e_name_len); size_t size = prefix_len + entry->e_name_len + 1;
if (buffer) { if (buffer) {
if (size > rest) { if (size > rest) {
error = -ERANGE; error = -ERANGE;
goto cleanup; goto cleanup;
} }
buffer += size; memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
} }
rest -= size; rest -= size;
} }
......
...@@ -7,29 +7,11 @@ ...@@ -7,29 +7,11 @@
#include <linux/security.h> #include <linux/security.h>
#include "xattr.h" #include "xattr.h"
static size_t
ext2_xattr_security_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{
const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
const size_t total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int static int
ext2_xattr_security_get(const struct xattr_handler *handler, ext2_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
buffer, size); buffer, size);
} }
...@@ -39,8 +21,6 @@ ext2_xattr_security_set(const struct xattr_handler *handler, ...@@ -39,8 +21,6 @@ ext2_xattr_security_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name, return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
value, size, flags); value, size, flags);
} }
...@@ -71,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir, ...@@ -71,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir,
const struct xattr_handler ext2_xattr_security_handler = { const struct xattr_handler ext2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list,
.get = ext2_xattr_security_get, .get = ext2_xattr_security_get,
.set = ext2_xattr_security_set, .set = ext2_xattr_security_set,
}; };
...@@ -8,23 +8,10 @@ ...@@ -8,23 +8,10 @@
#include "ext2.h" #include "ext2.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext2_xattr_trusted_list(const struct xattr_handler *handler, ext2_xattr_trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; return capable(CAP_SYS_ADMIN);
const size_t total_len = prefix_len + name_len + 1;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
...@@ -32,8 +19,6 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler, ...@@ -32,8 +19,6 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
buffer, size); buffer, size);
} }
...@@ -43,8 +28,6 @@ ext2_xattr_trusted_set(const struct xattr_handler *handler, ...@@ -43,8 +28,6 @@ ext2_xattr_trusted_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
value, size, flags); value, size, flags);
} }
......
...@@ -10,23 +10,10 @@ ...@@ -10,23 +10,10 @@
#include "ext2.h" #include "ext2.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext2_xattr_user_list(const struct xattr_handler *handler, ext2_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_USER_PREFIX_LEN; return test_opt(dentry->d_sb, XATTR_USER);
const size_t total_len = prefix_len + name_len + 1;
if (!test_opt(dentry->d_sb, XATTR_USER))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
...@@ -34,8 +21,6 @@ ext2_xattr_user_get(const struct xattr_handler *handler, ...@@ -34,8 +21,6 @@ ext2_xattr_user_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
if (!test_opt(dentry->d_sb, XATTR_USER)) if (!test_opt(dentry->d_sb, XATTR_USER))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_USER, return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_USER,
...@@ -47,8 +32,6 @@ ext2_xattr_user_set(const struct xattr_handler *handler, ...@@ -47,8 +32,6 @@ ext2_xattr_user_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
if (!test_opt(dentry->d_sb, XATTR_USER)) if (!test_opt(dentry->d_sb, XATTR_USER))
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, ...@@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
const struct xattr_handler *handler = const struct xattr_handler *handler =
ext4_xattr_handler(entry->e_name_index); ext4_xattr_handler(entry->e_name_index);
if (handler) { if (handler && (!handler->list || handler->list(dentry))) {
size_t size = handler->list(handler, dentry, buffer, const char *prefix = handler->prefix ?: handler->name;
rest, entry->e_name, size_t prefix_len = strlen(prefix);
entry->e_name_len); size_t size = prefix_len + entry->e_name_len + 1;
if (buffer) { if (buffer) {
if (size > rest) if (size > rest)
return -ERANGE; return -ERANGE;
buffer += size; memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
} }
rest -= size; rest -= size;
} }
} }
return buffer_size - rest; return buffer_size - rest; /* total size */
} }
static int static int
......
...@@ -11,30 +11,11 @@ ...@@ -11,30 +11,11 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t
ext4_xattr_security_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{
const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;
const size_t total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int static int
ext4_xattr_security_get(const struct xattr_handler *handler, ext4_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY,
name, buffer, size); name, buffer, size);
} }
...@@ -44,8 +25,6 @@ ext4_xattr_security_set(const struct xattr_handler *handler, ...@@ -44,8 +25,6 @@ ext4_xattr_security_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY, return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY,
name, value, size, flags); name, value, size, flags);
} }
...@@ -79,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, ...@@ -79,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct xattr_handler ext4_xattr_security_handler = { const struct xattr_handler ext4_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext4_xattr_security_list,
.get = ext4_xattr_security_get, .get = ext4_xattr_security_get,
.set = ext4_xattr_security_set, .set = ext4_xattr_security_set,
}; };
...@@ -12,23 +12,10 @@ ...@@ -12,23 +12,10 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext4_xattr_trusted_list(const struct xattr_handler *handler, ext4_xattr_trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; return capable(CAP_SYS_ADMIN);
const size_t total_len = prefix_len + name_len + 1;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
...@@ -36,8 +23,6 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler, ...@@ -36,8 +23,6 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, void *buffer, struct dentry *dentry, const char *name, void *buffer,
size_t size) size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED,
name, buffer, size); name, buffer, size);
} }
...@@ -47,8 +32,6 @@ ext4_xattr_trusted_set(const struct xattr_handler *handler, ...@@ -47,8 +32,6 @@ ext4_xattr_trusted_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED, return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED,
name, value, size, flags); name, value, size, flags);
} }
......
...@@ -11,23 +11,10 @@ ...@@ -11,23 +11,10 @@
#include "ext4.h" #include "ext4.h"
#include "xattr.h" #include "xattr.h"
static size_t static bool
ext4_xattr_user_list(const struct xattr_handler *handler, ext4_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t prefix_len = XATTR_USER_PREFIX_LEN; return test_opt(dentry->d_sb, XATTR_USER);
const size_t total_len = prefix_len + name_len + 1;
if (!test_opt(dentry->d_sb, XATTR_USER))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
} }
static int static int
...@@ -35,8 +22,6 @@ ext4_xattr_user_get(const struct xattr_handler *handler, ...@@ -35,8 +22,6 @@ ext4_xattr_user_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
if (!test_opt(dentry->d_sb, XATTR_USER)) if (!test_opt(dentry->d_sb, XATTR_USER))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_USER, return ext4_xattr_get(d_inode(dentry), EXT4_XATTR_INDEX_USER,
...@@ -48,8 +33,6 @@ ext4_xattr_user_set(const struct xattr_handler *handler, ...@@ -48,8 +33,6 @@ ext4_xattr_user_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
if (!test_opt(dentry->d_sb, XATTR_USER)) if (!test_opt(dentry->d_sb, XATTR_USER))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER, return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER,
......
...@@ -25,38 +25,6 @@ ...@@ -25,38 +25,6 @@
#include "f2fs.h" #include "f2fs.h"
#include "xattr.h" #include "xattr.h"
static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t len)
{
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
int total_len, prefix_len;
switch (handler->flags) {
case F2FS_XATTR_INDEX_USER:
if (!test_opt(sbi, XATTR_USER))
return -EOPNOTSUPP;
break;
case F2FS_XATTR_INDEX_TRUSTED:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break;
case F2FS_XATTR_INDEX_SECURITY:
break;
default:
return -EINVAL;
}
prefix_len = strlen(handler->prefix);
total_len = prefix_len + len + 1;
if (list && total_len <= list_size) {
memcpy(list, handler->prefix, prefix_len);
memcpy(list + prefix_len, name, len);
list[prefix_len + len] = '\0';
}
return total_len;
}
static int f2fs_xattr_generic_get(const struct xattr_handler *handler, static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, void *buffer, struct dentry *dentry, const char *name, void *buffer,
size_t size) size_t size)
...@@ -77,8 +45,6 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler, ...@@ -77,8 +45,6 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
default: default:
return -EINVAL; return -EINVAL;
} }
if (strcmp(name, "") == 0)
return -EINVAL;
return f2fs_getxattr(d_inode(dentry), handler->flags, name, return f2fs_getxattr(d_inode(dentry), handler->flags, name,
buffer, size, NULL); buffer, size, NULL);
} }
...@@ -103,24 +69,20 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler, ...@@ -103,24 +69,20 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
default: default:
return -EINVAL; return -EINVAL;
} }
if (strcmp(name, "") == 0)
return -EINVAL;
return f2fs_setxattr(d_inode(dentry), handler->flags, name, return f2fs_setxattr(d_inode(dentry), handler->flags, name,
value, size, NULL, flags); value, size, NULL, flags);
} }
static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, static bool f2fs_xattr_user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t len)
{ {
const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
size_t size;
size = strlen(xname) + 1; return test_opt(sbi, XATTR_USER);
if (list && size <= list_size) }
memcpy(list, xname, size);
return size; static bool f2fs_xattr_trusted_list(struct dentry *dentry)
{
return capable(CAP_SYS_ADMIN);
} }
static int f2fs_xattr_advise_get(const struct xattr_handler *handler, static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
...@@ -129,9 +91,6 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler, ...@@ -129,9 +91,6 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
{ {
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
if (strcmp(name, "") != 0)
return -EINVAL;
if (buffer) if (buffer)
*((char *)buffer) = F2FS_I(inode)->i_advise; *((char *)buffer) = F2FS_I(inode)->i_advise;
return sizeof(char); return sizeof(char);
...@@ -143,8 +102,6 @@ static int f2fs_xattr_advise_set(const struct xattr_handler *handler, ...@@ -143,8 +102,6 @@ static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
{ {
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
if (strcmp(name, "") != 0)
return -EINVAL;
if (!inode_owner_or_capable(inode)) if (!inode_owner_or_capable(inode))
return -EPERM; return -EPERM;
if (value == NULL) if (value == NULL)
...@@ -183,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir, ...@@ -183,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir,
const struct xattr_handler f2fs_xattr_user_handler = { const struct xattr_handler f2fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.flags = F2FS_XATTR_INDEX_USER, .flags = F2FS_XATTR_INDEX_USER,
.list = f2fs_xattr_generic_list, .list = f2fs_xattr_user_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
...@@ -191,15 +148,14 @@ const struct xattr_handler f2fs_xattr_user_handler = { ...@@ -191,15 +148,14 @@ const struct xattr_handler f2fs_xattr_user_handler = {
const struct xattr_handler f2fs_xattr_trusted_handler = { const struct xattr_handler f2fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX, .prefix = XATTR_TRUSTED_PREFIX,
.flags = F2FS_XATTR_INDEX_TRUSTED, .flags = F2FS_XATTR_INDEX_TRUSTED,
.list = f2fs_xattr_generic_list, .list = f2fs_xattr_trusted_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
const struct xattr_handler f2fs_xattr_advise_handler = { const struct xattr_handler f2fs_xattr_advise_handler = {
.prefix = F2FS_SYSTEM_ADVISE_PREFIX, .name = F2FS_SYSTEM_ADVISE_NAME,
.flags = F2FS_XATTR_INDEX_ADVISE, .flags = F2FS_XATTR_INDEX_ADVISE,
.list = f2fs_xattr_advise_list,
.get = f2fs_xattr_advise_get, .get = f2fs_xattr_advise_get,
.set = f2fs_xattr_advise_set, .set = f2fs_xattr_advise_set,
}; };
...@@ -207,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = { ...@@ -207,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
const struct xattr_handler f2fs_xattr_security_handler = { const struct xattr_handler f2fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.flags = F2FS_XATTR_INDEX_SECURITY, .flags = F2FS_XATTR_INDEX_SECURITY,
.list = f2fs_xattr_generic_list,
.get = f2fs_xattr_generic_get, .get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set, .set = f2fs_xattr_generic_set,
}; };
...@@ -455,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -455,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
list_for_each_xattr(entry, base_addr) { list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler = const struct xattr_handler *handler =
f2fs_xattr_handler(entry->e_name_index); f2fs_xattr_handler(entry->e_name_index);
const char *prefix;
size_t prefix_len;
size_t size; size_t size;
if (!handler) if (!handler || (handler->list && !handler->list(dentry)))
continue; continue;
size = handler->list(handler, dentry, buffer, rest, prefix = handler->prefix ?: handler->name;
entry->e_name, entry->e_name_len); prefix_len = strlen(prefix);
if (buffer && size > rest) { size = prefix_len + entry->e_name_len + 1;
error = -ERANGE; if (buffer) {
goto cleanup; if (size > rest) {
error = -ERANGE;
goto cleanup;
}
memcpy(buffer, prefix, prefix_len);
buffer += prefix_len;
memcpy(buffer, entry->e_name, entry->e_name_len);
buffer += entry->e_name_len;
*buffer++ = 0;
} }
if (buffer)
buffer += size;
rest -= size; rest -= size;
} }
error = buffer_size - rest; error = buffer_size - rest;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define F2FS_XATTR_REFCOUNT_MAX 1024 #define F2FS_XATTR_REFCOUNT_MAX 1024
/* Name indexes */ /* Name indexes */
#define F2FS_SYSTEM_ADVISE_PREFIX "system.advise" #define F2FS_SYSTEM_ADVISE_NAME "system.advise"
#define F2FS_XATTR_INDEX_USER 1 #define F2FS_XATTR_INDEX_USER 1
#define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2 #define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2
#define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 #define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3
......
...@@ -31,9 +31,9 @@ static const char *gfs2_acl_name(int type) ...@@ -31,9 +31,9 @@ static const char *gfs2_acl_name(int type)
{ {
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
return GFS2_POSIX_ACL_ACCESS; return XATTR_POSIX_ACL_ACCESS;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
return GFS2_POSIX_ACL_DEFAULT; return XATTR_POSIX_ACL_DEFAULT;
} }
return NULL; return NULL;
} }
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
#include "incore.h" #include "incore.h"
#define GFS2_POSIX_ACL_ACCESS "posix_acl_access"
#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default"
#define GFS2_ACL_MAX_ENTRIES(sdp) ((300 << (sdp)->sd_sb.sb_bsize_shift) >> 12) #define GFS2_ACL_MAX_ENTRIES(sdp) ((300 << (sdp)->sd_sb.sb_bsize_shift) >> 12)
extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type);
......
...@@ -1237,56 +1237,6 @@ static int gfs2_xattr_set(const struct xattr_handler *handler, ...@@ -1237,56 +1237,6 @@ static int gfs2_xattr_set(const struct xattr_handler *handler,
size, flags, handler->flags); size, flags, handler->flags);
} }
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
struct gfs2_ea_header *ea, char *data)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
unsigned int amount = GFS2_EA_DATA_LEN(ea);
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
int ret;
ret = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
if (ret)
return ret;
ret = gfs2_iter_unstuffed(ip, ea, data, NULL);
gfs2_trans_end(sdp);
return ret;
}
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
{
struct inode *inode = &ip->i_inode;
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_ea_location el;
int error;
error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el);
if (error)
return error;
if (GFS2_EA_IS_STUFFED(el.el_ea)) {
error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0);
if (error == 0) {
gfs2_trans_add_meta(ip->i_gl, el.el_bh);
memcpy(GFS2_EA2DATA(el.el_ea), data,
GFS2_EA_DATA_LEN(el.el_ea));
}
} else {
error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
}
brelse(el.el_bh);
if (error)
return error;
error = gfs2_setattr_simple(inode, attr);
gfs2_trans_end(sdp);
return error;
}
static int ea_dealloc_indirect(struct gfs2_inode *ip) static int ea_dealloc_indirect(struct gfs2_inode *ip)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
......
...@@ -62,6 +62,5 @@ extern int gfs2_ea_dealloc(struct gfs2_inode *ip); ...@@ -62,6 +62,5 @@ extern int gfs2_ea_dealloc(struct gfs2_inode *ip);
/* Exported to acl.c */ /* Exported to acl.c */
extern int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **data); extern int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **data);
extern int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data);
#endif /* __EATTR_DOT_H__ */ #endif /* __EATTR_DOT_H__ */
...@@ -21,10 +21,10 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type) ...@@ -21,10 +21,10 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
xattr_name = POSIX_ACL_XATTR_ACCESS; xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
xattr_name = POSIX_ACL_XATTR_DEFAULT; xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -66,7 +66,7 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, ...@@ -66,7 +66,7 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
xattr_name = POSIX_ACL_XATTR_ACCESS; xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) { if (acl) {
err = posix_acl_equiv_mode(acl, &inode->i_mode); err = posix_acl_equiv_mode(acl, &inode->i_mode);
if (err < 0) if (err < 0)
...@@ -76,7 +76,7 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, ...@@ -76,7 +76,7 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
xattr_name = POSIX_ACL_XATTR_DEFAULT; xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
break; break;
......
...@@ -431,9 +431,6 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name, ...@@ -431,9 +431,6 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
char *xattr_name; char *xattr_name;
int res; int res;
if (!strcmp(name, ""))
return -EINVAL;
xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1,
GFP_KERNEL); GFP_KERNEL);
if (!xattr_name) if (!xattr_name)
...@@ -589,9 +586,6 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, ...@@ -589,9 +586,6 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
int res; int res;
char *xattr_name; char *xattr_name;
if (!strcmp(name, ""))
return -EINVAL;
xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1,
GFP_KERNEL); GFP_KERNEL);
if (!xattr_name) if (!xattr_name)
...@@ -853,9 +847,6 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler, ...@@ -853,9 +847,6 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (!strcmp(name, ""))
return -EINVAL;
/* /*
* Don't allow retrieving properly prefixed attributes * Don't allow retrieving properly prefixed attributes
* by prepending them with "osx." * by prepending them with "osx."
...@@ -876,9 +867,6 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler, ...@@ -876,9 +867,6 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *buffer, size_t size, int flags) const void *buffer, size_t size, int flags)
{ {
if (!strcmp(name, ""))
return -EINVAL;
/* /*
* Don't allow setting properly prefixed attributes * Don't allow setting properly prefixed attributes
* by prepending them with "osx." * by prepending them with "osx."
......
...@@ -52,9 +52,6 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler, ...@@ -52,9 +52,6 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY,
name, buffer, size); name, buffer, size);
} }
...@@ -63,31 +60,12 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler, ...@@ -63,31 +60,12 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *buffer, size_t size, int flags) const void *buffer, size_t size, int flags)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY, return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_security_listxattr(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
if (list && retlen <= list_size) {
strcpy(list, XATTR_SECURITY_PREFIX);
strcpy(list + XATTR_SECURITY_PREFIX_LEN, name);
}
return retlen;
}
const struct xattr_handler jffs2_security_xattr_handler = { const struct xattr_handler jffs2_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = jffs2_security_listxattr,
.set = jffs2_security_setxattr, .set = jffs2_security_setxattr,
.get = jffs2_security_getxattr .get = jffs2_security_getxattr
}; };
...@@ -967,7 +967,8 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -967,7 +967,8 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct jffs2_xattr_ref *ref, **pref; struct jffs2_xattr_ref *ref, **pref;
struct jffs2_xattr_datum *xd; struct jffs2_xattr_datum *xd;
const struct xattr_handler *xhandle; const struct xattr_handler *xhandle;
ssize_t len, rc; const char *prefix;
ssize_t prefix_len, len, rc;
int retry = 0; int retry = 0;
rc = check_xattr_ref_inode(c, ic); rc = check_xattr_ref_inode(c, ic);
...@@ -998,18 +999,23 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -998,18 +999,23 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
} }
} }
xhandle = xprefix_to_handler(xd->xprefix); xhandle = xprefix_to_handler(xd->xprefix);
if (!xhandle) if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
continue; continue;
prefix = xhandle->prefix ?: xhandle->name;
prefix_len = strlen(prefix);
rc = prefix_len + xd->name_len + 1;
if (buffer) { if (buffer) {
rc = xhandle->list(xhandle, dentry, buffer + len, if (rc > size - len) {
size - len, xd->xname, rc = -ERANGE;
xd->name_len); goto out;
} else { }
rc = xhandle->list(xhandle, dentry, NULL, 0, memcpy(buffer, prefix, prefix_len);
xd->xname, xd->name_len); buffer += prefix_len;
memcpy(buffer, xd->xname, xd->name_len);
buffer += xd->name_len;
*buffer++ = 0;
} }
if (rc < 0)
goto out;
len += rc; len += rc;
} }
rc = len; rc = len;
......
...@@ -20,8 +20,6 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler, ...@@ -20,8 +20,6 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED,
name, buffer, size); name, buffer, size);
} }
...@@ -30,28 +28,13 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler, ...@@ -30,28 +28,13 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *buffer, size_t size, int flags) const void *buffer, size_t size, int flags)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED, return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_trusted_listxattr(const struct xattr_handler *handler, static bool jffs2_trusted_listxattr(struct dentry *dentry)
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{ {
size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; return capable(CAP_SYS_ADMIN);
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && retlen<=list_size) {
strcpy(list, XATTR_TRUSTED_PREFIX);
strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
}
return retlen;
} }
const struct xattr_handler jffs2_trusted_xattr_handler = { const struct xattr_handler jffs2_trusted_xattr_handler = {
......
...@@ -20,8 +20,6 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler, ...@@ -20,8 +20,6 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_USER, return do_jffs2_getxattr(d_inode(dentry), JFFS2_XPREFIX_USER,
name, buffer, size); name, buffer, size);
} }
...@@ -30,30 +28,12 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler, ...@@ -30,30 +28,12 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *buffer, size_t size, int flags) const void *buffer, size_t size, int flags)
{ {
if (!strcmp(name, ""))
return -EINVAL;
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER, return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER,
name, buffer, size, flags); name, buffer, size, flags);
} }
static size_t jffs2_user_listxattr(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
if (list && retlen <= list_size) {
strcpy(list, XATTR_USER_PREFIX);
strcpy(list + XATTR_USER_PREFIX_LEN, name);
}
return retlen;
}
const struct xattr_handler jffs2_user_xattr_handler = { const struct xattr_handler jffs2_user_xattr_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.list = jffs2_user_listxattr,
.set = jffs2_user_setxattr, .set = jffs2_user_setxattr,
.get = jffs2_user_getxattr .get = jffs2_user_getxattr
}; };
...@@ -40,10 +40,10 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type) ...@@ -40,10 +40,10 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type)
switch(type) { switch(type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS; ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT; ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -82,7 +82,7 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type, ...@@ -82,7 +82,7 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS; ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) { if (acl) {
rc = posix_acl_equiv_mode(acl, &inode->i_mode); rc = posix_acl_equiv_mode(acl, &inode->i_mode);
if (rc < 0) if (rc < 0)
...@@ -94,7 +94,7 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type, ...@@ -94,7 +94,7 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
} }
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT; ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -205,7 +205,7 @@ int kernfs_iop_removexattr(struct dentry *dentry, const char *name) ...@@ -205,7 +205,7 @@ int kernfs_iop_removexattr(struct dentry *dentry, const char *name)
if (!attrs) if (!attrs)
return -ENOMEM; return -ENOMEM;
return simple_xattr_remove(&attrs->xattrs, name); return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE);
} }
ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf, ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf,
...@@ -230,7 +230,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) ...@@ -230,7 +230,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
if (!attrs) if (!attrs)
return -ENOMEM; return -ENOMEM;
return simple_xattr_list(&attrs->xattrs, buf, size); return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size);
} }
static inline void set_default_inode_attr(struct inode *inode, umode_t mode) static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
......
...@@ -284,12 +284,12 @@ nfs3_listxattr(struct dentry *dentry, char *data, size_t size) ...@@ -284,12 +284,12 @@ nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
int error; int error;
error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS, error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
POSIX_ACL_XATTR_ACCESS, data, size, &result); XATTR_NAME_POSIX_ACL_ACCESS, data, size, &result);
if (error) if (error)
return error; return error;
error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT, error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
POSIX_ACL_XATTR_DEFAULT, data, size, &result); XATTR_NAME_POSIX_ACL_DEFAULT, data, size, &result);
if (error) if (error)
return error; return error;
return result; return result;
......
...@@ -6253,9 +6253,6 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, ...@@ -6253,9 +6253,6 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
const void *buf, size_t buflen, const void *buf, size_t buflen,
int flags) int flags)
{ {
if (strcmp(key, "") != 0)
return -EINVAL;
return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
} }
...@@ -6263,32 +6260,15 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, ...@@ -6263,32 +6260,15 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
struct dentry *dentry, const char *key, struct dentry *dentry, const char *key,
void *buf, size_t buflen) void *buf, size_t buflen)
{ {
if (strcmp(key, "") != 0)
return -EINVAL;
return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
} }
static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler, static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
struct dentry *dentry, char *list,
size_t list_len, const char *name,
size_t name_len)
{ {
size_t len = sizeof(XATTR_NAME_NFSV4_ACL); return nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)));
if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry))))
return 0;
if (list && len <= list_len)
memcpy(list, XATTR_NAME_NFSV4_ACL, len);
return len;
} }
#ifdef CONFIG_NFS_V4_SECURITY_LABEL #ifdef CONFIG_NFS_V4_SECURITY_LABEL
static inline int nfs4_server_supports_labels(struct nfs_server *server)
{
return server->caps & NFS_CAP_SECURITY_LABEL;
}
static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler, static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
struct dentry *dentry, const char *key, struct dentry *dentry, const char *key,
...@@ -6310,29 +6290,34 @@ static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler, ...@@ -6310,29 +6290,34 @@ static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static size_t nfs4_xattr_list_nfs4_label(const struct xattr_handler *handler, static ssize_t
struct dentry *dentry, char *list, nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)
size_t list_len, const char *name,
size_t name_len)
{ {
size_t len = 0; int len = 0;
if (nfs_server_capable(d_inode(dentry), NFS_CAP_SECURITY_LABEL)) { if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL)) {
len = security_inode_listsecurity(d_inode(dentry), NULL, 0); len = security_inode_listsecurity(inode, list, list_len);
if (list && len <= list_len) if (list_len && len > list_len)
security_inode_listsecurity(d_inode(dentry), list, len); return -ERANGE;
} }
return len; return len;
} }
static const struct xattr_handler nfs4_xattr_nfs4_label_handler = { static const struct xattr_handler nfs4_xattr_nfs4_label_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = nfs4_xattr_list_nfs4_label,
.get = nfs4_xattr_get_nfs4_label, .get = nfs4_xattr_get_nfs4_label,
.set = nfs4_xattr_set_nfs4_label, .set = nfs4_xattr_set_nfs4_label,
}; };
#endif
#else
static ssize_t
nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)
{
return 0;
}
#endif
/* /*
* nfs_fhget will use either the mounted_on_fileid or the fileid * nfs_fhget will use either the mounted_on_fileid or the fileid
...@@ -8749,6 +8734,24 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = { ...@@ -8749,6 +8734,24 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
#endif #endif
}; };
ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
{
ssize_t error, error2;
error = generic_listxattr(dentry, list, size);
if (error < 0)
return error;
if (list) {
list += error;
size -= error;
}
error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size);
if (error2 < 0)
return error2;
return error + error2;
}
static const struct inode_operations nfs4_dir_inode_operations = { static const struct inode_operations nfs4_dir_inode_operations = {
.create = nfs_create, .create = nfs_create,
.lookup = nfs_lookup, .lookup = nfs_lookup,
...@@ -8765,7 +8768,7 @@ static const struct inode_operations nfs4_dir_inode_operations = { ...@@ -8765,7 +8768,7 @@ static const struct inode_operations nfs4_dir_inode_operations = {
.setattr = nfs_setattr, .setattr = nfs_setattr,
.getxattr = generic_getxattr, .getxattr = generic_getxattr,
.setxattr = generic_setxattr, .setxattr = generic_setxattr,
.listxattr = generic_listxattr, .listxattr = nfs4_listxattr,
.removexattr = generic_removexattr, .removexattr = generic_removexattr,
}; };
...@@ -8775,7 +8778,7 @@ static const struct inode_operations nfs4_file_inode_operations = { ...@@ -8775,7 +8778,7 @@ static const struct inode_operations nfs4_file_inode_operations = {
.setattr = nfs_setattr, .setattr = nfs_setattr,
.getxattr = generic_getxattr, .getxattr = generic_getxattr,
.setxattr = generic_setxattr, .setxattr = generic_setxattr,
.listxattr = generic_listxattr, .listxattr = nfs4_listxattr,
.removexattr = generic_removexattr, .removexattr = generic_removexattr,
}; };
...@@ -8834,7 +8837,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { ...@@ -8834,7 +8837,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
}; };
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
.prefix = XATTR_NAME_NFSV4_ACL, .name = XATTR_NAME_NFSV4_ACL,
.list = nfs4_xattr_list_nfs4_acl, .list = nfs4_xattr_list_nfs4_acl,
.get = nfs4_xattr_get_nfs4_acl, .get = nfs4_xattr_get_nfs4_acl,
.set = nfs4_xattr_set_nfs4_acl, .set = nfs4_xattr_set_nfs4_acl,
......
...@@ -544,8 +544,7 @@ static inline const char *ocfs2_xattr_prefix(int name_index) ...@@ -544,8 +544,7 @@ static inline const char *ocfs2_xattr_prefix(int name_index)
if (name_index > 0 && name_index < OCFS2_XATTR_MAX) if (name_index > 0 && name_index < OCFS2_XATTR_MAX)
handler = ocfs2_xattr_handler_map[name_index]; handler = ocfs2_xattr_handler_map[name_index];
return handler ? xattr_prefix(handler) : NULL;
return handler ? handler->prefix : NULL;
} }
static u32 ocfs2_xattr_name_hash(struct inode *inode, static u32 ocfs2_xattr_name_hash(struct inode *inode,
...@@ -884,14 +883,39 @@ static int ocfs2_xattr_value_truncate(struct inode *inode, ...@@ -884,14 +883,39 @@ static int ocfs2_xattr_value_truncate(struct inode *inode,
return ret; return ret;
} }
static int ocfs2_xattr_list_entry(char *buffer, size_t size, static int ocfs2_xattr_list_entry(struct super_block *sb,
size_t *result, const char *prefix, char *buffer, size_t size,
size_t *result, int type,
const char *name, int name_len) const char *name, int name_len)
{ {
char *p = buffer + *result; char *p = buffer + *result;
int prefix_len = strlen(prefix); const char *prefix;
int total_len = prefix_len + name_len + 1; int prefix_len;
int total_len;
switch(type) {
case OCFS2_XATTR_INDEX_USER:
if (OCFS2_SB(sb)->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
return 0;
break;
case OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS:
case OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT:
if (!(sb->s_flags & MS_POSIXACL))
return 0;
break;
case OCFS2_XATTR_INDEX_TRUSTED:
if (!capable(CAP_SYS_ADMIN))
return 0;
break;
}
prefix = ocfs2_xattr_prefix(type);
if (!prefix)
return 0;
prefix_len = strlen(prefix);
total_len = prefix_len + name_len + 1;
*result += total_len; *result += total_len;
/* we are just looking for how big our buffer needs to be */ /* we are just looking for how big our buffer needs to be */
...@@ -914,23 +938,20 @@ static int ocfs2_xattr_list_entries(struct inode *inode, ...@@ -914,23 +938,20 @@ static int ocfs2_xattr_list_entries(struct inode *inode,
{ {
size_t result = 0; size_t result = 0;
int i, type, ret; int i, type, ret;
const char *prefix, *name; const char *name;
for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) { for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) {
struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
type = ocfs2_xattr_get_type(entry); type = ocfs2_xattr_get_type(entry);
prefix = ocfs2_xattr_prefix(type); name = (const char *)header +
le16_to_cpu(entry->xe_name_offset);
if (prefix) {
name = (const char *)header +
le16_to_cpu(entry->xe_name_offset);
ret = ocfs2_xattr_list_entry(buffer, buffer_size, ret = ocfs2_xattr_list_entry(inode->i_sb,
&result, prefix, name, buffer, buffer_size,
entry->xe_name_len); &result, type, name,
if (ret) entry->xe_name_len);
return ret; if (ret)
} return ret;
} }
return result; return result;
...@@ -4033,32 +4054,30 @@ static int ocfs2_list_xattr_bucket(struct inode *inode, ...@@ -4033,32 +4054,30 @@ static int ocfs2_list_xattr_bucket(struct inode *inode,
int ret = 0, type; int ret = 0, type;
struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para; struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para;
int i, block_off, new_offset; int i, block_off, new_offset;
const char *prefix, *name; const char *name;
for (i = 0 ; i < le16_to_cpu(bucket_xh(bucket)->xh_count); i++) { for (i = 0 ; i < le16_to_cpu(bucket_xh(bucket)->xh_count); i++) {
struct ocfs2_xattr_entry *entry = &bucket_xh(bucket)->xh_entries[i]; struct ocfs2_xattr_entry *entry = &bucket_xh(bucket)->xh_entries[i];
type = ocfs2_xattr_get_type(entry); type = ocfs2_xattr_get_type(entry);
prefix = ocfs2_xattr_prefix(type);
if (prefix) { ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, bucket_xh(bucket),
bucket_xh(bucket), i,
i, &block_off,
&block_off, &new_offset);
&new_offset); if (ret)
if (ret) break;
break;
name = (const char *)bucket_block(bucket, block_off) + name = (const char *)bucket_block(bucket, block_off) +
new_offset; new_offset;
ret = ocfs2_xattr_list_entry(xl->buffer, ret = ocfs2_xattr_list_entry(inode->i_sb,
xl->buffer_size, xl->buffer,
&xl->result, xl->buffer_size,
prefix, name, &xl->result,
entry->xe_name_len); type, name,
if (ret) entry->xe_name_len);
break; if (ret)
} break;
} }
return ret; return ret;
...@@ -7226,31 +7245,14 @@ int ocfs2_init_security_and_acl(struct inode *dir, ...@@ -7226,31 +7245,14 @@ int ocfs2_init_security_and_acl(struct inode *dir,
leave: leave:
return ret; return ret;
} }
/* /*
* 'security' attributes support * 'security' attributes support
*/ */
static size_t ocfs2_xattr_security_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
const size_t total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(list + prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int ocfs2_xattr_security_get(const struct xattr_handler *handler, static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY,
name, buffer, size); name, buffer, size);
} }
...@@ -7259,9 +7261,6 @@ static int ocfs2_xattr_security_set(const struct xattr_handler *handler, ...@@ -7259,9 +7261,6 @@ static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY, return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY,
name, value, size, flags); name, value, size, flags);
} }
...@@ -7314,7 +7313,6 @@ int ocfs2_init_security_set(handle_t *handle, ...@@ -7314,7 +7313,6 @@ int ocfs2_init_security_set(handle_t *handle,
const struct xattr_handler ocfs2_xattr_security_handler = { const struct xattr_handler ocfs2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ocfs2_xattr_security_list,
.get = ocfs2_xattr_security_get, .get = ocfs2_xattr_security_get,
.set = ocfs2_xattr_security_set, .set = ocfs2_xattr_security_set,
}; };
...@@ -7322,31 +7320,10 @@ const struct xattr_handler ocfs2_xattr_security_handler = { ...@@ -7322,31 +7320,10 @@ const struct xattr_handler ocfs2_xattr_security_handler = {
/* /*
* 'trusted' attributes support * 'trusted' attributes support
*/ */
static size_t ocfs2_xattr_trusted_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
const size_t total_len = prefix_len + name_len + 1;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(list + prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED,
name, buffer, size); name, buffer, size);
} }
...@@ -7355,16 +7332,12 @@ static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler, ...@@ -7355,16 +7332,12 @@ static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
if (strcmp(name, "") == 0)
return -EINVAL;
return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED, return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED,
name, value, size, flags); name, value, size, flags);
} }
const struct xattr_handler ocfs2_xattr_trusted_handler = { const struct xattr_handler ocfs2_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX, .prefix = XATTR_TRUSTED_PREFIX,
.list = ocfs2_xattr_trusted_list,
.get = ocfs2_xattr_trusted_get, .get = ocfs2_xattr_trusted_get,
.set = ocfs2_xattr_trusted_set, .set = ocfs2_xattr_trusted_set,
}; };
...@@ -7372,34 +7345,12 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = { ...@@ -7372,34 +7345,12 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = {
/* /*
* 'user' attributes support * 'user' attributes support
*/ */
static size_t ocfs2_xattr_user_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list,
size_t list_size, const char *name,
size_t name_len)
{
const size_t prefix_len = XATTR_USER_PREFIX_LEN;
const size_t total_len = prefix_len + name_len + 1;
struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
return 0;
if (list && total_len <= list_size) {
memcpy(list, XATTR_USER_PREFIX, prefix_len);
memcpy(list + prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
}
static int ocfs2_xattr_user_get(const struct xattr_handler *handler, static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name, struct dentry *dentry, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
if (strcmp(name, "") == 0)
return -EINVAL;
if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_USER, name, return ocfs2_xattr_get(d_inode(dentry), OCFS2_XATTR_INDEX_USER, name,
...@@ -7412,8 +7363,6 @@ static int ocfs2_xattr_user_set(const struct xattr_handler *handler, ...@@ -7412,8 +7363,6 @@ static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
{ {
struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
if (strcmp(name, "") == 0)
return -EINVAL;
if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -7423,7 +7372,6 @@ static int ocfs2_xattr_user_set(const struct xattr_handler *handler, ...@@ -7423,7 +7372,6 @@ static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
const struct xattr_handler ocfs2_xattr_user_handler = { const struct xattr_handler ocfs2_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.list = ocfs2_xattr_user_list,
.get = ocfs2_xattr_user_get, .get = ocfs2_xattr_user_get,
.set = ocfs2_xattr_user_set, .set = ocfs2_xattr_user_set,
}; };
...@@ -769,8 +769,6 @@ posix_acl_xattr_get(const struct xattr_handler *handler, ...@@ -769,8 +769,6 @@ posix_acl_xattr_get(const struct xattr_handler *handler,
struct posix_acl *acl; struct posix_acl *acl;
int error; int error;
if (strcmp(name, "") != 0)
return -EINVAL;
if (!IS_POSIXACL(d_backing_inode(dentry))) if (!IS_POSIXACL(d_backing_inode(dentry)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (d_is_symlink(dentry)) if (d_is_symlink(dentry))
...@@ -797,8 +795,6 @@ posix_acl_xattr_set(const struct xattr_handler *handler, ...@@ -797,8 +795,6 @@ posix_acl_xattr_set(const struct xattr_handler *handler,
struct posix_acl *acl = NULL; struct posix_acl *acl = NULL;
int ret; int ret;
if (strcmp(name, "") != 0)
return -EINVAL;
if (!IS_POSIXACL(inode)) if (!IS_POSIXACL(inode))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!inode->i_op->set_acl) if (!inode->i_op->set_acl)
...@@ -827,25 +823,14 @@ posix_acl_xattr_set(const struct xattr_handler *handler, ...@@ -827,25 +823,14 @@ posix_acl_xattr_set(const struct xattr_handler *handler,
return ret; return ret;
} }
static size_t static bool
posix_acl_xattr_list(const struct xattr_handler *handler, posix_acl_xattr_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const char *xname = handler->prefix; return IS_POSIXACL(d_backing_inode(dentry));
size_t size;
if (!IS_POSIXACL(d_backing_inode(dentry)))
return 0;
size = strlen(xname) + 1;
if (list && size <= list_size)
memcpy(list, xname, size);
return size;
} }
const struct xattr_handler posix_acl_access_xattr_handler = { const struct xattr_handler posix_acl_access_xattr_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS, .name = XATTR_NAME_POSIX_ACL_ACCESS,
.flags = ACL_TYPE_ACCESS, .flags = ACL_TYPE_ACCESS,
.list = posix_acl_xattr_list, .list = posix_acl_xattr_list,
.get = posix_acl_xattr_get, .get = posix_acl_xattr_get,
...@@ -854,7 +839,7 @@ const struct xattr_handler posix_acl_access_xattr_handler = { ...@@ -854,7 +839,7 @@ const struct xattr_handler posix_acl_access_xattr_handler = {
EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler); EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
const struct xattr_handler posix_acl_default_xattr_handler = { const struct xattr_handler posix_acl_default_xattr_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT, .name = XATTR_NAME_POSIX_ACL_DEFAULT,
.flags = ACL_TYPE_DEFAULT, .flags = ACL_TYPE_DEFAULT,
.list = posix_acl_xattr_list, .list = posix_acl_xattr_list,
.get = posix_acl_xattr_get, .get = posix_acl_xattr_get,
......
...@@ -756,7 +756,8 @@ find_xattr_handler_prefix(const struct xattr_handler **handlers, ...@@ -756,7 +756,8 @@ find_xattr_handler_prefix(const struct xattr_handler **handlers,
return NULL; return NULL;
for_each_xattr_handler(handlers, xah) { for_each_xattr_handler(handlers, xah) {
if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0) const char *prefix = xattr_prefix(xah);
if (strncmp(prefix, name, strlen(prefix)) == 0)
break; break;
} }
...@@ -839,19 +840,16 @@ static int listxattr_filler(struct dir_context *ctx, const char *name, ...@@ -839,19 +840,16 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
name); name);
if (!handler) /* Unsupported xattr name */ if (!handler /* Unsupported xattr name */ ||
(handler->list && !handler->list(b->dentry)))
return 0; return 0;
size = namelen + 1;
if (b->buf) { if (b->buf) {
size = handler->list(handler, b->dentry,
b->buf + b->pos, b->size, name,
namelen);
if (size > b->size) if (size > b->size)
return -ERANGE; return -ERANGE;
} else { memcpy(b->buf + b->pos, name, namelen);
size = handler->list(handler, b->dentry, b->buf[b->pos + namelen] = 0;
NULL, 0, name, namelen);
} }
b->pos += size; b->pos += size;
} }
return 0; return 0;
......
...@@ -186,10 +186,10 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) ...@@ -186,10 +186,10 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
break; break;
default: default:
BUG(); BUG();
...@@ -244,7 +244,7 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, ...@@ -244,7 +244,7 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl) { if (acl) {
error = posix_acl_equiv_mode(acl, &inode->i_mode); error = posix_acl_equiv_mode(acl, &inode->i_mode);
if (error < 0) if (error < 0)
...@@ -256,7 +256,7 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, ...@@ -256,7 +256,7 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
} }
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = XATTR_NAME_POSIX_ACL_DEFAULT;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
break; break;
......
...@@ -34,21 +34,9 @@ security_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -34,21 +34,9 @@ security_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t security_list(const struct xattr_handler *handler, static bool security_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_len,
const char *name, size_t namelen)
{ {
const size_t len = namelen + 1; return !IS_PRIVATE(d_inode(dentry));
if (IS_PRIVATE(d_inode(dentry)))
return 0;
if (list && len <= list_len) {
memcpy(list, name, namelen);
list[namelen] = '\0';
}
return len;
} }
/* Initializes the security context for a new inode and returns the number /* Initializes the security context for a new inode and returns the number
......
...@@ -33,20 +33,9 @@ trusted_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -33,20 +33,9 @@ trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t trusted_list(const struct xattr_handler *handler, static bool trusted_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t len = name_len + 1; return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
return 0;
if (list && len <= list_size) {
memcpy(list, name, name_len);
list[name_len] = '\0';
}
return len;
} }
const struct xattr_handler reiserfs_xattr_trusted_handler = { const struct xattr_handler reiserfs_xattr_trusted_handler = {
......
...@@ -30,19 +30,9 @@ user_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -30,19 +30,9 @@ user_set(const struct xattr_handler *handler, struct dentry *dentry,
return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
} }
static size_t user_list(const struct xattr_handler *handler, static bool user_list(struct dentry *dentry)
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
{ {
const size_t len = name_len + 1; return reiserfs_xattrs_user(dentry->d_sb);
if (!reiserfs_xattrs_user(dentry->d_sb))
return 0;
if (list && len <= list_size) {
memcpy(list, name, name_len);
list[name_len] = '\0';
}
return len;
} }
const struct xattr_handler reiserfs_xattr_user_handler = { const struct xattr_handler reiserfs_xattr_user_handler = {
......
...@@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, ...@@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
struct squashfs_xattr_entry entry; struct squashfs_xattr_entry entry;
struct squashfs_xattr_val val; struct squashfs_xattr_val val;
const struct xattr_handler *handler; const struct xattr_handler *handler;
int name_size, prefix_size = 0; int name_size;
err = squashfs_read_metadata(sb, &entry, &start, &offset, err = squashfs_read_metadata(sb, &entry, &start, &offset,
sizeof(entry)); sizeof(entry));
...@@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, ...@@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
name_size = le16_to_cpu(entry.size); name_size = le16_to_cpu(entry.size);
handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); handler = squashfs_xattr_handler(le16_to_cpu(entry.type));
if (handler) if (handler && (!handler->list || handler->list(d))) {
prefix_size = handler->list(handler, d, buffer, rest, const char *prefix = handler->prefix ?: handler->name;
NULL, name_size); size_t prefix_size = strlen(prefix);
if (prefix_size) {
if (buffer) { if (buffer) {
if (prefix_size + name_size + 1 > rest) { if (prefix_size + name_size + 1 > rest) {
err = -ERANGE; err = -ERANGE;
goto failed; goto failed;
} }
memcpy(buffer, prefix, prefix_size);
buffer += prefix_size; buffer += prefix_size;
} }
err = squashfs_read_metadata(sb, buffer, &start, err = squashfs_read_metadata(sb, buffer, &start,
...@@ -212,25 +213,10 @@ static int squashfs_xattr_get(struct inode *inode, int name_index, ...@@ -212,25 +213,10 @@ static int squashfs_xattr_get(struct inode *inode, int name_index,
} }
static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler,
struct dentry *d, char *list,
size_t list_size, const char *name,
size_t name_len)
{
int len = strlen(handler->prefix);
if (list && len <= list_size)
memcpy(list, handler->prefix, len);
return len;
}
static int squashfs_xattr_handler_get(const struct xattr_handler *handler, static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
struct dentry *d, const char *name, struct dentry *d, const char *name,
void *buffer, size_t size) void *buffer, size_t size)
{ {
if (name[0] == '\0')
return -EINVAL;
return squashfs_xattr_get(d_inode(d), handler->flags, name, return squashfs_xattr_get(d_inode(d), handler->flags, name,
buffer, size); buffer, size);
} }
...@@ -241,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, ...@@ -241,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
static const struct xattr_handler squashfs_xattr_user_handler = { static const struct xattr_handler squashfs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX, .prefix = XATTR_USER_PREFIX,
.flags = SQUASHFS_XATTR_USER, .flags = SQUASHFS_XATTR_USER,
.list = squashfs_xattr_handler_list,
.get = squashfs_xattr_handler_get .get = squashfs_xattr_handler_get
}; };
/* /*
* Trusted namespace support * Trusted namespace support
*/ */
static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
struct dentry *d, char *list,
size_t list_size, const char *name,
size_t name_len)
{ {
if (!capable(CAP_SYS_ADMIN)) return capable(CAP_SYS_ADMIN);
return 0;
return squashfs_xattr_handler_list(handler, d, list, list_size, name,
name_len);
} }
static const struct xattr_handler squashfs_xattr_trusted_handler = { static const struct xattr_handler squashfs_xattr_trusted_handler = {
...@@ -272,7 +251,6 @@ static const struct xattr_handler squashfs_xattr_trusted_handler = { ...@@ -272,7 +251,6 @@ static const struct xattr_handler squashfs_xattr_trusted_handler = {
static const struct xattr_handler squashfs_xattr_security_handler = { static const struct xattr_handler squashfs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.flags = SQUASHFS_XATTR_SECURITY, .flags = SQUASHFS_XATTR_SECURITY,
.list = squashfs_xattr_handler_list,
.get = squashfs_xattr_handler_get .get = squashfs_xattr_handler_get
}; };
......
...@@ -208,25 +208,6 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, ...@@ -208,25 +208,6 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
return error; return error;
} }
/* Compare an extended attribute value with the given value */
int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
const char *value, size_t size, gfp_t flags)
{
char *xattr_value = NULL;
int rc;
rc = vfs_getxattr_alloc(dentry, xattr_name, &xattr_value, 0, flags);
if (rc < 0)
return rc;
if ((rc != size) || (memcmp(xattr_value, value, rc) != 0))
rc = -EINVAL;
else
rc = 0;
kfree(xattr_value);
return rc;
}
ssize_t ssize_t
vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
{ {
...@@ -700,13 +681,20 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name) ...@@ -700,13 +681,20 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
return NULL; return NULL;
for_each_xattr_handler(handlers, handler) { for_each_xattr_handler(handlers, handler) {
const char *n = strcmp_prefix(*name, handler->prefix); const char *n;
n = strcmp_prefix(*name, xattr_prefix(handler));
if (n) { if (n) {
if (!handler->prefix ^ !*n) {
if (*n)
continue;
return ERR_PTR(-EINVAL);
}
*name = n; *name = n;
break; return handler;
} }
} }
return handler; return ERR_PTR(-EOPNOTSUPP);
} }
/* /*
...@@ -718,8 +706,8 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s ...@@ -718,8 +706,8 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s
const struct xattr_handler *handler; const struct xattr_handler *handler;
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
if (!handler) if (IS_ERR(handler))
return -EOPNOTSUPP; return PTR_ERR(handler);
return handler->get(handler, dentry, name, buffer, size); return handler->get(handler, dentry, name, buffer, size);
} }
...@@ -735,19 +723,25 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -735,19 +723,25 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
if (!buffer) { if (!buffer) {
for_each_xattr_handler(handlers, handler) { for_each_xattr_handler(handlers, handler) {
size += handler->list(handler, dentry, NULL, 0, if (!handler->name ||
NULL, 0); (handler->list && !handler->list(dentry)))
continue;
size += strlen(handler->name) + 1;
} }
} else { } else {
char *buf = buffer; char *buf = buffer;
size_t len;
for_each_xattr_handler(handlers, handler) { for_each_xattr_handler(handlers, handler) {
size = handler->list(handler, dentry, buf, buffer_size, if (!handler->name ||
NULL, 0); (handler->list && !handler->list(dentry)))
if (size > buffer_size) continue;
len = strlen(handler->name);
if (len + 1 > buffer_size)
return -ERANGE; return -ERANGE;
buf += size; memcpy(buf, handler->name, len + 1);
buffer_size -= size; buf += len + 1;
buffer_size -= len + 1;
} }
size = buf - buffer; size = buf - buffer;
} }
...@@ -765,8 +759,8 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz ...@@ -765,8 +759,8 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
if (size == 0) if (size == 0)
value = ""; /* empty EA, do not remove */ value = ""; /* empty EA, do not remove */
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
if (!handler) if (IS_ERR(handler))
return -EOPNOTSUPP; return PTR_ERR(handler);
return handler->set(handler, dentry, name, value, size, flags); return handler->set(handler, dentry, name, value, size, flags);
} }
...@@ -780,8 +774,8 @@ generic_removexattr(struct dentry *dentry, const char *name) ...@@ -780,8 +774,8 @@ generic_removexattr(struct dentry *dentry, const char *name)
const struct xattr_handler *handler; const struct xattr_handler *handler;
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
if (!handler) if (IS_ERR(handler))
return -EOPNOTSUPP; return PTR_ERR(handler);
return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE); return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
} }
...@@ -808,7 +802,7 @@ EXPORT_SYMBOL(generic_removexattr); ...@@ -808,7 +802,7 @@ EXPORT_SYMBOL(generic_removexattr);
const char *xattr_full_name(const struct xattr_handler *handler, const char *xattr_full_name(const struct xattr_handler *handler,
const char *name) const char *name)
{ {
size_t prefix_len = strlen(handler->prefix); size_t prefix_len = strlen(xattr_prefix(handler));
return name - prefix_len; return name - prefix_len;
} }
...@@ -863,8 +857,22 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, ...@@ -863,8 +857,22 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
return ret; return ret;
} }
static int __simple_xattr_set(struct simple_xattrs *xattrs, const char *name, /**
const void *value, size_t size, int flags) * simple_xattr_set - xattr SET operation for in-memory/pseudo filesystems
* @xattrs: target simple_xattr list
* @name: name of the extended attribute
* @value: value of the xattr. If %NULL, will remove the attribute.
* @size: size of the new xattr
* @flags: %XATTR_{CREATE|REPLACE}
*
* %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
* with -EEXIST. If %XATTR_REPLACE is set, the xattr should exist;
* otherwise, fails with -ENODATA.
*
* Returns 0 on success, -errno on failure.
*/
int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
const void *value, size_t size, int flags)
{ {
struct simple_xattr *xattr; struct simple_xattr *xattr;
struct simple_xattr *new_xattr = NULL; struct simple_xattr *new_xattr = NULL;
...@@ -914,73 +922,64 @@ static int __simple_xattr_set(struct simple_xattrs *xattrs, const char *name, ...@@ -914,73 +922,64 @@ static int __simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
} }
/** static bool xattr_is_trusted(const char *name)
* simple_xattr_set - xattr SET operation for in-memory/pseudo filesystems
* @xattrs: target simple_xattr list
* @name: name of the new extended attribute
* @value: value of the new xattr. If %NULL, will remove the attribute
* @size: size of the new xattr
* @flags: %XATTR_{CREATE|REPLACE}
*
* %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
* with -EEXIST. If %XATTR_REPLACE is set, the xattr should exist;
* otherwise, fails with -ENODATA.
*
* Returns 0 on success, -errno on failure.
*/
int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
const void *value, size_t size, int flags)
{
if (size == 0)
value = ""; /* empty EA, do not remove */
return __simple_xattr_set(xattrs, name, value, size, flags);
}
/*
* xattr REMOVE operation for in-memory/pseudo filesystems
*/
int simple_xattr_remove(struct simple_xattrs *xattrs, const char *name)
{ {
return __simple_xattr_set(xattrs, name, NULL, 0, XATTR_REPLACE); return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
} }
static bool xattr_is_trusted(const char *name) static int xattr_list_one(char **buffer, ssize_t *remaining_size,
const char *name)
{ {
return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); size_t len = strlen(name) + 1;
if (*buffer) {
if (*remaining_size < len)
return -ERANGE;
memcpy(*buffer, name, len);
*buffer += len;
}
*remaining_size -= len;
return 0;
} }
/* /*
* xattr LIST operation for in-memory/pseudo filesystems * xattr LIST operation for in-memory/pseudo filesystems
*/ */
ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer, ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
size_t size) char *buffer, size_t size)
{ {
bool trusted = capable(CAP_SYS_ADMIN); bool trusted = capable(CAP_SYS_ADMIN);
struct simple_xattr *xattr; struct simple_xattr *xattr;
size_t used = 0; ssize_t remaining_size = size;
int err;
#ifdef CONFIG_FS_POSIX_ACL
if (inode->i_acl) {
err = xattr_list_one(&buffer, &remaining_size,
XATTR_NAME_POSIX_ACL_ACCESS);
if (err)
return err;
}
if (inode->i_default_acl) {
err = xattr_list_one(&buffer, &remaining_size,
XATTR_NAME_POSIX_ACL_DEFAULT);
if (err)
return err;
}
#endif
spin_lock(&xattrs->lock); spin_lock(&xattrs->lock);
list_for_each_entry(xattr, &xattrs->head, list) { list_for_each_entry(xattr, &xattrs->head, list) {
size_t len;
/* skip "trusted." attributes for unprivileged callers */ /* skip "trusted." attributes for unprivileged callers */
if (!trusted && xattr_is_trusted(xattr->name)) if (!trusted && xattr_is_trusted(xattr->name))
continue; continue;
len = strlen(xattr->name) + 1; err = xattr_list_one(&buffer, &remaining_size, xattr->name);
used += len; if (err)
if (buffer) { return err;
if (size < used) {
used = -ERANGE;
break;
}
memcpy(buffer, xattr->name, len);
buffer += len;
}
} }
spin_unlock(&xattrs->lock); spin_unlock(&xattrs->lock);
return used; return size - remaining_size;
} }
/* /*
......
...@@ -252,29 +252,6 @@ xfs_set_mode(struct inode *inode, umode_t mode) ...@@ -252,29 +252,6 @@ xfs_set_mode(struct inode *inode, umode_t mode)
return error; return error;
} }
static int
xfs_acl_exists(struct inode *inode, unsigned char *name)
{
int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb));
return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
ATTR_ROOT|ATTR_KERNOVAL) == 0);
}
int
posix_acl_access_exists(struct inode *inode)
{
return xfs_acl_exists(inode, SGI_ACL_FILE);
}
int
posix_acl_default_exists(struct inode *inode)
{
if (!S_ISDIR(inode->i_mode))
return 0;
return xfs_acl_exists(inode, SGI_ACL_DEFAULT);
}
int int
xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{ {
......
...@@ -24,16 +24,12 @@ struct posix_acl; ...@@ -24,16 +24,12 @@ struct posix_acl;
#ifdef CONFIG_XFS_POSIX_ACL #ifdef CONFIG_XFS_POSIX_ACL
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
extern int posix_acl_access_exists(struct inode *inode);
extern int posix_acl_default_exists(struct inode *inode);
#else #else
static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
{ {
return NULL; return NULL;
} }
# define xfs_set_acl NULL # define xfs_set_acl NULL
# define posix_acl_access_exists(inode) 0
# define posix_acl_default_exists(inode) 0
#endif /* CONFIG_XFS_POSIX_ACL */ #endif /* CONFIG_XFS_POSIX_ACL */
extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags); extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags);
......
...@@ -39,9 +39,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -39,9 +39,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry,
struct xfs_inode *ip = XFS_I(d_inode(dentry)); struct xfs_inode *ip = XFS_I(d_inode(dentry));
int error, asize = size; int error, asize = size;
if (strcmp(name, "") == 0)
return -EINVAL;
/* Convert Linux syscall to XFS internal ATTR flags */ /* Convert Linux syscall to XFS internal ATTR flags */
if (!size) { if (!size) {
xflags |= ATTR_KERNOVAL; xflags |= ATTR_KERNOVAL;
...@@ -84,9 +81,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, ...@@ -84,9 +81,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
struct xfs_inode *ip = XFS_I(d_inode(dentry)); struct xfs_inode *ip = XFS_I(d_inode(dentry));
int error; int error;
if (strcmp(name, "") == 0)
return -EINVAL;
/* Convert Linux syscall to XFS internal ATTR flags */ /* Convert Linux syscall to XFS internal ATTR flags */
if (flags & XATTR_CREATE) if (flags & XATTR_CREATE)
xflags |= ATTR_CREATE; xflags |= ATTR_CREATE;
...@@ -135,47 +129,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = { ...@@ -135,47 +129,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
NULL NULL
}; };
static unsigned int xfs_xattr_prefix_len(int flags)
{
if (flags & XFS_ATTR_SECURE)
return sizeof("security");
else if (flags & XFS_ATTR_ROOT)
return sizeof("trusted");
else
return sizeof("user");
}
static const char *xfs_xattr_prefix(int flags)
{
if (flags & XFS_ATTR_SECURE)
return xfs_xattr_security_handler.prefix;
else if (flags & XFS_ATTR_ROOT)
return xfs_xattr_trusted_handler.prefix;
else
return xfs_xattr_user_handler.prefix;
}
static int static int
xfs_xattr_put_listent( __xfs_xattr_put_listent(
struct xfs_attr_list_context *context, struct xfs_attr_list_context *context,
int flags, char *prefix,
unsigned char *name, int prefix_len,
int namelen, unsigned char *name,
int valuelen, int namelen)
unsigned char *value)
{ {
unsigned int prefix_len = xfs_xattr_prefix_len(flags);
char *offset; char *offset;
int arraytop; int arraytop;
ASSERT(context->count >= 0); if (!context->alist)
goto compute_size;
/*
* Only show root namespace entries if we are actually allowed to
* see them.
*/
if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN))
return 0;
arraytop = context->count + prefix_len + namelen + 1; arraytop = context->count + prefix_len + namelen + 1;
if (arraytop > context->firstu) { if (arraytop > context->firstu) {
...@@ -183,17 +149,19 @@ xfs_xattr_put_listent( ...@@ -183,17 +149,19 @@ xfs_xattr_put_listent(
return 1; return 1;
} }
offset = (char *)context->alist + context->count; offset = (char *)context->alist + context->count;
strncpy(offset, xfs_xattr_prefix(flags), prefix_len); strncpy(offset, prefix, prefix_len);
offset += prefix_len; offset += prefix_len;
strncpy(offset, (char *)name, namelen); /* real name */ strncpy(offset, (char *)name, namelen); /* real name */
offset += namelen; offset += namelen;
*offset = '\0'; *offset = '\0';
compute_size:
context->count += prefix_len + namelen + 1; context->count += prefix_len + namelen + 1;
return 0; return 0;
} }
static int static int
xfs_xattr_put_listent_sizes( xfs_xattr_put_listent(
struct xfs_attr_list_context *context, struct xfs_attr_list_context *context,
int flags, int flags,
unsigned char *name, unsigned char *name,
...@@ -201,24 +169,55 @@ xfs_xattr_put_listent_sizes( ...@@ -201,24 +169,55 @@ xfs_xattr_put_listent_sizes(
int valuelen, int valuelen,
unsigned char *value) unsigned char *value)
{ {
context->count += xfs_xattr_prefix_len(flags) + namelen + 1; char *prefix;
return 0; int prefix_len;
}
static int ASSERT(context->count >= 0);
list_one_attr(const char *name, const size_t len, void *data,
size_t size, ssize_t *result)
{
char *p = data + *result;
*result += len; if (flags & XFS_ATTR_ROOT) {
if (!size) #ifdef CONFIG_XFS_POSIX_ACL
return 0; if (namelen == SGI_ACL_FILE_SIZE &&
if (*result > size) strncmp(name, SGI_ACL_FILE,
return -ERANGE; SGI_ACL_FILE_SIZE) == 0) {
int ret = __xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_ACCESS,
strlen(XATTR_POSIX_ACL_ACCESS));
if (ret)
return ret;
} else if (namelen == SGI_ACL_DEFAULT_SIZE &&
strncmp(name, SGI_ACL_DEFAULT,
SGI_ACL_DEFAULT_SIZE) == 0) {
int ret = __xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_DEFAULT,
strlen(XATTR_POSIX_ACL_DEFAULT));
if (ret)
return ret;
}
#endif
strcpy(p, name); /*
return 0; * Only show root namespace entries if we are actually allowed to
* see them.
*/
if (!capable(CAP_SYS_ADMIN))
return 0;
prefix = XATTR_TRUSTED_PREFIX;
prefix_len = XATTR_TRUSTED_PREFIX_LEN;
} else if (flags & XFS_ATTR_SECURE) {
prefix = XATTR_SECURITY_PREFIX;
prefix_len = XATTR_SECURITY_PREFIX_LEN;
} else {
prefix = XATTR_USER_PREFIX;
prefix_len = XATTR_USER_PREFIX_LEN;
}
return __xfs_xattr_put_listent(context, prefix, prefix_len, name,
namelen);
} }
ssize_t ssize_t
...@@ -227,7 +226,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) ...@@ -227,7 +226,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
struct xfs_attr_list_context context; struct xfs_attr_list_context context;
struct attrlist_cursor_kern cursor = { 0 }; struct attrlist_cursor_kern cursor = { 0 };
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
int error;
/* /*
* First read the regular on-disk attributes. * First read the regular on-disk attributes.
...@@ -236,37 +234,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) ...@@ -236,37 +234,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
context.dp = XFS_I(inode); context.dp = XFS_I(inode);
context.cursor = &cursor; context.cursor = &cursor;
context.resynch = 1; context.resynch = 1;
context.alist = data; context.alist = size ? data : NULL;
context.bufsize = size; context.bufsize = size;
context.firstu = context.bufsize; context.firstu = context.bufsize;
context.put_listent = xfs_xattr_put_listent;
if (size)
context.put_listent = xfs_xattr_put_listent;
else
context.put_listent = xfs_xattr_put_listent_sizes;
xfs_attr_list_int(&context); xfs_attr_list_int(&context);
if (context.count < 0) if (context.count < 0)
return -ERANGE; return -ERANGE;
/*
* Then add the two synthetic ACL attributes.
*/
if (posix_acl_access_exists(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS) + 1,
data, size, &context.count);
if (error)
return error;
}
if (posix_acl_default_exists(inode)) {
error = list_one_attr(POSIX_ACL_XATTR_DEFAULT,
strlen(POSIX_ACL_XATTR_DEFAULT) + 1,
data, size, &context.count);
if (error)
return error;
}
return context.count; return context.count;
} }
...@@ -9,16 +9,12 @@ ...@@ -9,16 +9,12 @@
#ifndef _POSIX_ACL_XATTR_H #ifndef _POSIX_ACL_XATTR_H
#define _POSIX_ACL_XATTR_H #define _POSIX_ACL_XATTR_H
#include <uapi/linux/xattr.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
/* Extended attribute names */
#define POSIX_ACL_XATTR_ACCESS "system.posix_acl_access"
#define POSIX_ACL_XATTR_DEFAULT "system.posix_acl_default"
/* Supported ACL a_version fields */ /* Supported ACL a_version fields */
#define POSIX_ACL_XATTR_VERSION 0x0002 #define POSIX_ACL_XATTR_VERSION 0x0002
/* An undefined entry e_id value */ /* An undefined entry e_id value */
#define ACL_UNDEFINED_ID (-1) #define ACL_UNDEFINED_ID (-1)
......
...@@ -19,12 +19,16 @@ ...@@ -19,12 +19,16 @@
struct inode; struct inode;
struct dentry; struct dentry;
/*
* struct xattr_handler: When @name is set, match attributes with exactly that
* name. When @prefix is set instead, match attributes with that prefix and
* with a non-empty suffix.
*/
struct xattr_handler { struct xattr_handler {
const char *name;
const char *prefix; const char *prefix;
int flags; /* fs private flags */ int flags; /* fs private flags */
size_t (*list)(const struct xattr_handler *, struct dentry *dentry, bool (*list)(struct dentry *dentry);
char *list, size_t list_size, const char *name,
size_t name_len);
int (*get)(const struct xattr_handler *, struct dentry *dentry, int (*get)(const struct xattr_handler *, struct dentry *dentry,
const char *name, void *buffer, size_t size); const char *name, void *buffer, size_t size);
int (*set)(const struct xattr_handler *, struct dentry *dentry, int (*set)(const struct xattr_handler *, struct dentry *dentry,
...@@ -53,8 +57,11 @@ int generic_setxattr(struct dentry *dentry, const char *name, const void *value, ...@@ -53,8 +57,11 @@ int generic_setxattr(struct dentry *dentry, const char *name, const void *value,
int generic_removexattr(struct dentry *dentry, const char *name); int generic_removexattr(struct dentry *dentry, const char *name);
ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name, ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
char **xattr_value, size_t size, gfp_t flags); char **xattr_value, size_t size, gfp_t flags);
int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
const char *value, size_t size, gfp_t flags); static inline const char *xattr_prefix(const struct xattr_handler *handler)
{
return handler->prefix ?: handler->name;
}
struct simple_xattrs { struct simple_xattrs {
struct list_head head; struct list_head head;
...@@ -95,8 +102,7 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name, ...@@ -95,8 +102,7 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
void *buffer, size_t size); void *buffer, size_t size);
int simple_xattr_set(struct simple_xattrs *xattrs, const char *name, int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
const void *value, size_t size, int flags); const void *value, size_t size, int flags);
int simple_xattr_remove(struct simple_xattrs *xattrs, const char *name); ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, char *buffer,
ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer,
size_t size); size_t size);
void simple_xattr_list_add(struct simple_xattrs *xattrs, void simple_xattr_list_add(struct simple_xattrs *xattrs,
struct simple_xattr *new_xattr); struct simple_xattr *new_xattr);
......
...@@ -2564,99 +2564,52 @@ static int shmem_initxattrs(struct inode *inode, ...@@ -2564,99 +2564,52 @@ static int shmem_initxattrs(struct inode *inode,
return 0; return 0;
} }
static const struct xattr_handler *shmem_xattr_handlers[] = { static int shmem_xattr_handler_get(const struct xattr_handler *handler,
#ifdef CONFIG_TMPFS_POSIX_ACL struct dentry *dentry, const char *name,
&posix_acl_access_xattr_handler, void *buffer, size_t size)
&posix_acl_default_xattr_handler,
#endif
NULL
};
static int shmem_xattr_validate(const char *name)
{
struct { const char *prefix; size_t len; } arr[] = {
{ XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN },
{ XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN }
};
int i;
for (i = 0; i < ARRAY_SIZE(arr); i++) {
size_t preflen = arr[i].len;
if (strncmp(name, arr[i].prefix, preflen) == 0) {
if (!name[preflen])
return -EINVAL;
return 0;
}
}
return -EOPNOTSUPP;
}
static ssize_t shmem_getxattr(struct dentry *dentry, const char *name,
void *buffer, size_t size)
{ {
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
int err;
/*
* 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_getxattr(dentry, name, buffer, size);
err = shmem_xattr_validate(name);
if (err)
return err;
name = xattr_full_name(handler, name);
return simple_xattr_get(&info->xattrs, name, buffer, size); return simple_xattr_get(&info->xattrs, name, buffer, size);
} }
static int shmem_setxattr(struct dentry *dentry, const char *name, static int shmem_xattr_handler_set(const struct xattr_handler *handler,
const void *value, size_t size, int flags) struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{ {
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
int err;
/*
* 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);
err = shmem_xattr_validate(name);
if (err)
return err;
name = xattr_full_name(handler, name);
return simple_xattr_set(&info->xattrs, name, value, size, flags); return simple_xattr_set(&info->xattrs, name, value, size, flags);
} }
static int shmem_removexattr(struct dentry *dentry, const char *name) static const struct xattr_handler shmem_security_xattr_handler = {
{ .prefix = XATTR_SECURITY_PREFIX,
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); .get = shmem_xattr_handler_get,
int err; .set = shmem_xattr_handler_set,
};
/*
* 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);
err = shmem_xattr_validate(name); static const struct xattr_handler shmem_trusted_xattr_handler = {
if (err) .prefix = XATTR_TRUSTED_PREFIX,
return err; .get = shmem_xattr_handler_get,
.set = shmem_xattr_handler_set,
};
return simple_xattr_remove(&info->xattrs, name); static const struct xattr_handler *shmem_xattr_handlers[] = {
} #ifdef CONFIG_TMPFS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&shmem_security_xattr_handler,
&shmem_trusted_xattr_handler,
NULL
};
static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size)
{ {
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
return simple_xattr_list(&info->xattrs, buffer, size); return simple_xattr_list(d_inode(dentry), &info->xattrs, buffer, size);
} }
#endif /* CONFIG_TMPFS_XATTR */ #endif /* CONFIG_TMPFS_XATTR */
...@@ -2664,10 +2617,10 @@ static const struct inode_operations shmem_short_symlink_operations = { ...@@ -2664,10 +2617,10 @@ static const struct inode_operations shmem_short_symlink_operations = {
.readlink = generic_readlink, .readlink = generic_readlink,
.get_link = simple_get_link, .get_link = simple_get_link,
#ifdef CONFIG_TMPFS_XATTR #ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr, .setxattr = generic_setxattr,
.getxattr = shmem_getxattr, .getxattr = generic_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = generic_removexattr,
#endif #endif
}; };
...@@ -2675,10 +2628,10 @@ static const struct inode_operations shmem_symlink_inode_operations = { ...@@ -2675,10 +2628,10 @@ static const struct inode_operations shmem_symlink_inode_operations = {
.readlink = generic_readlink, .readlink = generic_readlink,
.get_link = shmem_get_link, .get_link = shmem_get_link,
#ifdef CONFIG_TMPFS_XATTR #ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr, .setxattr = generic_setxattr,
.getxattr = shmem_getxattr, .getxattr = generic_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = generic_removexattr,
#endif #endif
}; };
...@@ -3150,10 +3103,10 @@ static const struct inode_operations shmem_inode_operations = { ...@@ -3150,10 +3103,10 @@ static const struct inode_operations shmem_inode_operations = {
.getattr = shmem_getattr, .getattr = shmem_getattr,
.setattr = shmem_setattr, .setattr = shmem_setattr,
#ifdef CONFIG_TMPFS_XATTR #ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr, .setxattr = generic_setxattr,
.getxattr = shmem_getxattr, .getxattr = generic_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = generic_removexattr,
.set_acl = simple_set_acl, .set_acl = simple_set_acl,
#endif #endif
}; };
...@@ -3172,10 +3125,10 @@ static const struct inode_operations shmem_dir_inode_operations = { ...@@ -3172,10 +3125,10 @@ static const struct inode_operations shmem_dir_inode_operations = {
.tmpfile = shmem_tmpfile, .tmpfile = shmem_tmpfile,
#endif #endif
#ifdef CONFIG_TMPFS_XATTR #ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr, .setxattr = generic_setxattr,
.getxattr = shmem_getxattr, .getxattr = generic_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = generic_removexattr,
#endif #endif
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_setattr, .setattr = shmem_setattr,
...@@ -3185,10 +3138,10 @@ static const struct inode_operations shmem_dir_inode_operations = { ...@@ -3185,10 +3138,10 @@ static const struct inode_operations shmem_dir_inode_operations = {
static const struct inode_operations shmem_special_inode_operations = { static const struct inode_operations shmem_special_inode_operations = {
#ifdef CONFIG_TMPFS_XATTR #ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr, .setxattr = generic_setxattr,
.getxattr = shmem_getxattr, .getxattr = generic_getxattr,
.listxattr = shmem_listxattr, .listxattr = shmem_listxattr,
.removexattr = shmem_removexattr, .removexattr = generic_removexattr,
#endif #endif
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_setattr, .setattr = shmem_setattr,
......
...@@ -1519,8 +1519,6 @@ static int smack_inode_getsecurity(const struct inode *inode, ...@@ -1519,8 +1519,6 @@ static int smack_inode_getsecurity(const struct inode *inode,
* @inode: the object * @inode: the object
* @buffer: where they go * @buffer: where they go
* @buffer_size: size of buffer * @buffer_size: size of buffer
*
* Returns 0 on success, -EINVAL otherwise
*/ */
static int smack_inode_listsecurity(struct inode *inode, char *buffer, static int smack_inode_listsecurity(struct inode *inode, char *buffer,
size_t buffer_size) size_t buffer_size)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册