mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 10:43:43 +00:00
vfs: Distinguish between full xattr names and proper prefixes
Add an additional "name" field to struct xattr_handler. When the name
is set, the handler matches attributes with exactly that name. When the
prefix is set instead, the handler matches attributes with the given
prefix and with a non-empty suffix.
This patch should avoid bugs like the one fixed in commit c361016a
in
the future.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: James Morris <james.l.morris@oracle.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
97d7929922
commit
98e9cb5711
16
fs/9p/acl.c
16
fs/9p/acl.c
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const struct xattr_handler v9fs_xattr_acl_access_handler = {
|
const struct xattr_handler v9fs_xattr_acl_access_handler = {
|
||||||
.prefix = XATTR_NAME_POSIX_ACL_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 = XATTR_NAME_POSIX_ACL_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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@ 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 +37,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);
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,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 +41,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);
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,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 +45,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;
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ 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 +42,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);
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,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 +45,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);
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,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 +46,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,
|
||||||
|
@ -30,6 +30,7 @@ static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
|
|||||||
const char *name, size_t len)
|
const char *name, size_t len)
|
||||||
{
|
{
|
||||||
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
|
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
|
||||||
|
const char *prefix;
|
||||||
int total_len, prefix_len;
|
int total_len, prefix_len;
|
||||||
|
|
||||||
switch (handler->flags) {
|
switch (handler->flags) {
|
||||||
@ -47,10 +48,11 @@ static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix_len = strlen(handler->prefix);
|
prefix = xattr_prefix(handler);
|
||||||
|
prefix_len = strlen(prefix);
|
||||||
total_len = prefix_len + len + 1;
|
total_len = prefix_len + len + 1;
|
||||||
if (list && total_len <= list_size) {
|
if (list && total_len <= list_size) {
|
||||||
memcpy(list, handler->prefix, prefix_len);
|
memcpy(list, prefix, prefix_len);
|
||||||
memcpy(list + prefix_len, name, len);
|
memcpy(list + prefix_len, name, len);
|
||||||
list[prefix_len + len] = '\0';
|
list[prefix_len + len] = '\0';
|
||||||
}
|
}
|
||||||
@ -77,8 +79,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,9 +103,6 @@ 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);
|
||||||
}
|
}
|
||||||
@ -114,7 +111,7 @@ static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler,
|
|||||||
struct dentry *dentry, char *list, size_t list_size,
|
struct dentry *dentry, char *list, size_t list_size,
|
||||||
const char *name, size_t len)
|
const char *name, size_t len)
|
||||||
{
|
{
|
||||||
const char *xname = F2FS_SYSTEM_ADVISE_PREFIX;
|
const char *xname = F2FS_SYSTEM_ADVISE_NAME;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
size = strlen(xname) + 1;
|
size = strlen(xname) + 1;
|
||||||
@ -129,9 +126,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 +137,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)
|
||||||
@ -197,7 +189,7 @@ const struct xattr_handler f2fs_xattr_trusted_handler = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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,
|
.list = f2fs_xattr_advise_list,
|
||||||
.get = f2fs_xattr_advise_get,
|
.get = f2fs_xattr_advise_get,
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,9 +60,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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,8 +28,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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,8 +28,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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,9 +6260,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8834,7 +8828,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)
|
|||||||
|
|
||||||
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,
|
||||||
@ -7249,8 +7248,6 @@ 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 +7256,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);
|
||||||
}
|
}
|
||||||
@ -7345,8 +7339,6 @@ 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,9 +7347,6 @@ 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);
|
||||||
}
|
}
|
||||||
@ -7398,8 +7387,6 @@ static int ocfs2_xattr_user_get(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;
|
||||||
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 +7399,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;
|
||||||
|
|
||||||
|
@ -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,
|
|||||||
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)
|
||||||
@ -832,7 +828,7 @@ posix_acl_xattr_list(const struct xattr_handler *handler,
|
|||||||
struct dentry *dentry, char *list, size_t list_size,
|
struct dentry *dentry, char *list, size_t list_size,
|
||||||
const char *name, size_t name_len)
|
const char *name, size_t name_len)
|
||||||
{
|
{
|
||||||
const char *xname = handler->prefix;
|
const char *xname = handler->name;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (!IS_POSIXACL(d_backing_inode(dentry)))
|
if (!IS_POSIXACL(d_backing_inode(dentry)))
|
||||||
@ -845,7 +841,7 @@ posix_acl_xattr_list(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const struct xattr_handler posix_acl_access_xattr_handler = {
|
const struct xattr_handler posix_acl_access_xattr_handler = {
|
||||||
.prefix = XATTR_NAME_POSIX_ACL_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 +850,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 = XATTR_NAME_POSIX_ACL_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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +228,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
27
fs/xattr.c
27
fs/xattr.c
@ -681,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -699,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,8 +753,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,8 +768,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,7 +796,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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|||||||
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;
|
||||||
|
@ -19,7 +19,13 @@
|
|||||||
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,
|
size_t (*list)(const struct xattr_handler *, struct dentry *dentry,
|
||||||
@ -54,6 +60,11 @@ 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);
|
||||||
|
|
||||||
|
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;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
Loading…
Reference in New Issue
Block a user