[Concept,03/10] ext4l: Add orphan.c and required support

Message ID 20251220232355.845414-4-sjg@u-boot.org
State New
Headers
Series ext4l: Add more ext4 files to the build (part D) |

Commit Message

Simon Glass Dec. 20, 2025, 11:23 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add orphan.c to the ext4l build and fix various build issues:

- Add atomic_inc/atomic_dec macros to ext4_uboot.h
- Add s_flags member to struct super_block and SB_RDONLY constant
- Add bdev_read_only() stub function
- Add kvfree() and kvmalloc_array() to linux/slab.h
- Add stub functions for orphan.c: ext4_reserve_inode_write,
  ext4_superblock_csum_set, ext4_mark_iloc_dirty, ext4_truncate,
  ext4_feature_set_ok, ext4_bread
- Fix orphan.c to use U-Boot include pattern
- Remove linux/atomic.h include from buffer_head.h (types provided
  by ext4_uboot.h)
- Add kunit/static_stub.h and linux/nospec.h stub headers
- Simplify seq_file.h macros

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

 fs/ext4l/Makefile           |  3 ++-
 fs/ext4l/ext4_uboot.h       | 48 ++++++++++++++++++++++++++++++++-----
 fs/ext4l/extents_status.c   |  1 -
 fs/ext4l/ialloc.c           |  1 -
 fs/ext4l/orphan.c           |  5 ++--
 fs/ext4l/stub.c             | 37 ++++++++++++++++++++++++++++
 include/kunit/static_stub.h | 13 ++++++++++
 include/linux/buffer_head.h | 12 ++++------
 include/linux/nospec.h      | 14 +++++++++++
 include/linux/seq_file.h    |  7 +++---
 include/linux/slab.h        | 10 ++++++++
 11 files changed, 127 insertions(+), 24 deletions(-)
 create mode 100644 include/kunit/static_stub.h
 create mode 100644 include/linux/nospec.h
  

Patch

diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile
index 4878523eae3..c5adb121f77 100644
--- a/fs/ext4l/Makefile
+++ b/fs/ext4l/Makefile
@@ -6,4 +6,5 @@ 
 obj-y := interface.o stub.o
 
 obj-y	+= balloc.o bitmap.o block_validity.o ext4_jbd2.o extents.o \
-		extents_status.o hash.o ialloc.o indirect.o
+		extents_status.o hash.o ialloc.o indirect.o \
+		orphan.o
diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index 943b474cdc8..6c328a5abf1 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -48,8 +48,24 @@  typedef struct { long counter; } atomic64_t;
 
 #define atomic_read(v)		((v)->counter)
 #define atomic_set(v, i)	((v)->counter = (i))
+#define atomic_inc(v)		((v)->counter++)
+#define atomic_dec(v)		((v)->counter--)
 #define atomic64_read(v)	((v)->counter)
 #define atomic64_set(v, i)	((v)->counter = (i))
+#define atomic_dec_if_positive(v)	(--(v)->counter)
+
+/* SMP stubs - U-Boot is single-threaded */
+#define raw_smp_processor_id()	0
+
+/* cmpxchg - compare and exchange, single-threaded version */
+#define cmpxchg(ptr, old, new) ({		\
+	typeof(*(ptr)) __old = (old);		\
+	typeof(*(ptr)) __new = (new);		\
+	typeof(*(ptr)) __ret = *(ptr);		\
+	if (__ret == __old)			\
+		*(ptr) = __new;			\
+	__ret;					\
+})
 
 /* Reference count type */
 typedef struct { atomic_t refs; } refcount_t;
@@ -58,10 +74,10 @@  typedef struct { atomic_t refs; } refcount_t;
 typedef int rwlock_t;
 /* spinlock_t is defined in linux/compat.h */
 
-#define read_lock(l)		do { (void)(l); } while (0)
-#define read_unlock(l)		do { (void)(l); } while (0)
-#define write_lock(l)		do { (void)(l); } while (0)
-#define write_unlock(l)		do { (void)(l); } while (0)
+#define read_lock(l)		do { } while (0)
+#define read_unlock(l)		do { } while (0)
+#define write_lock(l)		do { } while (0)
+#define write_unlock(l)		do { } while (0)
 
 /* RB tree types - stubs */
 struct rb_node {
@@ -374,7 +390,12 @@  struct qstr;
 int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
 			     struct buffer_head *block_bh, size_t value_len,
 			     bool is_create);
