Skip to content

Commit

Permalink
xattr handlers: Simplify list operation
Browse files Browse the repository at this point in the history
Change the list operation to only return whether or not an attribute
should be listed.  Copying the attribute names into the buffer is moved
to the callers.

Since the result only depends on the dentry and not on the attribute
name, we do not pass the attribute name to list operations.

Signed-off-by: Andreas Gruenbacher <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Andreas Gruenbacher authored and Al Viro committed Dec 14, 2015
1 parent 1046cb1 commit 764a5c6
Show file tree
Hide file tree
Showing 22 changed files with 113 additions and 335 deletions.
15 changes: 10 additions & 5 deletions fs/ext2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
const struct xattr_handler *handler =
ext2_xattr_handler(entry->e_name_index);

if (handler) {
size_t size = handler->list(handler, dentry, buffer,
rest, entry->e_name,
entry->e_name_len);
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;

if (buffer) {
if (size > rest) {
error = -ERANGE;
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;
}
Expand Down
17 changes: 0 additions & 17 deletions fs/ext2/xattr_security.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,6 @@
#include <linux/security.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
ext2_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
Expand Down Expand Up @@ -67,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir,

const struct xattr_handler ext2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list,
.get = ext2_xattr_security_get,
.set = ext2_xattr_security_set,
};
19 changes: 3 additions & 16 deletions fs/ext2/xattr_trusted.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,10 @@
#include "ext2.h"
#include "xattr.h"

static size_t
ext2_xattr_trusted_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
static bool
ext2_xattr_trusted_list(struct dentry *dentry)
{
const int 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;
return capable(CAP_SYS_ADMIN);
}

static int
Expand Down
19 changes: 3 additions & 16 deletions fs/ext2/xattr_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,10 @@
#include "ext2.h"
#include "xattr.h"

static size_t
ext2_xattr_user_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
static bool
ext2_xattr_user_list(struct dentry *dentry)
{
const size_t prefix_len = XATTR_USER_PREFIX_LEN;
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;
return test_opt(dentry->d_sb, XATTR_USER);
}

static int
Expand Down
17 changes: 11 additions & 6 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
const struct xattr_handler *handler =
ext4_xattr_handler(entry->e_name_index);

if (handler) {
size_t size = handler->list(handler, dentry, buffer,
rest, entry->e_name,
entry->e_name_len);
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;

if (buffer) {
if (size > rest)
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;
}
}
return buffer_size - rest;
return buffer_size - rest; /* total size */
}

static int
Expand Down
18 changes: 0 additions & 18 deletions fs/ext4/xattr_security.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,6 @@
#include "ext4.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
ext4_xattr_security_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
Expand Down Expand Up @@ -75,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,

const struct xattr_handler ext4_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext4_xattr_security_list,
.get = ext4_xattr_security_get,
.set = ext4_xattr_security_set,
};
19 changes: 3 additions & 16 deletions fs/ext4/xattr_trusted.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,10 @@
#include "ext4.h"
#include "xattr.h"

static size_t
ext4_xattr_trusted_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
static bool
ext4_xattr_trusted_list(struct dentry *dentry)
{
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;
return capable(CAP_SYS_ADMIN);
}

static int
Expand Down
19 changes: 3 additions & 16 deletions fs/ext4/xattr_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,10 @@
#include "ext4.h"
#include "xattr.h"

static size_t
ext4_xattr_user_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t name_len)
static bool
ext4_xattr_user_list(struct dentry *dentry)
{
const size_t prefix_len = XATTR_USER_PREFIX_LEN;
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;
return test_opt(dentry->d_sb, XATTR_USER);
}

static int
Expand Down
82 changes: 26 additions & 56 deletions fs/f2fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,40 +25,6 @@
#include "f2fs.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);
const char *prefix;
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 = xattr_prefix(handler);
prefix_len = strlen(prefix);
total_len = prefix_len + len + 1;
if (list && total_len <= list_size) {
memcpy(list, 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,
struct dentry *dentry, const char *name, void *buffer,
size_t size)
Expand Down Expand Up @@ -107,17 +73,16 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
value, size, NULL, flags);
}

static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler,
struct dentry *dentry, char *list, size_t list_size,
const char *name, size_t len)
static bool f2fs_xattr_user_list(struct dentry *dentry)
{
const char *xname = F2FS_SYSTEM_ADVISE_NAME;
size_t size;
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);

return test_opt(sbi, XATTR_USER);
}

size = strlen(xname) + 1;
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,
Expand Down Expand Up @@ -175,31 +140,29 @@ int f2fs_init_security(struct inode *inode, struct inode *dir,
const struct xattr_handler f2fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX,
.flags = F2FS_XATTR_INDEX_USER,
.list = f2fs_xattr_generic_list,
.list = f2fs_xattr_user_list,
.get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set,
};

const struct xattr_handler f2fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.flags = F2FS_XATTR_INDEX_TRUSTED,
.list = f2fs_xattr_generic_list,
.list = f2fs_xattr_trusted_list,
.get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set,
};

const struct xattr_handler f2fs_xattr_advise_handler = {
.name = F2FS_SYSTEM_ADVISE_NAME,
.flags = F2FS_XATTR_INDEX_ADVISE,
.list = f2fs_xattr_advise_list,
.get = f2fs_xattr_advise_get,
.set = f2fs_xattr_advise_set,
};

const struct xattr_handler f2fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.flags = F2FS_XATTR_INDEX_SECURITY,
.list = f2fs_xattr_generic_list,
.get = f2fs_xattr_generic_get,
.set = f2fs_xattr_generic_set,
};
Expand Down Expand Up @@ -447,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler =
f2fs_xattr_handler(entry->e_name_index);
const char *prefix;
size_t prefix_len;
size_t size;

if (!handler)
if (!handler || (handler->list && !handler->list(dentry)))
continue;

size = handler->list(handler, dentry, buffer, rest,
entry->e_name, entry->e_name_len);
if (buffer && size > rest) {
error = -ERANGE;
goto cleanup;
prefix = handler->prefix ?: handler->name;
prefix_len = strlen(prefix);
size = prefix_len + entry->e_name_len + 1;
if (buffer) {
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;
}
error = buffer_size - rest;
Expand Down
16 changes: 0 additions & 16 deletions fs/jffs2/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,8 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler,
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 = {
.prefix = XATTR_SECURITY_PREFIX,
.list = jffs2_security_listxattr,
.set = jffs2_security_setxattr,
.get = jffs2_security_getxattr
};
Loading

0 comments on commit 764a5c6

Please sign in to comment.