[Concept,10/21] ext4l: Make extended attributes (xattr) optional

Message ID 20260108185149.1995917-11-sjg@u-boot.org
State New
Headers
Series ext4l: Add Kconfig options to reduce binary size (part P) |

Commit Message

Simon Glass Jan. 8, 2026, 6:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add CONFIG_EXT4_XATTR to allow disabling support for extended
attributes. This saves about 14K on Thumb2 (e.g. firefly-rk3288).

When disabled, inline stub functions return -EOPNOTSUPP or 0 as
appropriate.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/Kconfig      | 10 ++++++
 fs/ext4l/Makefile     |  5 +--
 fs/ext4l/ext4_uboot.h |  2 ++
 fs/ext4l/super.c      |  2 +-
 fs/ext4l/xattr.h      | 83 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 99 insertions(+), 3 deletions(-)
  

Patch

diff --git a/fs/ext4l/Kconfig b/fs/ext4l/Kconfig
index 7bb1cbe7537..ee7b9bb2dd6 100644
--- a/fs/ext4l/Kconfig
+++ b/fs/ext4l/Kconfig
@@ -78,3 +78,13 @@  config EXT4_MOVE_EXTENT
 
 	  This adds about 1.5K to the image size. Not needed for U-Boot.
 	  If unsure, say N.
+
+config EXT4_XATTR
+	bool "Enable ext4 extended attributes support"
+	depends on FS_EXT4L
+	help
+	  Enable support for extended attributes (xattrs) on ext4
+	  filesystems. This is required for ACLs, security labels,
+	  and user-defined attributes.
+
+	  This adds about 14K to the image size. If unsure, say N.
diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile
index 262384b6bbb..720181908f8 100644
--- a/fs/ext4l/Makefile
+++ b/fs/ext4l/Makefile
@@ -9,10 +9,11 @@  obj-y := interface.o support.o stub.o
 obj-y	+= balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
 		extents_status.o file.o fsmap.o fsync.o hash.o ialloc.o \
 		indirect.o inline.o inode.o mballoc.o mmp.o namei.o \
-		page-io.o readpage.o super.o symlink.o xattr.o \
-		xattr_hurd.o xattr_trusted.o xattr_user.o fast_commit.o orphan.o
+		page-io.o readpage.o super.o symlink.o fast_commit.o orphan.o
 
 # Optional features
 obj-$(CONFIG_EXT4_RESIZE)	+= resize.o
 obj-$(CONFIG_EXT4_MIGRATE)	+= migrate.o
 obj-$(CONFIG_EXT4_MOVE_EXTENT)	+= move_extent.o
+obj-$(CONFIG_EXT4_XATTR)	+= xattr.o xattr_hurd.o xattr_trusted.o \
+				   xattr_user.o
diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index a34f5d74dfa..4a7e41a75a1 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -420,9 +420,11 @@  struct super_block;
 struct buffer_head;
 struct qstr;
 
+#ifdef CONFIG_EXT4_XATTR
 int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
 			     struct buffer_head *block_bh, size_t value_len,
 			     bool is_create);
+#endif
 /* ext4_init_security is provided by xattr.h */
 
 /* inode state stubs */
diff --git a/fs/ext4l/super.c b/fs/ext4l/super.c
index b2c95118220..d3e1b85ac5d 100644
--- a/fs/ext4l/super.c
+++ b/fs/ext4l/super.c
@@ -5421,7 +5421,7 @@  static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
 		needs_recovery = 0;
 	}
 
-	if (!test_opt(sb, NO_MBCACHE)) {
+	if (!test_opt(sb, NO_MBCACHE) && IS_ENABLED(CONFIG_EXT4_XATTR)) {
 		sbi->s_ea_block_cache = ext4_xattr_create_cache();
 		if (!sbi->s_ea_block_cache) {
 			ext4_msg(sb, KERN_ERR,
diff --git a/fs/ext4l/xattr.h b/fs/ext4l/xattr.h
index 1fedf44d4fb..f7b6de1743e 100644
--- a/fs/ext4l/xattr.h
+++ b/fs/ext4l/xattr.h
@@ -175,6 +175,7 @@  static inline void ext4_write_unlock_xattr(struct inode *inode, int *save)
 	up_write(&EXT4_I(inode)->xattr_sem);
 }
 
+#ifdef CONFIG_EXT4_XATTR
 extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
 
 extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
@@ -216,6 +217,88 @@  __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
 #define xattr_check_inode(inode, header, end) \
 	__xattr_check_inode((inode), (header), (end), __func__, __LINE__)
 
+#else /* !CONFIG_EXT4_XATTR */
+
+static inline ssize_t ext4_listxattr(struct dentry *d, char *b, size_t s)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
+					  struct ext4_xattr_inode_array **array,
+					  int extra_credits)
+{
+	return 0;
+}
+
+static inline void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *a)
+{
+}
+
+static inline void ext4_evict_ea_inode(struct inode *inode)
+{
+}
+
+#define ext4_xattr_handlers NULL
+
+static inline struct mb_cache *ext4_xattr_create_cache(void)
+{
+	return NULL;
+}
+
+static inline void ext4_xattr_destroy_cache(struct mb_cache *c)
+{
+}
+
+static inline int
+__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+		    void *end, const char *function, unsigned int line)
+{
+	return 0;
+}
+
+#define xattr_check_inode(inode, header, end) \
+	__xattr_check_inode((inode), (header), (end), __func__, __LINE__)
+
+static inline int __ext4_xattr_set_credits(struct super_block *sb,
+					   struct inode *inode,
+					   struct buffer_head *block_bh,
+					   size_t value_len, bool is_create)
+{
+	return 0;
+}
+
+static inline int ext4_expand_extra_isize_ea(struct inode *inode,
+					     int new_extra_isize,
+					     struct ext4_inode *raw_inode,
+					     handle_t *handle)
+{
+	return 0;
+}
+
+static inline int ext4_xattr_ibody_find(struct inode *inode,
+					struct ext4_xattr_info *i,
+					struct ext4_xattr_ibody_find *is)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int ext4_xattr_ibody_get(struct inode *inode, int name_index,
+				       const char *name, void *buffer,
+				       size_t buffer_size)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+				       struct ext4_xattr_info *i,
+				       struct ext4_xattr_ibody_find *is)
+{
+	return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_EXT4_XATTR */
+
 #ifdef CONFIG_EXT4_FS_SECURITY
 extern int ext4_init_security(handle_t *handle, struct inode *inode,
 			      struct inode *dir, const struct qstr *qstr);