Commit a5488f29 authored by Christian Brauner's avatar Christian Brauner Committed by Christian Brauner (Microsoft)

fs: simplify ->listxattr() implementation

The ext{2,4}, erofs, f2fs, and jffs2 filesystems use the same logic to
check whether a given xattr can be listed. Simplify them and avoid
open-coding the same check by calling the helper we introduced earlier.
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: linux-f2fs-devel@lists.sourceforge.net
Cc: linux-erofs@lists.ozlabs.org
Cc: linux-ext4@vger.kernel.org
Cc: linux-mtd@lists.infradead.org
Signed-off-by: default avatarChristian Brauner (Microsoft) <brauner@kernel.org>
parent 0c95c025
...@@ -486,13 +486,9 @@ static int xattr_entrylist(struct xattr_iter *_it, ...@@ -486,13 +486,9 @@ static int xattr_entrylist(struct xattr_iter *_it,
unsigned int prefix_len; unsigned int prefix_len;
const char *prefix; const char *prefix;
const struct xattr_handler *h = prefix = erofs_xattr_prefix(entry->e_name_index, it->dentry);
erofs_xattr_handler(entry->e_name_index); if (!prefix)
if (!h || (h->list && !h->list(it->dentry)))
return 1; return 1;
prefix = xattr_prefix(h);
prefix_len = strlen(prefix); prefix_len = strlen(prefix);
if (!it->buffer) { if (!it->buffer) {
......
...@@ -41,8 +41,11 @@ extern const struct xattr_handler erofs_xattr_user_handler; ...@@ -41,8 +41,11 @@ extern const struct xattr_handler erofs_xattr_user_handler;
extern const struct xattr_handler erofs_xattr_trusted_handler; extern const struct xattr_handler erofs_xattr_trusted_handler;
extern const struct xattr_handler erofs_xattr_security_handler; extern const struct xattr_handler erofs_xattr_security_handler;
static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx) static inline const char *erofs_xattr_prefix(unsigned int idx,
struct dentry *dentry)
{ {
const struct xattr_handler *handler = NULL;
static const struct xattr_handler *xattr_handler_map[] = { static const struct xattr_handler *xattr_handler_map[] = {
[EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler, [EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler,
#ifdef CONFIG_EROFS_FS_POSIX_ACL #ifdef CONFIG_EROFS_FS_POSIX_ACL
...@@ -57,8 +60,13 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx) ...@@ -57,8 +60,13 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
#endif #endif
}; };
return idx && idx < ARRAY_SIZE(xattr_handler_map) ? if (idx && idx < ARRAY_SIZE(xattr_handler_map))
xattr_handler_map[idx] : NULL; handler = xattr_handler_map[idx];
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
} }
extern const struct xattr_handler *erofs_xattr_handlers[]; extern const struct xattr_handler *erofs_xattr_handlers[];
......
...@@ -121,14 +121,18 @@ const struct xattr_handler *ext2_xattr_handlers[] = { ...@@ -121,14 +121,18 @@ const struct xattr_handler *ext2_xattr_handlers[] = {
#define EA_BLOCK_CACHE(inode) (EXT2_SB(inode->i_sb)->s_ea_block_cache) #define EA_BLOCK_CACHE(inode) (EXT2_SB(inode->i_sb)->s_ea_block_cache)
static inline const struct xattr_handler * static inline const char *ext2_xattr_prefix(int name_index,
ext2_xattr_handler(int name_index) struct dentry *dentry)
{ {
const struct xattr_handler *handler = NULL; const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
handler = ext2_xattr_handler_map[name_index]; handler = ext2_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
} }
static bool static bool
...@@ -329,11 +333,10 @@ ext2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -329,11 +333,10 @@ ext2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
/* list the attribute names */ /* list the attribute names */
for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
entry = EXT2_XATTR_NEXT(entry)) { entry = EXT2_XATTR_NEXT(entry)) {
const struct xattr_handler *handler = const char *prefix;
ext2_xattr_handler(entry->e_name_index);
if (handler && (!handler->list || handler->list(dentry))) { prefix = ext2_xattr_prefix(entry->e_name_index, dentry);
const char *prefix = handler->prefix ?: handler->name; if (prefix) {
size_t prefix_len = strlen(prefix); size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1; size_t size = prefix_len + entry->e_name_len + 1;
......
...@@ -169,14 +169,18 @@ static void ext4_xattr_block_csum_set(struct inode *inode, ...@@ -169,14 +169,18 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
bh->b_blocknr, BHDR(bh)); bh->b_blocknr, BHDR(bh));
} }
static inline const struct xattr_handler * static inline const char *ext4_xattr_prefix(int name_index,
ext4_xattr_handler(int name_index) struct dentry *dentry)
{ {
const struct xattr_handler *handler = NULL; const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
handler = ext4_xattr_handler_map[name_index]; handler = ext4_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
} }
static int static int
...@@ -736,11 +740,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, ...@@ -736,11 +740,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
size_t rest = buffer_size; size_t rest = buffer_size;
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
const struct xattr_handler *handler = const char *prefix;
ext4_xattr_handler(entry->e_name_index);
if (handler && (!handler->list || handler->list(dentry))) { prefix = ext4_xattr_prefix(entry->e_name_index, dentry);
const char *prefix = handler->prefix ?: handler->name; if (prefix) {
size_t prefix_len = strlen(prefix); size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1; size_t size = prefix_len + entry->e_name_len + 1;
......
...@@ -212,13 +212,18 @@ const struct xattr_handler *f2fs_xattr_handlers[] = { ...@@ -212,13 +212,18 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
NULL, NULL,
}; };
static inline const struct xattr_handler *f2fs_xattr_handler(int index) static inline const char *f2fs_xattr_prefix(int index,
struct dentry *dentry)
{ {
const struct xattr_handler *handler = NULL; const struct xattr_handler *handler = NULL;
if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map)) if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
handler = f2fs_xattr_handler_map[index]; handler = f2fs_xattr_handler_map[index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
} }
static struct f2fs_xattr_entry *__find_xattr(void *base_addr, static struct f2fs_xattr_entry *__find_xattr(void *base_addr,
...@@ -569,12 +574,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -569,12 +574,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
last_base_addr = (void *)base_addr + XATTR_SIZE(inode); last_base_addr = (void *)base_addr + XATTR_SIZE(inode);
list_for_each_xattr(entry, base_addr) { list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler =
f2fs_xattr_handler(entry->e_name_index);
const char *prefix; const char *prefix;
size_t prefix_len; size_t prefix_len;
size_t size; size_t size;
prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
if ((void *)(entry) + sizeof(__u32) > last_base_addr || if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) { (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr", f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
...@@ -586,10 +591,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -586,10 +591,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
goto cleanup; goto cleanup;
} }
if (!handler || (handler->list && !handler->list(dentry))) if (!prefix)
continue; continue;
prefix = xattr_prefix(handler);
prefix_len = strlen(prefix); prefix_len = strlen(prefix);
size = prefix_len + entry->e_name_len + 1; size = prefix_len + entry->e_name_len + 1;
if (buffer) { if (buffer) {
......
...@@ -924,8 +924,9 @@ const struct xattr_handler *jffs2_xattr_handlers[] = { ...@@ -924,8 +924,9 @@ const struct xattr_handler *jffs2_xattr_handlers[] = {
NULL NULL
}; };
static const struct xattr_handler *xprefix_to_handler(int xprefix) { static const char *jffs2_xattr_prefix(int xprefix, struct dentry *dentry)
const struct xattr_handler *ret; {
const struct xattr_handler *ret = NULL;
switch (xprefix) { switch (xprefix) {
case JFFS2_XPREFIX_USER: case JFFS2_XPREFIX_USER:
...@@ -948,10 +949,13 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) { ...@@ -948,10 +949,13 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) {
ret = &jffs2_trusted_xattr_handler; ret = &jffs2_trusted_xattr_handler;
break; break;
default: default:
ret = NULL; return NULL;
break;
} }
return ret;
if (!xattr_handler_can_list(ret, dentry))
return NULL;
return xattr_prefix(ret);
} }
ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
...@@ -962,7 +966,6 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -962,7 +966,6 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct jffs2_inode_cache *ic = f->inocache; struct jffs2_inode_cache *ic = f->inocache;
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 char *prefix; const char *prefix;
ssize_t prefix_len, len, rc; ssize_t prefix_len, len, rc;
int retry = 0; int retry = 0;
...@@ -994,10 +997,10 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -994,10 +997,10 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
goto out; goto out;
} }
} }
xhandle = xprefix_to_handler(xd->xprefix);
if (!xhandle || (xhandle->list && !xhandle->list(dentry))) prefix = jffs2_xattr_prefix(xd->xprefix, dentry);
if (!prefix)
continue; continue;
prefix = xhandle->prefix ?: xhandle->name;
prefix_len = strlen(prefix); prefix_len = strlen(prefix);
rc = prefix_len + xd->name_len + 1; rc = prefix_len + xd->name_len + 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment