fs: simplify ->listxattr() implementation
authorChristian Brauner <brauner@kernel.org>
Wed, 1 Feb 2023 13:14:56 +0000 (14:14 +0100)
committerChristian Brauner (Microsoft) <brauner@kernel.org>
Mon, 6 Mar 2023 08:57:12 +0000 (09:57 +0100)
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>
fs/erofs/xattr.c
fs/erofs/xattr.h
fs/ext2/xattr.c
fs/ext4/xattr.c
fs/f2fs/xattr.c
fs/jffs2/xattr.c

index 3de058f..0154627 100644 (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) {
index 0a43c9e..08658e4 100644 (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[];
index 262951f..958976f 100644 (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;
 
index abe659e..09a9fad 100644 (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;
 
index 37cfc03..c8a2659 100644 (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) {
index 0eaec4a..1189a70 100644 (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;