[Concept,17/21] ext4l: Exclude write functions from read-only builds

Message ID 20260108185149.1995917-18-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>

The inode_operations structs contain function pointers for write
operations (create, unlink, mkdir, rename, setattr, etc.). Even when
CONFIG_EXT4_WRITE is disabled, these function pointers cause the linker
to include much of the write-related code.

Add an EXT4_WR_OP() macro that returns the function pointer when
CONFIG_EXT4_WRITE is enabled, or NULL when disabled. Apply this macro
to write operation entries in structs ext4_dir_inode_operations,
ext4_special_inode_operations, ext4_file_inode_operations and the
symlink inode_operations structs.

This reduces ext4l code size by about 15K on Thumb2 when write-support
is disabled.

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

 fs/ext4l/ext4.h    | 11 +++++++++++
 fs/ext4l/file.c    |  2 +-
 fs/ext4l/namei.c   | 28 ++++++++++++++--------------
 fs/ext4l/symlink.c |  6 +++---
 4 files changed, 29 insertions(+), 18 deletions(-)
  

Patch

diff --git a/fs/ext4l/ext4.h b/fs/ext4l/ext4.h
index 8d4e20e538a..9c182ad0d89 100644
--- a/fs/ext4l/ext4.h
+++ b/fs/ext4l/ext4.h
@@ -22,6 +22,17 @@ 
 #include <linux/jbd2.h>
 #include <linux/compiler.h>
 
+/*
+ * Macro for write operation function pointers in inode_operations structs.
+ * When CONFIG_EXT4_WRITE is disabled, these return NULL so the linker
+ * doesn't pull in the write functions.
+ */
+#ifdef CONFIG_EXT4_WRITE
+#define EXT4_WR_OP(func) (func)
+#else
+#define EXT4_WR_OP(func) NULL
+#endif
+
 /*
  * The fourth extended filesystem constants/structures
  */
diff --git a/fs/ext4l/file.c b/fs/ext4l/file.c
index 8cbc8c5f785..6f775c498cf 100644
--- a/fs/ext4l/file.c
+++ b/fs/ext4l/file.c
@@ -966,7 +966,7 @@  const struct file_operations ext4_file_operations = {
 
 /* U-Boot simplified inode operations */
 const struct inode_operations ext4_file_inode_operations = {
-	.setattr	= ext4_setattr,
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_file_getattr,
 	.listxattr	= ext4_listxattr,
 	.fiemap		= ext4_fiemap,
diff --git a/fs/ext4l/namei.c b/fs/ext4l/namei.c
index bede355d497..b8b6016a136 100644
--- a/fs/ext4l/namei.c
+++ b/fs/ext4l/namei.c
@@ -4199,30 +4199,30 @@  static int ext4_rename2(struct mnt_idmap *idmap,
  * directories can handle most operations...
  */
 const struct inode_operations ext4_dir_inode_operations = {
-	.create		= ext4_create,
+	.create		= EXT4_WR_OP(ext4_create),
 	.lookup		= ext4_lookup,
-	.link		= ext4_link,
-	.unlink		= ext4_unlink,
-	.symlink	= ext4_symlink,
-	.mkdir		= ext4_mkdir,
-	.rmdir		= ext4_rmdir,
-	.mknod		= ext4_mknod,
-	.tmpfile	= ext4_tmpfile,
-	.rename		= ext4_rename2,
-	.setattr	= ext4_setattr,
+	.link		= EXT4_WR_OP(ext4_link),
+	.unlink		= EXT4_WR_OP(ext4_unlink),
+	.symlink	= EXT4_WR_OP(ext4_symlink),
+	.mkdir		= EXT4_WR_OP(ext4_mkdir),
+	.rmdir		= EXT4_WR_OP(ext4_rmdir),
+	.mknod		= EXT4_WR_OP(ext4_mknod),
+	.tmpfile	= EXT4_WR_OP(ext4_tmpfile),
+	.rename		= EXT4_WR_OP(ext4_rename2),
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
 	.get_inode_acl	= ext4_get_acl,
-	.set_acl	= ext4_set_acl,
+	.set_acl	= EXT4_WR_OP(ext4_set_acl),
 	.fiemap         = ext4_fiemap,
 	.fileattr_get	= ext4_fileattr_get,
-	.fileattr_set	= ext4_fileattr_set,
+	.fileattr_set	= EXT4_WR_OP(ext4_fileattr_set),
 };
 
 const struct inode_operations ext4_special_inode_operations = {
-	.setattr	= ext4_setattr,
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
 	.get_inode_acl	= ext4_get_acl,
-	.set_acl	= ext4_set_acl,
+	.set_acl	= EXT4_WR_OP(ext4_set_acl),
 };
diff --git a/fs/ext4l/symlink.c b/fs/ext4l/symlink.c
index 2e4d0942a3b..dd3b82b5da2 100644
--- a/fs/ext4l/symlink.c
+++ b/fs/ext4l/symlink.c
@@ -115,21 +115,21 @@  static const char *ext4_get_link(struct dentry *dentry, struct inode *inode,
 
 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.get_link	= ext4_encrypted_get_link,
-	.setattr	= ext4_setattr,
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
 };
 
 const struct inode_operations ext4_symlink_inode_operations = {
 	.get_link	= ext4_get_link,
-	.setattr	= ext4_setattr,
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
 };
 
 const struct inode_operations ext4_fast_symlink_inode_operations = {
 	.get_link	= simple_get_link,
-	.setattr	= ext4_setattr,
+	.setattr	= EXT4_WR_OP(ext4_setattr),
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
 };