-/* ext4_init_security is declared in xattr.h */
+/* ext4_init_security - stub for files that don't include xattr.h */
+static inline int ext4_init_security(void *handle, struct inode *inode,
+				     struct inode *dir, const struct qstr *qstr)
+{
+	return 0;
+}
 
 /* inode state stubs */
 #define is_bad_inode(inode)			(0)
@@ -431,7 +452,7 @@  int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
 #define rb_next(node)		((node)->rb_right)
 #define rb_prev(node)		((node)->rb_left)
 #define rb_insert_color(node, root)	do { } while (0)
-#define rb_erase(node, root)		do { (void)(node); (void)(root); } while (0)
+#define rb_erase(node, root)		do { } while (0)
 #define rb_link_node(node, parent, rb_link)	do { *(rb_link) = (node); } while (0)
 #define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
 #define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
@@ -563,6 +584,9 @@  struct fstrim_range {
 
 /* block_device is defined in linux/fs.h */
 
+/* Superblock flags */
+#define SB_RDONLY		(1 << 0)
+
 /* super_block - minimal stub */
 struct super_block {
 	void *s_fs_info;
@@ -570,6 +594,7 @@  struct super_block {
 	unsigned char s_blocksize_bits;
 	unsigned long s_magic;
 	loff_t s_maxbytes;
+	unsigned long s_flags;
 	struct rw_semaphore s_umount;
 	struct sb_writers s_writers;
 	struct block_device *s_bdev;
@@ -577,9 +602,19 @@  struct super_block {
 	struct dentry *s_root;
 };
 
+/* Block device read-only check - stub */
+static inline int bdev_read_only(struct block_device *bdev)
+{
+	return 0;
+}
+
 /* kuid_t and kgid_t - from linux/cred.h */
 #include <linux/cred.h>
 
+/* Inode state bits */
+#define I_NEW			(1 << 0)
+#define I_FREEING		(1 << 1)
+
 /* inode - minimal stub */
 struct inode {
 	struct super_block *i_sb;
@@ -594,6 +629,7 @@  struct inode {
 	unsigned int i_generation;
 	unsigned int i_flags;
 	unsigned int i_blkbits;
+	unsigned long i_state;
 	struct timespec64 i_atime;
 	struct timespec64 i_mtime;
 	struct timespec64 i_ctime;
diff --git a/fs/ext4l/extents_status.c b/fs/ext4l/extents_status.c
index 72377fadd70..485f3a2f5cc 100644
--- a/fs/ext4l/extents_status.c
+++ b/fs/ext4l/extents_status.c
@@ -1741,7 +1741,6 @@  int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v)
 		    max->vfs_inode.i_ino, max->i_es_all_nr, max->i_es_shk_nr,
 		    div_u64(es_stats->es_stats_max_scan_time, 1000));
 
-	(void)es_stats;  /* Used only by seq_printf which is stubbed */
 	return 0;
 }
 
diff --git a/fs/ext4l/ialloc.c b/fs/ext4l/ialloc.c
index d72204a5d02..3d9edbcc1c3 100644
--- a/fs/ext4l/ialloc.c
+++ b/fs/ext4l/ialloc.c
@@ -16,7 +16,6 @@ 
 #include "ext4_uboot.h"
 #include "ext4.h"
 #include "ext4_jbd2.h"
-#include "xattr.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
diff --git a/fs/ext4l/orphan.c b/fs/ext4l/orphan.c
index 82d5e750145..32ec59b2978 100644
--- a/fs/ext4l/orphan.c
+++ b/fs/ext4l/orphan.c
@@ -1,10 +1,9 @@ 
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Ext4 orphan inode handling
  */
-#include <linux/fs.h>
-#include <linux/quotaops.h>
-#include <linux/buffer_head.h>
 
+#include "ext4_uboot.h"
 #include "ext4.h"
 #include "ext4_jbd2.h"
 
diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c
index 44cc4b7f52e..5a3eda0ad2e 100644
--- a/fs/ext4l/stub.c
+++ b/fs/ext4l/stub.c
@@ -395,3 +395,40 @@  int ext4_init_security(void *handle, struct inode *inode, struct inode *dir,
 {
 	return 0;
 }
+
+/*
+ * Stubs for orphan.c
+ */
+struct ext4_iloc;
+
+int ext4_reserve_inode_write(void *handle, struct inode *inode,
+			     struct ext4_iloc *iloc)
+{
+	return 0;
+}
+
+void ext4_superblock_csum_set(struct super_block *sb)
+{
+}
+
+int ext4_mark_iloc_dirty(void *handle, struct inode *inode,
+			 struct ext4_iloc *iloc)
+{
+	return 0;
+}
+
+int ext4_truncate(struct inode *inode)
+{
+	return 0;
+}
+
+int ext4_feature_set_ok(struct super_block *sb, int readonly)
+{
+	return 1;
+}
+
+struct buffer_head *ext4_bread(void *handle, struct inode *inode,
+			       unsigned long long block, int create)
+{
+	return NULL;
+}
diff --git a/include/kunit/static_stub.h b/include/kunit/static_stub.h
new file mode 100644
index 00000000000..995a919f641
--- /dev/null
+++ b/include/kunit/static_stub.h
@@ -0,0 +1,13 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _KUNIT_STATIC_STUB_H
+#define _KUNIT_STATIC_STUB_H
+
+/*
+ * Stub header for U-Boot ext4l.
+ *
+ * KUnit static stubs are for kernel unit testing - not needed in U-Boot.
+ */
+
+#define KUNIT_STATIC_STUB_REDIRECT(func, args...)	do { } while (0)
+
+#endif /* _KUNIT_STATIC_STUB_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 9c663741bef..b7596a74108 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -12,14 +12,10 @@ 
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
-
-/* Simple atomic_inc/dec for U-Boot (single-threaded) */
-#ifndef atomic_inc
-#define atomic_inc(v)	((v)->counter++)
-#endif
-#ifndef atomic_dec
-#define atomic_dec(v)	((v)->counter--)
-#endif
+/*
+ * Note: atomic_t and sector_t are expected to be defined by the including
+ * file (ext4_uboot.h) before including this header.
+ */
 
 enum bh_state_bits {
 	BH_Uptodate,	/* Contains valid data */
diff --git a/include/linux/nospec.h b/include/linux/nospec.h
new file mode 100644
index 00000000000..97d8271a00b
--- /dev/null
+++ b/include/linux/nospec.h
@@ -0,0 +1,14 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_NOSPEC_H
+#define _LINUX_NOSPEC_H
+
+/*
+ * Stub header for U-Boot ext4l.
+ *
+ * array_index_nospec bounds-checks array access, but in U-Boot's
+ * single-user environment this is not necessary.
+ */
+
+#define array_index_nospec(index, size)	(index)
+
+#endif /* _LINUX_NOSPEC_H */
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 1d43f23348a..fb5dbf97708 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -11,9 +11,8 @@  struct seq_file {
 	void *private;
 };
 
-#define seq_printf(m, fmt, ...) \
-	do { (void)(m); (void)(fmt); } while (0)
-#define seq_puts(m, s)			do { (void)(m); (void)(s); } while (0)
-#define seq_putc(m, c)			do { (void)(m); (void)(c); } while (0)
+#define seq_printf(m, fmt, ...)		do { } while (0)
+#define seq_puts(m, s)			do { } while (0)
+#define seq_putc(m, c)			do { } while (0)
 
 #endif /* _LINUX_SEQ_FILE_H */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 8da8f36e413..ac588dec6e2 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -67,6 +67,16 @@  static inline void kfree(const void *block)
 	free((void *)block);
 }
 
+static inline void kvfree(const void *addr)
+{
+	kfree(addr);
+}
+
+static inline void *kvmalloc_array(size_t n, size_t size, gfp_t flags)
+{
+	return kmalloc_array(n, size, flags);
+}
+
 static inline void *krealloc(const void *p, size_t new_size, gfp_t flags)
 {
 	return realloc((void *)p, new_size);