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: Christoph 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: Christian Brauner (Microsoft) <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2023-02-01 14:14:56 +01:00 committed by Christian Brauner (Microsoft)
parent 0c95c025a0
commit a5488f2983
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
6 changed files with 55 additions and 38 deletions

View File

@ -486,13 +486,9 @@ static int xattr_entrylist(struct xattr_iter *_it,
unsigned int prefix_len;
const char *prefix;
const struct xattr_handler *h =
erofs_xattr_handler(entry->e_name_index);
if (!h || (h->list && !h->list(it->dentry)))
prefix = erofs_xattr_prefix(entry->e_name_index, it->dentry);
if (!prefix)
return 1;
prefix = xattr_prefix(h);
prefix_len = strlen(prefix);
if (!it->buffer) {

View File

@ -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_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[] = {
[EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler,
#ifdef CONFIG_EROFS_FS_POSIX_ACL
@ -57,8 +60,13 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
#endif
};
return idx && idx < ARRAY_SIZE(xattr_handler_map) ?
xattr_handler_map[idx] : NULL;
if (idx && idx < ARRAY_SIZE(xattr_handler_map))
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[];

View File

@ -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)
static inline const struct xattr_handler *
ext2_xattr_handler(int name_index)
static inline const char *ext2_xattr_prefix(int name_index,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
handler = ext2_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
static bool
@ -329,11 +333,10 @@ bad_block:
/* list the attribute names */
for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
entry = EXT2_XATTR_NEXT(entry)) {
const struct xattr_handler *handler =
ext2_xattr_handler(entry->e_name_index);
const char *prefix;
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
prefix = ext2_xattr_prefix(entry->e_name_index, dentry);
if (prefix) {
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;

View File

@ -169,14 +169,18 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
bh->b_blocknr, BHDR(bh));
}
static inline const struct xattr_handler *
ext4_xattr_handler(int name_index)
static inline const char *ext4_xattr_prefix(int name_index,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
handler = ext4_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
static int
@ -736,11 +740,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
size_t rest = buffer_size;
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
const struct xattr_handler *handler =
ext4_xattr_handler(entry->e_name_index);
const char *prefix;
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
prefix = ext4_xattr_prefix(entry->e_name_index, dentry);
if (prefix) {
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;

View File

@ -212,13 +212,18 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
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;
if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
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,
@ -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);
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;
prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
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)
goto cleanup;
}
if (!handler || (handler->list && !handler->list(dentry)))
if (!prefix)
continue;
prefix = xattr_prefix(handler);
prefix_len = strlen(prefix);
size = prefix_len + entry->e_name_len + 1;
if (buffer) {

View File

@ -924,8 +924,9 @@ const struct xattr_handler *jffs2_xattr_handlers[] = {
NULL
};
static const struct xattr_handler *xprefix_to_handler(int xprefix) {
const struct xattr_handler *ret;
static const char *jffs2_xattr_prefix(int xprefix, struct dentry *dentry)
{
const struct xattr_handler *ret = NULL;
switch (xprefix) {
case JFFS2_XPREFIX_USER:
@ -948,10 +949,13 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) {
ret = &jffs2_trusted_xattr_handler;
break;
default:
ret = NULL;
break;
return NULL;
}
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)
@ -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_xattr_ref *ref, **pref;
struct jffs2_xattr_datum *xd;
const struct xattr_handler *xhandle;
const char *prefix;
ssize_t prefix_len, len, rc;
int retry = 0;
@ -994,10 +997,10 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
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;
prefix = xhandle->prefix ?: xhandle->name;
prefix_len = strlen(prefix);
rc = prefix_len + xd->name_len + 1;