[PATCH 00/19] ext4l: Reduce ext4_uboot.h size by moving code to include/linux
From: Simon Glass <simon.glass@canonical.com> This series reduces fs/ext4l/ext4_uboot.h from 2584 to 1980 lines (a 23% reduction) by moving definitions to appropriate include/linux/ header files. The ext4l subsystem requires many Linux kernel types and functions. Rather than keeping everything in one large file, this series creates proper stub headers in include/linux/ matching Linux kernel organisation: - ktime.h: Time functions and ktime_t type - rcupdate.h: RCU stubs (single-threaded no-ops) - shrinker.h: Memory-reclaim stubs - mm_types.h: VM stubs (address_space, vm_area_struct) - pagemap.h: Page cache and folio stubs - bio.h: Block I/O stubs - fs_context.h/fs_parser.h: Filesystem context types - dcache.h: Dentry and qstr types - uuid.h: UUID/GUID types - smp.h: SMP memory barriers - refcount.h: Reference counting type - kobject.h: Kobject stubs - xarray.h: XArray stubs - mempool.h: Memory pool stubs - kdev_t.h: Device number macros - fsmap.h: Filesystem map definitions Additionally, cmpxchg(), try_cmpxchg(), and xchg() are moved to asm-generic/atomic.h, and blk_plug is added to linux/blkdev.h. All implementations are appropriate stubs for U-Boot's single-threaded, no-VM, no-page-cache environment. Simon Glass (19): linux: Add ktime.h header with time functions linux: Add rcupdate.h header with RCU stubs linux: Add shrinker.h header with memory-reclaim stubs linux: Add mm_types.h header with VM stubs linux: Add pagemap.h header with folio and page cache stubs linux: Add bio.h header with block I/O stubs linux: Add fs_context.h and fs_parser.h headers linux: Add dcache.h header with dentry stubs linux: Add uuid.h header with UUID/GUID types asm-generic: atomic: Add cmpxchg() macro linux: Add smp.h header with SMP stubs linux: Add refcount.h header with refcount_t type linux: Add kobject.h header with kobject stubs linux: Add xarray.h header with XArray stubs linux: Add mempool.h header with memory pool stubs linux: Add kdev_t.h header with device number macros linux: blkdev: Add blk_plug structure and operations linux: Add fsmap.h header with filesystem map definitions asm-generic: atomic: Add xchg() and try_cmpxchg() macros fs/ext4l/ext4_fscrypt.h | 9 +- fs/ext4l/ext4_uboot.h | 738 ++++------------------------------- include/asm-generic/atomic.h | 55 +++ include/linux/bio.h | 117 ++++++ include/linux/blkdev.h | 25 ++ include/linux/dcache.h | 94 +++++ include/linux/fs_context.h | 154 ++++++++ include/linux/fs_parser.h | 110 ++++++ include/linux/fsmap.h | 46 +++ include/linux/kdev_t.h | 56 +++ include/linux/kobject.h | 34 ++ include/linux/ktime.h | 70 ++++ include/linux/mempool.h | 57 +++ include/linux/mm_types.h | 116 ++++++ include/linux/pagemap.h | 201 ++++++++++ include/linux/rcupdate.h | 54 +++ include/linux/refcount.h | 70 ++++ include/linux/shrinker.h | 83 ++++ include/linux/smp.h | 60 +++ include/linux/uuid.h | 120 ++++++ include/linux/xarray.h | 50 +++ 21 files changed, 1640 insertions(+), 679 deletions(-) create mode 100644 include/linux/bio.h create mode 100644 include/linux/dcache.h create mode 100644 include/linux/fs_context.h create mode 100644 include/linux/fs_parser.h create mode 100644 include/linux/fsmap.h create mode 100644 include/linux/kdev_t.h create mode 100644 include/linux/kobject.h create mode 100644 include/linux/ktime.h create mode 100644 include/linux/mempool.h create mode 100644 include/linux/mm_types.h create mode 100644 include/linux/pagemap.h create mode 100644 include/linux/rcupdate.h create mode 100644 include/linux/refcount.h create mode 100644 include/linux/shrinker.h create mode 100644 include/linux/smp.h create mode 100644 include/linux/uuid.h create mode 100644 include/linux/xarray.h -- 2.43.0 base-commit: 3f7c0f2d98ec4d41d0f15578358219ae2fdf8b88 branch: extr
From: Simon Glass <simon.glass@canonical.com> The ext4l filesystem uses several ktime functions which are currently defined inline in ext4_uboot.h. Create a new linux/ktime.h header file with these stub implementations to better match the Linux kernel structure. This reduces duplication and makes ext4_uboot.h smaller. Functions moved: - ktime_get() - ktime_to_ns() - ktime_sub() - ktime_add_ns() - ktime_get_ns() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 25 ++-------------- include/linux/ktime.h | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 22 deletions(-) create mode 100644 include/linux/ktime.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 91e0ce95467..04872c0a34e 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1032,26 +1032,8 @@ static inline void shrinker_free(struct shrinker *s) { } -/* ktime functions */ -static inline ktime_t ktime_get(void) -{ - return 0; -} - -static inline s64 ktime_to_ns(ktime_t kt) -{ - return kt; -} - -static inline ktime_t ktime_sub(ktime_t a, ktime_t b) -{ - return a - b; -} - -static inline ktime_t ktime_add_ns(ktime_t kt, s64 ns) -{ - return kt + ns; -} +/* ktime functions - use linux/ktime.h */ +#include <linux/ktime.h> /* hrtimer stubs */ #define HRTIMER_MODE_ABS 0 @@ -1983,8 +1965,7 @@ int IOPRIO_PRIO_VALUE(int class, int data); void *kvzalloc(size_t size, gfp_t flags); #define kvmalloc(size, flags) kvzalloc(size, flags) -/* Time operations */ -#define ktime_get_ns() (0ULL) +/* Time operations - ktime_get_ns is in linux/ktime.h */ /* nsecs_to_jiffies is in linux/jiffies.h */ /* Superblock write operations */ diff --git a/include/linux/ktime.h b/include/linux/ktime.h new file mode 100644 index 00000000000..c853e694823 --- /dev/null +++ b/include/linux/ktime.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ktime_t - nanosecond-resolution time format. + * + * Stub implementation for U-Boot. + */ +#ifndef _LINUX_KTIME_H +#define _LINUX_KTIME_H + +#include <linux/types.h> + +/* ktime_t is defined in linux/types.h */ + +/** + * ktime_get() - get current time + * + * U-Boot stub - returns 0 as we don't track real time during operations. + * + * Return: current time as ktime_t (always 0) + */ +static inline ktime_t ktime_get(void) +{ + return 0; +} + +/** + * ktime_to_ns() - convert ktime_t to nanoseconds + * @kt: the ktime_t value to convert + * + * Return: the nanosecond value + */ +static inline s64 ktime_to_ns(ktime_t kt) +{ + return kt; +} + +/** + * ktime_sub() - subtract two ktime_t values + * @a: first ktime_t value + * @b: second ktime_t value + * + * Return: a - b + */ +static inline ktime_t ktime_sub(ktime_t a, ktime_t b) +{ + return a - b; +} + +/** + * ktime_add_ns() - add nanoseconds to a ktime_t value + * @kt: base ktime_t value + * @ns: nanoseconds to add + * + * Return: kt + ns + */ +static inline ktime_t ktime_add_ns(ktime_t kt, s64 ns) +{ + return kt + ns; +} + +/** + * ktime_get_ns() - get current time in nanoseconds + * + * U-Boot stub - returns 0. + * + * Return: current time in nanoseconds (always 0) + */ +#define ktime_get_ns() (0ULL) + +#endif /* _LINUX_KTIME_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> U-Boot is single-threaded, so RCU (Read-Copy-Update) synchronisation is not needed. The ext4l filesystem uses several RCU macros which are currently defined in ext4_uboot.h. Create a new linux/rcupdate.h header file with stub implementations to better match the Linux kernel structure. This reduces duplication and makes ext4_uboot.h smaller. Stubs moved: - rcu_read_lock() / rcu_read_unlock() - rcu_dereference() / rcu_dereference_protected() - rcu_assign_pointer() - call_rcu() - synchronize_rcu() - rcu_barrier() - list_for_each_entry_rcu() - list_del_rcu() / list_add_rcu() / list_add_tail_rcu() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 21 +++------------- include/linux/rcupdate.h | 54 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 include/linux/rcupdate.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 04872c0a34e..47236e63911 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -357,14 +357,8 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode, /* Block group lock - stub */ #define bgl_lock_ptr(lock, group) NULL -/* RCU stubs */ -#define rcu_read_lock() do { } while (0) -#define rcu_read_unlock() do { } while (0) -#define rcu_dereference(p) (p) -#define rcu_dereference_protected(p, c) (p) -#define rcu_assign_pointer(p, v) ((p) = (v)) -#define call_rcu(head, func) do { func(head); } while (0) -#define synchronize_rcu() do { } while (0) +/* RCU stubs - use linux/rcupdate.h */ +#include <linux/rcupdate.h> /* RCU head for callbacks - defined in linux/compat.h as callback_head */ @@ -384,9 +378,6 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode, * implementation - do not stub them! */ -/* RCU barrier - stub */ -#define rcu_barrier() do { } while (0) - /* inode/dentry operations */ void iput(struct inode *inode); @@ -2198,13 +2189,7 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, /* atomic_sub, atomic64_sub, atomic_dec_and_test are in asm-generic/atomic.h */ -/* RCU list operations - use regular list operations in U-Boot */ -#define list_for_each_entry_rcu(pos, head, member, ...) \ - list_for_each_entry(pos, head, member) -#define list_del_rcu(entry) list_del(entry) -#define list_add_rcu(new, head) list_add(new, head) -#define list_add_tail_rcu(new, head) list_add_tail(new, head) -/* Other RCU stubs are defined earlier in this file */ +/* RCU list operations are in linux/rcupdate.h */ /* raw_cpu_ptr - get pointer to per-CPU data for current CPU */ #define raw_cpu_ptr(ptr) (ptr) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h new file mode 100644 index 00000000000..209e0d4ec8c --- /dev/null +++ b/include/linux/rcupdate.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Read-Copy Update mechanism stub for U-Boot + * + * U-Boot is single-threaded, so RCU operations are no-ops. + */ +#ifndef __LINUX_RCUPDATE_H +#define __LINUX_RCUPDATE_H + +#include <linux/list.h> + +/* + * RCU read-side critical section markers - no-ops in single-threaded U-Boot + */ +#define rcu_read_lock() do { } while (0) +#define rcu_read_unlock() do { } while (0) + +/* + * RCU pointer access - just return the pointer directly + */ +#define rcu_dereference(p) (p) +#define rcu_dereference_protected(p, c) (p) +#define rcu_dereference_raw(p) (p) + +/* + * RCU pointer assignment - direct assignment in single-threaded environment + */ +#define rcu_assign_pointer(p, v) ((p) = (v)) + +/* + * RCU callbacks - execute immediately in single-threaded U-Boot + */ +#define call_rcu(head, func) do { func(head); } while (0) + +/* + * Synchronize RCU - no-op since there are no concurrent readers + */ +#define synchronize_rcu() do { } while (0) + +/* + * RCU barrier - wait for all RCU callbacks to complete (no-op in U-Boot) + */ +#define rcu_barrier() do { } while (0) + +/* + * RCU list operations - use regular list operations in single-threaded U-Boot + */ +#define list_for_each_entry_rcu(pos, head, member, ...) \ + list_for_each_entry(pos, head, member) +#define list_del_rcu(entry) list_del(entry) +#define list_add_rcu(new, head) list_add(new, head) +#define list_add_tail_rcu(new, head) list_add_tail(new, head) + +#endif /* __LINUX_RCUPDATE_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> U-Boot does not have memory pressure or reclaim infrastructure. The ext4l filesystem uses shrinker structures which are currently defined in ext4_uboot.h. Create a new linux/shrinker.h header file with stub implementations to better match the Linux kernel structure. Types and functions moved: - struct shrink_control - struct shrinker - shrinker_alloc() - shrinker_register() - shrinker_free() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 32 +--------------- include/linux/shrinker.h | 83 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 include/linux/shrinker.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 47236e63911..d04a843175b 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -992,36 +992,8 @@ static inline int in_range(unsigned long val, unsigned long start, /* extents_status.c stubs */ -/* shrinker - memory reclaim infrastructure (stub for U-Boot) */ -struct shrink_control { - gfp_t gfp_mask; - int nid; - unsigned long nr_to_scan; - unsigned long nr_scanned; -}; - -struct shrinker { - unsigned long (*count_objects)(struct shrinker *, struct shrink_control *); - unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *); - void *private_data; -}; - -static inline struct shrinker *shrinker_alloc(unsigned int flags, - const char *fmt, ...) -{ - /* Return static dummy - U-Boot doesn't need memory reclamation */ - static struct shrinker dummy_shrinker; - - return &dummy_shrinker; -} - -static inline void shrinker_register(struct shrinker *s) -{ -} - -static inline void shrinker_free(struct shrinker *s) -{ -} +/* shrinker - use linux/shrinker.h */ +#include <linux/shrinker.h> /* ktime functions - use linux/ktime.h */ #include <linux/ktime.h> diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h new file mode 100644 index 00000000000..b95df9d6dc9 --- /dev/null +++ b/include/linux/shrinker.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Shrinker interface stub for U-Boot + * + * U-Boot doesn't have memory pressure or reclaim, so these are stubs. + */ +#ifndef _LINUX_SHRINKER_H +#define _LINUX_SHRINKER_H + +#include <linux/types.h> + +/** + * struct shrink_control - control structure for shrinker callbacks + * @gfp_mask: allocation flags + * @nid: NUMA node being shrunk + * @nr_to_scan: number of objects to scan + * @nr_scanned: number of objects scanned + * + * Stub for U-Boot - memory reclaim is not needed. + */ +struct shrink_control { + gfp_t gfp_mask; + int nid; + unsigned long nr_to_scan; + unsigned long nr_scanned; +}; + +struct shrinker; + +/** + * struct shrinker - memory reclaim callback structure + * @count_objects: callback to count freeable objects + * @scan_objects: callback to scan and free objects + * @private_data: private data for the shrinker + * + * Stub for U-Boot - memory reclaim is not needed. + */ +struct shrinker { + unsigned long (*count_objects)(struct shrinker *, + struct shrink_control *); + unsigned long (*scan_objects)(struct shrinker *, + struct shrink_control *); + void *private_data; +}; + +/** + * shrinker_alloc() - allocate a shrinker structure + * @flags: shrinker flags + * @fmt: format string for name (unused) + * + * U-Boot stub - returns a static dummy shrinker. + * + * Return: pointer to dummy shrinker + */ +static inline struct shrinker *shrinker_alloc(unsigned int flags, + const char *fmt, ...) +{ + static struct shrinker dummy_shrinker; + + return &dummy_shrinker; +} + +/** + * shrinker_register() - register a shrinker + * @s: shrinker to register + * + * U-Boot stub - no-op. + */ +static inline void shrinker_register(struct shrinker *s) +{ +} + +/** + * shrinker_free() - free a shrinker + * @s: shrinker to free + * + * U-Boot stub - no-op. + */ +static inline void shrinker_free(struct shrinker *s) +{ +} + +#endif /* _LINUX_SHRINKER_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> U-Boot does not have virtual memory management. The ext4l filesystem uses several VM-related types which are currently defined inline in ext4_uboot.h. Create a new linux/mm_types.h header file with stub implementations to better match the Linux kernel structure. Types moved: - struct page - vm_fault_t - VM_SHARED, VM_WRITE, VM_HUGEPAGE flags - FAULT_FLAG_WRITE - VM_FAULT_SIGBUS, VM_FAULT_NOPAGE, VM_FAULT_LOCKED - MAX_PAGECACHE_ORDER - struct vm_area_struct - struct vm_fault - struct vm_operations_struct - struct vm_area_desc Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 60 ++------------------ include/linux/mm_types.h | 116 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 55 deletions(-) create mode 100644 include/linux/mm_types.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index d04a843175b..6a06805329f 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -456,29 +456,15 @@ struct name_snapshot { struct qstr name; }; -/* vm_fault_t - stub */ -typedef unsigned int vm_fault_t; - -/* VM flags */ -#define VM_SHARED 0x00000008 -#define VM_WRITE 0x00000002 -#define VM_HUGEPAGE 0x01000000 -#define FAULT_FLAG_WRITE 0x01 +/* VM types - use linux/mm_types.h */ +#include <linux/mm_types.h> /* pipe_inode_info - forward declaration */ struct pipe_inode_info; -/* vm_area_desc - for mmap_prepare */ -struct vm_area_desc { - struct file *file; - unsigned long vm_flags; - const struct vm_operations_struct *vm_ops; -}; - -/* Forward declarations for function prototypes */ +/* Forward declarations for function prototypes (vm_fault is in linux/mm_types.h) */ struct kstat; struct path; -struct vm_fault; struct file_kattr; struct dir_context; struct readahead_control; @@ -592,10 +578,7 @@ static inline int bdev_read_only(struct block_device *bdev) #define STATX_ATTR_ENCRYPTED 0x00000800 #define STATX_ATTR_VERITY 0x00100000 -/* VM fault return values */ -#define VM_FAULT_SIGBUS 0x0002 -#define VM_FAULT_NOPAGE 0x0010 -#define VM_FAULT_LOCKED 0x0200 +/* VM fault return values are in linux/mm_types.h */ /* struct path is defined in linux/fs.h */ @@ -625,44 +608,11 @@ struct kstat { u32 atomic_write_segments_max; }; -/* struct vm_area_struct - virtual memory area */ -struct vm_area_struct { - unsigned long vm_start; - unsigned long vm_end; - struct file *vm_file; - unsigned long vm_flags; -}; - -/* struct page - minimal stub */ -struct page { - unsigned long flags; -}; - -/* struct vm_fault - virtual memory fault info */ -struct vm_fault { - struct vm_area_struct *vma; - unsigned long address; - unsigned int flags; - pgoff_t pgoff; - struct folio *folio; - struct page *page; -}; - -/* vm_operations_struct - virtual memory area operations */ -struct vm_operations_struct { - vm_fault_t (*fault)(struct vm_fault *vmf); - vm_fault_t (*huge_fault)(struct vm_fault *vmf, unsigned int order); - vm_fault_t (*page_mkwrite)(struct vm_fault *vmf); - vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf); - vm_fault_t (*map_pages)(struct vm_fault *vmf, pgoff_t start, pgoff_t end); -}; +/* VM structs (vm_area_struct, page, vm_fault, vm_operations_struct) are in linux/mm_types.h */ /* Forward declaration for swap */ struct swap_info_struct; -/* MAX_PAGECACHE_ORDER - maximum order for page cache allocations */ -#define MAX_PAGECACHE_ORDER 12 - /* Process flags */ #define PF_MEMALLOC 0x00000800 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h new file mode 100644 index 00000000000..57a52769b05 --- /dev/null +++ b/include/linux/mm_types.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Memory management types stub for U-Boot + * + * U-Boot doesn't have virtual memory management, so these are stubs. + */ +#ifndef _LINUX_MM_TYPES_H +#define _LINUX_MM_TYPES_H + +#include <linux/types.h> + +/* Forward declarations */ +struct file; +struct folio; +struct address_space; + +/** + * struct page - minimal stub for page structure + * @flags: page flags + * + * U-Boot stub - only the flags field is provided. + */ +struct page { + unsigned long flags; +}; + +/** + * typedef vm_fault_t - return type for page fault handlers + * + * Encodes the result of a page fault. + */ +typedef unsigned int vm_fault_t; + +/* VM flags for vm_area_struct */ +#define VM_SHARED 0x00000008 +#define VM_WRITE 0x00000002 +#define VM_HUGEPAGE 0x01000000 + +/* Fault flags */ +#define FAULT_FLAG_WRITE 0x01 + +/* VM fault return values */ +#define VM_FAULT_SIGBUS 0x0002 +#define VM_FAULT_NOPAGE 0x0010 +#define VM_FAULT_LOCKED 0x0200 + +/* Maximum order for page cache allocations */ +#define MAX_PAGECACHE_ORDER 12 + +struct vm_operations_struct; + +/** + * struct vm_area_struct - virtual memory area + * @vm_start: start address + * @vm_end: end address + * @vm_file: file this vma is associated with + * @vm_flags: VM flags + * + * U-Boot stub. + */ +struct vm_area_struct { + unsigned long vm_start; + unsigned long vm_end; + struct file *vm_file; + unsigned long vm_flags; +}; + +/** + * struct vm_fault - virtual memory fault info + * @vma: virtual memory area + * @address: faulting address + * @flags: fault flags + * @pgoff: page offset + * @folio: folio being faulted + * @page: page being faulted + * + * U-Boot stub. + */ +struct vm_fault { + struct vm_area_struct *vma; + unsigned long address; + unsigned int flags; + pgoff_t pgoff; + struct folio *folio; + struct page *page; +}; + +/** + * struct vm_operations_struct - virtual memory area operations + * + * Callbacks for VM operations. U-Boot stub. + */ +struct vm_operations_struct { + vm_fault_t (*fault)(struct vm_fault *vmf); + vm_fault_t (*huge_fault)(struct vm_fault *vmf, unsigned int order); + vm_fault_t (*page_mkwrite)(struct vm_fault *vmf); + vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf); + vm_fault_t (*map_pages)(struct vm_fault *vmf, pgoff_t start, + pgoff_t end); +}; + +/** + * struct vm_area_desc - for mmap_prepare + * @file: associated file + * @vm_flags: VM flags + * @vm_ops: VM operations + * + * U-Boot stub. + */ +struct vm_area_desc { + struct file *file; + unsigned long vm_flags; + const struct vm_operations_struct *vm_ops; +}; + +#endif /* _LINUX_MM_TYPES_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> U-Boot does not have a real page cache or VM system. The ext4l filesystem uses many folio and filemap operations which are currently defined inline in ext4_uboot.h. Create a new linux/pagemap.h header file with stub implementations to better match the Linux kernel structure. This significantly reduces duplication and makes ext4_uboot.h smaller. Types and operations moved: - struct folio - FGP_* flags for __filemap_get_folio() - PAGECACHE_TAG_* constants - folio operation stubs (folio_mark_dirty, folio_test_*, etc.) - filemap operation stubs (filemap_invalidate_*, filemap_write_*, etc.) - truncate stubs (truncate_pagecache, truncate_inode_pages, etc.) - readahead stubs (readahead_pos, readahead_length, etc.) - kmap/kunmap stubs - struct readahead_control Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 192 +++----------------------------------- include/linux/pagemap.h | 201 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 177 deletions(-) create mode 100644 include/linux/pagemap.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 6a06805329f..40c68085c7a 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -394,8 +394,7 @@ struct sb_writers { int frozen; }; -/* mapping_large_folio_support stub */ -#define mapping_large_folio_support(m) (0) +/* mapping_large_folio_support is in linux/pagemap.h */ /* sector_t is now in linux/types.h */ @@ -870,28 +869,7 @@ static inline unsigned long memweight(const void *ptr, size_t bytes) /* Security checks - no security in U-Boot */ #define IS_NOSEC(inode) (1) -/* Filemap operations */ -#define filemap_invalidate_lock(m) do { } while (0) -#define filemap_invalidate_unlock(m) do { } while (0) -#define filemap_invalidate_lock_shared(m) do { } while (0) -#define filemap_invalidate_unlock_shared(m) do { } while (0) -#define filemap_write_and_wait_range(m, s, e) ({ (void)(m); (void)(s); (void)(e); 0; }) -#define filemap_fdatawrite_range(m, s, e) ({ (void)(m); (void)(s); (void)(e); 0; }) -#define truncate_pagecache(i, s) do { } while (0) -#define pagecache_isize_extended(i, f, t) do { } while (0) -#define invalidate_mapping_pages(m, s, e) do { (void)(m); (void)(s); (void)(e); } while (0) - -/* Filemap fault handlers - stubs */ -static inline vm_fault_t filemap_fault(struct vm_fault *vmf) -{ - return 0; -} - -static inline vm_fault_t filemap_map_pages(struct vm_fault *vmf, - pgoff_t start, pgoff_t end) -{ - return 0; -} +/* Filemap operations and fault handlers are in linux/pagemap.h */ /* DAX device mapping check - always false in U-Boot */ #define daxdev_mapping_supported(f, i, d) ({ (void)(f); (void)(i); (void)(d); 1; }) @@ -935,8 +913,7 @@ static inline int in_range(unsigned long val, unsigned long start, /* umin - unsigned min (Linux 6.x) */ #define umin(x, y) ((x) < (y) ? (x) : (y)) -/* truncate_inode_pages - stub */ -#define truncate_inode_pages(m, s) do { } while (0) +/* truncate_inode_pages is in linux/pagemap.h */ /* ext4_sb_bread_nofail is stubbed in interface.c */ @@ -966,48 +943,12 @@ static inline int in_range(unsigned long val, unsigned long start, /* SEQ_START_TOKEN is in linux/seq_file.h */ -/* folio - memory page container stub */ -struct folio { - struct page *page; - unsigned long index; - struct address_space *mapping; - unsigned long flags; - void *data; - struct buffer_head *private; - int _refcount; -}; - -/* struct folio_batch is in linux/pagevec.h */ - -/* folio operations - stubs */ -#define folio_mark_dirty(f) do { (void)(f); } while (0) -/* - * offset_in_folio - calculate offset of pointer within folio's data - * In Linux this uses page alignment, but in U-Boot we use the folio's - * actual data pointer since our buffers are malloc'd. - */ -#define offset_in_folio(f, p) ((f) ? (unsigned int)((uintptr_t)(p) - (uintptr_t)(f)->data) : 0U) -#define folio_buffers(f) ({ (void)(f); (struct buffer_head *)NULL; }) -#define virt_to_folio(p) ({ (void)(p); (struct folio *)NULL; }) -#define folio_set_bh(bh, f, off) do { if ((bh) && (f)) { (bh)->b_folio = (f); (bh)->b_data = (char *)(f)->data + (off); } } while (0) -#define memcpy_from_folio(dst, f, off, len) do { (void)(dst); (void)(f); (void)(off); (void)(len); } while (0) -#define folio_test_uptodate(f) ({ (void)(f); 1; }) -#define folio_pos(f) ({ (void)(f); 0LL; }) -#define folio_size(f) ({ (void)(f); PAGE_SIZE; }) -#define folio_unlock(f) do { (void)(f); } while (0) -/* folio_put and folio_get are implemented in support.c */ -#define folio_lock(f) do { (void)(f); } while (0) -/* folio_batch_init is in linux/pagevec.h */ -#define filemap_get_folios(m, i, e, fb) ({ (void)(m); (void)(i); (void)(e); (void)(fb); 0U; }) +/* folio and pagemap - use linux/pagemap.h */ +#include <linux/pagemap.h> /* xa_mark_t - xarray mark type */ typedef unsigned int xa_mark_t; -/* Page cache tags */ -#define PAGECACHE_TAG_DIRTY 0 -#define PAGECACHE_TAG_TOWRITE 1 -#define PAGECACHE_TAG_WRITEBACK 2 - static inline xa_mark_t wbc_to_tag(struct writeback_control *wbc) { if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) @@ -1025,54 +966,9 @@ struct blk_plug { /* Writeback reasons */ #define WB_REASON_FS_FREE_SPACE 0 -/* readahead_control stub */ -struct readahead_control { - struct address_space *mapping; - struct file *file; - unsigned long _index; - unsigned int _batch_count; -}; - -#define readahead_pos(rac) ({ (void)(rac); 0LL; }) -#define readahead_length(rac) ({ (void)(rac); 0UL; }) - /* address_space_operations is in linux/fs.h */ /* buffer_migrate_folio, buffer_migrate_folio_norefs, noop_dirty_folio are in linux/buffer_head.h */ - -/* Stub implementations for address_space_operations callbacks */ -static inline bool block_is_partially_uptodate(struct folio *folio, - size_t from, size_t count) -{ - return false; -} - -static inline int generic_error_remove_folio(struct address_space *mapping, - struct folio *folio) -{ - return 0; -} - -/* FGP flags for folio_grab_cache */ -#define FGP_ACCESSED 0x00000001 -#define FGP_LOCK 0x00000002 -#define FGP_CREAT 0x00000004 -#define FGP_WRITE 0x00000008 -#define FGP_NOFS 0x00000010 -#define FGP_NOWAIT 0x00000020 -#define FGP_FOR_MMAP 0x00000040 -#define FGP_STABLE 0x00000080 -#define FGP_WRITEBEGIN (FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE) - -/* kmap/kunmap stubs for inline.c */ -#define kmap_local_folio(folio, off) ((folio) ? (char *)(folio)->data + (off) : NULL) -#define kunmap_local(addr) do { (void)(addr); } while (0) - -/* Folio zeroing stubs for inline.c */ -#define folio_zero_tail(f, off, kaddr) ({ (void)(f); (void)(off); (void)(kaddr); (void *)NULL; }) -#define folio_zero_segment(f, s, e) do { (void)(f); (void)(s); (void)(e); } while (0) - -/* mapping_gfp_mask stub */ -#define mapping_gfp_mask(m) ({ (void)(m); GFP_KERNEL; }) +/* readahead_control, FGP_*, kmap/kunmap, folio stubs are in linux/pagemap.h */ /* Folio operations - implemented in support.c */ struct folio *__filemap_get_folio(struct address_space *mapping, @@ -1154,43 +1050,8 @@ static inline char *d_path(const struct path *path, char *buf, int buflen) #define inode_is_open_for_write(i) (0) #define inode_is_dirtytime_only(i) (0) -/* Writeback stubs for super.c */ -#define writeback_iter(mapping, wbc, folio, error) \ - ({ (void)(mapping); (void)(wbc); (void)(error); (struct folio *)NULL; }) -#define folio_redirty_for_writepage(wbc, folio) \ - ({ (void)(wbc); (void)(folio); false; }) - -/* Folio operations - additional stubs */ -#define folio_zero_segments(f, s1, e1, s2, e2) do { } while (0) -#define folio_zero_new_buffers(f, f2, t) do { } while (0) -#define folio_wait_stable(f) do { } while (0) -#define folio_zero_range(f, s, l) do { } while (0) -#define folio_mark_uptodate(f) do { } while (0) -#define folio_next_index(f) ((f)->index + 1) -#define folio_next_pos(f) ((loff_t)folio_next_index(f) << PAGE_SHIFT) -#define folio_mapped(f) (0) - -/* - * fgf_set_order - Set the order (size) for folio allocation - * U-Boot doesn't support large folios, so this is a no-op stub. - */ -#define fgf_set_order(size) (0) -#define folio_clear_dirty_for_io(f) ({ (void)(f); 1; }) -#define folio_clear_uptodate(f) do { } while (0) +/* Folio operations and writeback stubs are in linux/pagemap.h */ #define folio_batch_release(fb) do { } while (0) -#define folio_nr_pages(f) (1UL) -#define folio_contains(f, idx) ({ (void)(f); (void)(idx); 1; }) -#define folio_clear_checked(f) do { } while (0) -#define folio_test_dirty(f) (0) -#define folio_test_writeback(f) (0) -#define folio_wait_writeback(f) do { } while (0) -#define folio_clear_dirty(f) do { } while (0) -#define folio_test_checked(f) (0) -#define folio_maybe_dma_pinned(f) (0) -#define folio_set_checked(f) do { } while (0) -#define folio_test_locked(f) (0) -#define folio_mkclean(f) (0) -#define page_folio(page) ((struct folio *)(page)) /* Quota stubs - additional */ #define dquot_claim_block(i, n) ({ (void)(i); (void)(n); 0; }) @@ -1202,20 +1063,8 @@ static inline char *d_path(const struct path *path, char *buf, int buflen) /* percpu_counter_sub is in linux/percpu_counter.h */ -/* Filemap operations - additional */ -#define filemap_get_folio(m, i) ((struct folio *)NULL) -#define filemap_get_folios_tag(m, s, e, t, fb) ({ (void)(m); (void)(s); (void)(e); (void)(t); (void)(fb); 0U; }) -#define filemap_flush(m) ({ (void)(m); 0; }) -#define filemap_write_and_wait(m) ({ (void)(m); 0; }) -#define filemap_dirty_folio(m, f) ({ (void)(m); (void)(f); false; }) -#define filemap_lock_folio(m, i) ((struct folio *)NULL) -/* filemap_invalidate_lock_shared defined earlier */ -#define mapping_tagged(m, t) (0) -#define tag_pages_for_writeback(m, s, e) do { } while (0) +/* Filemap operations are in linux/pagemap.h */ #define try_to_writeback_inodes_sb(sb, r) do { } while (0) -#define mapping_gfp_constraint(m, g) (g) -#define mapping_set_folio_order_range(m, l, h) do { } while (0) -#define filemap_splice_read(i, p, pi, l, f) ({ (void)(i); (void)(p); (void)(pi); (void)(l); (void)(f); 0L; }) /* Buffer operations - additional */ #define getblk_unmovable(bdev, block, size) sb_getblk(bdev->bd_super, block) @@ -1340,9 +1189,7 @@ extern struct inode *iget_locked(struct super_block *sb, unsigned long ino); /* Block device alignment */ #define bdev_dma_alignment(bd) (0) -/* Truncation */ -#define truncate_inode_pages_final(m) do { } while (0) -#define truncate_pagecache_range(i, s, e) do { } while (0) +/* Truncation stubs are in linux/pagemap.h */ /* * Additional stubs for dir.c @@ -1353,9 +1200,7 @@ extern struct inode *iget_locked(struct super_block *sb, unsigned long ino); /* fscrypt directory operations are in ext4_fscrypt.h */ -/* Readahead operations */ -#define ra_has_index(ra, idx) ({ (void)(ra); (void)(idx); 0; }) -#define page_cache_sync_readahead(m, ra, f, i, n) do { } while (0) +/* Readahead operations are in linux/pagemap.h */ /* Inode version operations */ #define inode_eq_iversion(i, v) ({ (void)(i); (void)(v); 1; }) @@ -2072,9 +1917,7 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, /* CPU cycle counter stub */ #define get_cycles() (0ULL) -/* folio_address - get virtual address of folio data */ -#undef folio_address -#define folio_address(folio) ((folio)->data) +/* folio_address is in linux/pagemap.h */ /* sb_end_intwrite defined earlier */ @@ -2243,9 +2086,7 @@ typedef void *mempool_t; #define fsverity_verify_folio(f) ({ (void)(f); 1; }) #define IS_VERITY(inode) (0) -/* readahead operations */ -#define readahead_count(rac) ({ (void)(rac); 0UL; }) -#define readahead_folio(rac) ({ (void)(rac); (struct folio *)NULL; }) +/* readahead operations are in linux/pagemap.h */ /* prefetch operations */ #define prefetchw(addr) do { (void)(addr); } while (0) @@ -2300,10 +2141,9 @@ struct wait_bit_entry { #define write_dirty_buffer(bh, flags) sync_dirty_buffer(bh) #define spin_needbreak(l) ({ (void)(l); 0; }) -/* JBD2 commit.c stubs */ +/* JBD2 commit.c stubs (folio_trylock is in linux/pagemap.h) */ #define clear_bit_unlock(nr, addr) clear_bit(nr, addr) #define smp_mb__after_atomic() do { } while (0) -#define folio_trylock(f) ({ (void)(f); 1; }) #define ktime_get_coarse_real_ts64(ts) do { (ts)->tv_sec = 0; (ts)->tv_nsec = 0; } while (0) #define filemap_fdatawait_range_keep_errors(m, s, e) \ ({ (void)(m); (void)(s); (void)(e); 0; }) @@ -2379,7 +2219,7 @@ int bh_read(struct buffer_head *bh, int flags); #ifndef SECTOR_SHIFT #define SECTOR_SHIFT 9 #endif -#define mapping_max_folio_order(m) ({ (void)(m); 0; }) +/* mapping_max_folio_order is in linux/pagemap.h */ /* Memory allocation for journal.c */ #define __get_free_pages(gfp, order) ((unsigned long)memalign(PAGE_SIZE, PAGE_SIZE << (order))) @@ -2410,9 +2250,7 @@ static inline struct new_utsname *init_utsname(void) #define down_write_nested(sem, subclass) \ do { (void)(sem); (void)(subclass); } while (0) -/* filemap_release_folio - try to release a folio */ -#define filemap_release_folio(folio, gfp) \ - ({ (void)(folio); (void)(gfp); 1; }) +/* filemap_release_folio is in linux/pagemap.h */ /* IS_SWAPFILE - check if inode is a swap file */ #define IS_SWAPFILE(inode) ({ (void)(inode); 0; }) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h new file mode 100644 index 00000000000..19a64993955 --- /dev/null +++ b/include/linux/pagemap.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Page cache and folio management stubs for U-Boot + * + * U-Boot doesn't have a real page cache, so these are stubs. + */ +#ifndef _LINUX_PAGEMAP_H +#define _LINUX_PAGEMAP_H + +#include <linux/types.h> +#include <linux/mm_types.h> + +/* Forward declarations */ +struct address_space; +struct buffer_head; + +/** + * struct folio - memory page container stub + * @page: associated page + * @index: page index in the mapping + * @mapping: address space this folio belongs to + * @flags: folio flags + * @data: pointer to the actual data + * @private: private data for filesystem + * @_refcount: reference count + * + * U-Boot stub - simplified folio structure. + */ +struct folio { + struct page *page; + unsigned long index; + struct address_space *mapping; + unsigned long flags; + void *data; + struct buffer_head *private; + int _refcount; +}; + +/* FGP flags for __filemap_get_folio() */ +#define FGP_ACCESSED 0x00000001 +#define FGP_LOCK 0x00000002 +#define FGP_CREAT 0x00000004 +#define FGP_WRITE 0x00000008 +#define FGP_NOFS 0x00000010 +#define FGP_NOWAIT 0x00000020 +#define FGP_FOR_MMAP 0x00000040 +#define FGP_STABLE 0x00000080 +#define FGP_WRITEBEGIN (FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE) + +/* Page cache tags */ +#define PAGECACHE_TAG_DIRTY 0 +#define PAGECACHE_TAG_TOWRITE 1 +#define PAGECACHE_TAG_WRITEBACK 2 + +/* Folio operations - stubs */ +#define folio_mark_dirty(f) do { (void)(f); } while (0) +#define folio_test_uptodate(f) ({ (void)(f); 1; }) +#define folio_pos(f) ({ (void)(f); 0LL; }) +#define folio_size(f) ({ (void)(f); PAGE_SIZE; }) +#define folio_unlock(f) do { (void)(f); } while (0) +#define folio_lock(f) do { (void)(f); } while (0) +#define folio_buffers(f) ({ (void)(f); (struct buffer_head *)NULL; }) +#define virt_to_folio(p) ({ (void)(p); (struct folio *)NULL; }) +#define folio_zero_tail(f, off, kaddr) ({ (void)(f); (void)(off); (void)(kaddr); (void *)NULL; }) +#define folio_zero_segment(f, s, e) do { (void)(f); (void)(s); (void)(e); } while (0) +#define folio_zero_segments(f, s1, e1, s2, e2) do { } while (0) +#define folio_zero_new_buffers(f, f2, t) do { } while (0) +#define folio_wait_stable(f) do { } while (0) +#define folio_zero_range(f, s, l) do { } while (0) +#define folio_mark_uptodate(f) do { } while (0) +#define folio_next_index(f) ((f)->index + 1) +#define folio_next_pos(f) ((loff_t)folio_next_index(f) << PAGE_SHIFT) +#define folio_mapped(f) (0) +#define fgf_set_order(size) (0) +#define folio_clear_dirty_for_io(f) ({ (void)(f); 1; }) +#define folio_clear_uptodate(f) do { } while (0) +#define folio_nr_pages(f) (1UL) +#define folio_contains(f, idx) ({ (void)(f); (void)(idx); 1; }) +#define folio_clear_checked(f) do { } while (0) +#define folio_test_dirty(f) (0) +#define folio_test_writeback(f) (0) +#define folio_wait_writeback(f) do { } while (0) +#define folio_clear_dirty(f) do { } while (0) +#define folio_test_checked(f) (0) +#define folio_maybe_dma_pinned(f) (0) +#define folio_set_checked(f) do { } while (0) +#define folio_test_locked(f) (0) +#define folio_mkclean(f) (0) +#define page_folio(page) ((struct folio *)(page)) +#define folio_address(folio) ((folio)->data) +#define folio_trylock(f) ({ (void)(f); 1; }) + +/* Folio writeback operations */ +#define folio_end_writeback(f) do { (void)(f); } while (0) +#define folio_start_writeback(f) do { (void)(f); } while (0) +#define folio_start_writeback_keepwrite(f) do { (void)(f); } while (0) +#define folio_end_read(f, success) do { (void)(f); (void)(success); } while (0) +#define folio_set_mappedtodisk(f) do { (void)(f); } while (0) +#define folio_redirty_for_writepage(wbc, folio) \ + ({ (void)(wbc); (void)(folio); false; }) + +/* + * offset_in_folio - calculate offset of pointer within folio's data + * + * In Linux this uses page alignment, but in U-Boot we use the folio's + * actual data pointer since our buffers are malloc'd. + */ +#define offset_in_folio(f, p) ((f) ? (unsigned int)((uintptr_t)(p) - (uintptr_t)(f)->data) : 0U) + +/* folio_set_bh - associate buffer_head with folio */ +#define folio_set_bh(bh, f, off) do { if ((bh) && (f)) { (bh)->b_folio = (f); (bh)->b_data = (char *)(f)->data + (off); } } while (0) + +#define memcpy_from_folio(dst, f, off, len) do { (void)(dst); (void)(f); (void)(off); (void)(len); } while (0) + +/* kmap/kunmap for folio access */ +#define kmap_local_folio(folio, off) ((folio) ? (char *)(folio)->data + (off) : NULL) +#define kunmap_local(addr) do { (void)(addr); } while (0) + +/* mapping_gfp_mask - get GFP mask for address_space */ +#define mapping_gfp_mask(m) ({ (void)(m); GFP_KERNEL; }) + +/* mapping_large_folio_support stub */ +#define mapping_large_folio_support(m) (0) + +/* Filemap operations - stubs */ +#define filemap_get_folios(m, i, e, fb) ({ (void)(m); (void)(i); (void)(e); (void)(fb); 0U; }) +#define filemap_get_folio(m, i) ((struct folio *)NULL) +#define filemap_get_folios_tag(m, s, e, t, fb) \ + ({ (void)(m); (void)(s); (void)(e); (void)(t); (void)(fb); 0U; }) +#define filemap_lock_folio(m, i) ((struct folio *)NULL) +#define filemap_dirty_folio(m, f) ({ (void)(m); (void)(f); false; }) +#define filemap_invalidate_lock(m) do { } while (0) +#define filemap_invalidate_unlock(m) do { } while (0) +#define filemap_invalidate_lock_shared(m) do { } while (0) +#define filemap_invalidate_unlock_shared(m) do { } while (0) +#define filemap_write_and_wait_range(m, s, e) ({ (void)(m); (void)(s); (void)(e); 0; }) +#define filemap_fdatawrite_range(m, s, e) ({ (void)(m); (void)(s); (void)(e); 0; }) +#define filemap_flush(m) ({ (void)(m); 0; }) +#define filemap_write_and_wait(m) ({ (void)(m); 0; }) +#define filemap_release_folio(folio, gfp) ({ (void)(folio); (void)(gfp); 1; }) +#define mapping_tagged(m, t) (0) +#define tag_pages_for_writeback(m, s, e) do { } while (0) +#define mapping_gfp_constraint(m, g) (g) +#define mapping_set_folio_order_range(m, l, h) do { } while (0) +#define filemap_splice_read(i, p, pi, l, f) ({ (void)(i); (void)(p); (void)(pi); (void)(l); (void)(f); 0L; }) +#define mapping_max_folio_order(m) ({ (void)(m); 0; }) + +/* Truncation stubs */ +#define truncate_pagecache(i, s) do { } while (0) +#define truncate_inode_pages(m, s) do { } while (0) +#define truncate_inode_pages_final(m) do { } while (0) +#define truncate_pagecache_range(i, s, e) do { } while (0) +#define truncate_inode_pages_range(m, s, e) do { (void)(m); (void)(s); (void)(e); } while (0) +#define pagecache_isize_extended(i, f, t) do { } while (0) +#define invalidate_mapping_pages(m, s, e) do { (void)(m); (void)(s); (void)(e); } while (0) + +/* Filemap fault handlers */ +static inline vm_fault_t filemap_fault(struct vm_fault *vmf) +{ + return 0; +} + +static inline vm_fault_t filemap_map_pages(struct vm_fault *vmf, + pgoff_t start, pgoff_t end) +{ + return 0; +} + +/* readahead_control stub */ +struct readahead_control { + struct address_space *mapping; + struct file *file; + unsigned long _index; + unsigned int _batch_count; +}; + +#define readahead_pos(rac) ({ (void)(rac); 0LL; }) +#define readahead_length(rac) ({ (void)(rac); 0UL; }) +#define readahead_count(rac) ({ (void)(rac); 0UL; }) +#define readahead_folio(rac) ({ (void)(rac); (struct folio *)NULL; }) +#define page_cache_sync_readahead(m, ra, f, i, n) do { } while (0) +#define ra_has_index(ra, idx) ({ (void)(ra); (void)(idx); 0; }) + +/* Stub implementations for address_space_operations callbacks */ +static inline bool block_is_partially_uptodate(struct folio *folio, + size_t from, size_t count) +{ + return false; +} + +static inline int generic_error_remove_folio(struct address_space *mapping, + struct folio *folio) +{ + return 0; +} + +/* writeback_iter stub */ +#define writeback_iter(mapping, wbc, folio, error) \ + ({ (void)(mapping); (void)(wbc); (void)(error); (struct folio *)NULL; }) + +#endif /* _LINUX_PAGEMAP_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> U-Boot does not have a real block I/O layer. The ext4l filesystem uses bio structures which are currently defined inline in ext4_uboot.h. Create a new linux/bio.h header file with stub implementations to better match the Linux kernel structure. Types and operations moved: - struct bio_vec - struct bvec_iter - struct bio - bio_sectors() - struct folio_iter - BIO_MAX_VECS - bio_for_each_folio_all() - bio_put() / bio_alloc() - submit_bio() - bio_add_folio() - blk_status_to_errno() - mapping_set_error() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 65 ++--------------------- include/linux/bio.h | 117 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 62 deletions(-) create mode 100644 include/linux/bio.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 40c68085c7a..b49e6604589 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1972,60 +1972,9 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, ({ (void)(bdev); 0U; }) /* - * Stubs for page-io.c + * Stubs for page-io.c - bio types are in linux/bio.h */ - -/* bio_vec - segment in a bio */ -struct bio_vec { - struct page *bv_page; - unsigned int bv_len; - unsigned int bv_offset; -}; - -/* bvec_iter - iterator for bio_vec */ -struct bvec_iter { - sector_t bi_sector; - unsigned int bi_size; - unsigned int bi_idx; - unsigned int bi_bvec_done; -}; - -/* bio - block I/O structure */ -struct bio { - struct bio *bi_next; - struct block_device *bi_bdev; - unsigned long bi_opf; - unsigned short bi_flags; - unsigned short bi_ioprio; - unsigned short bi_write_hint; - int bi_status; - struct bvec_iter bi_iter; - atomic_t __bi_remaining; - void *bi_private; - void (*bi_end_io)(struct bio *); -}; - -/* bio_sectors - return number of sectors in bio */ -static inline unsigned int bio_sectors(struct bio *bio) -{ - return bio->bi_iter.bi_size >> 9; -} - -/* folio_iter for bio iteration */ -struct folio_iter { - int i; - struct folio *folio; - size_t offset; - size_t length; -}; - -/* bio operations - stubs */ -#define bio_for_each_folio_all(fi, bio) \ - for ((fi).i = 0; (fi).i < 0; (fi).i++) -#define bio_put(bio) free(bio) -#define bio_alloc(bdev, vecs, op, gfp) ((struct bio *)calloc(1, sizeof(struct bio))) -#define submit_bio(bio) do { } while (0) -#define BIO_MAX_VECS 256 +#include <linux/bio.h> /* refcount operations - map to atomic */ #define refcount_set(r, v) atomic_set((atomic_t *)(r), v) @@ -2037,12 +1986,6 @@ struct folio_iter { /* printk_ratelimited is in linux/printk.h */ -/* mapping_set_error - record error in address_space */ -#define mapping_set_error(m, e) do { (void)(m); (void)(e); } while (0) - -/* blk_status_to_errno - convert block status to errno */ -#define blk_status_to_errno(status) (-(status)) - /* atomic_inc is in asm-generic/atomic.h */ /* GFP_NOIO is in linux/slab.h */ @@ -2059,9 +2002,7 @@ bool __folio_start_writeback(struct folio *folio, bool keep_write); #define wbc_account_cgroup_owner(wbc, folio, bytes) \ do { (void)(wbc); (void)(folio); (void)(bytes); } while (0) -/* bio operations */ -#define bio_add_folio(bio, folio, len, off) \ - ({ (void)(bio); (void)(folio); (void)(len); (void)(off); 1; }) +/* bio_add_folio is in linux/bio.h */ /* * Stubs for readpage.c diff --git a/include/linux/bio.h b/include/linux/bio.h new file mode 100644 index 00000000000..d8a955dba12 --- /dev/null +++ b/include/linux/bio.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Block I/O structures stub for U-Boot + * + * U-Boot doesn't have a real block I/O layer, so these are stubs. + */ +#ifndef __LINUX_BIO_H +#define __LINUX_BIO_H + +#include <linux/types.h> +#include <malloc.h> + +/* Forward declarations */ +struct block_device; +struct page; +struct folio; + +/** + * struct bio_vec - segment in a bio + * @bv_page: page containing the data + * @bv_len: length of the segment + * @bv_offset: offset within the page + */ +struct bio_vec { + struct page *bv_page; + unsigned int bv_len; + unsigned int bv_offset; +}; + +/** + * struct bvec_iter - iterator for bio_vec + * @bi_sector: current sector + * @bi_size: remaining size + * @bi_idx: current index into bio_vec array + * @bi_bvec_done: bytes completed in current bvec + */ +struct bvec_iter { + sector_t bi_sector; + unsigned int bi_size; + unsigned int bi_idx; + unsigned int bi_bvec_done; +}; + +/** + * struct bio - block I/O structure + * @bi_next: next bio in chain + * @bi_bdev: target block device + * @bi_opf: operation and flags + * @bi_flags: bio flags + * @bi_ioprio: I/O priority + * @bi_write_hint: write lifetime hint + * @bi_status: completion status + * @bi_iter: current position iterator + * @__bi_remaining: remaining count for chained bios + * @bi_private: private data for completion + * @bi_end_io: completion callback + * + * U-Boot stub. + */ +struct bio { + struct bio *bi_next; + struct block_device *bi_bdev; + unsigned long bi_opf; + unsigned short bi_flags; + unsigned short bi_ioprio; + unsigned short bi_write_hint; + int bi_status; + struct bvec_iter bi_iter; + atomic_t __bi_remaining; + void *bi_private; + void (*bi_end_io)(struct bio *); +}; + +/** + * bio_sectors() - return number of sectors in bio + * @bio: bio to query + * + * Return: number of 512-byte sectors + */ +static inline unsigned int bio_sectors(struct bio *bio) +{ + return bio->bi_iter.bi_size >> 9; +} + +/** + * struct folio_iter - iterator for folio iteration over bio + * @i: current index + * @folio: current folio + * @offset: offset within folio + * @length: length of current segment + */ +struct folio_iter { + int i; + struct folio *folio; + size_t offset; + size_t length; +}; + +/* Maximum number of bio_vecs */ +#define BIO_MAX_VECS 256 + +/* bio operations - stubs */ +#define bio_for_each_folio_all(fi, bio) \ + for ((fi).i = 0; (fi).i < 0; (fi).i++) +#define bio_put(bio) free(bio) +#define bio_alloc(bdev, vecs, op, gfp) ((struct bio *)calloc(1, sizeof(struct bio))) +#define submit_bio(bio) do { } while (0) +#define bio_add_folio(bio, folio, len, off) \ + ({ (void)(bio); (void)(folio); (void)(len); (void)(off); 1; }) + +/* blk_status_to_errno - convert block status to errno */ +#define blk_status_to_errno(status) (-(status)) + +/* mapping_set_error - record error in address_space */ +#define mapping_set_error(m, e) do { (void)(m); (void)(e); } while (0) + +#endif /* __LINUX_BIO_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move filesystem context and parameter parsing stubs to dedicated header files that mirror the Linux kernel organisation. fs_context.h provides: - enum fs_context_purpose - struct fs_context_operations - struct file_system_type with FS_* flags - struct fs_context - struct fs_parameter - get_tree_bdev(), get_tree_nodev(), kill_block_super() stubs fs_parser.h provides: - struct constant_table - struct fs_parameter_spec with fs_param_is_* constants - struct fs_parse_result - fsparam_*() macros for mount option specification - fs_parse() and fs_lookup_param() stubs These are stubs for U-Boot since filesystem mounting is simpler than in the Linux kernel, but they allow ext4l code to compile. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 150 +----------------------------------- include/linux/fs_context.h | 154 +++++++++++++++++++++++++++++++++++++ include/linux/fs_parser.h | 110 ++++++++++++++++++++++++++ 3 files changed, 266 insertions(+), 148 deletions(-) create mode 100644 include/linux/fs_context.h create mode 100644 include/linux/fs_parser.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index b49e6604589..a1047607e79 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -84,6 +84,8 @@ #include <linux/jiffies.h> #include <linux/blkdev.h> #include <linux/blk_types.h> +#include <linux/fs_context.h> +#include <linux/fs_parser.h> /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */ @@ -1302,88 +1304,11 @@ static inline const char *simple_get_link(struct dentry *dentry, * Additional stubs for super.c */ -/* fs_context and fs_parser stubs */ -struct constant_table { - const char *name; - int value; -}; - -struct fs_parameter_spec { - const char *name; - int opt; - unsigned short type; - const struct constant_table *data; -}; - -/* fs_parameter spec types */ -#define fs_param_is_flag 0 -#define fs_param_is_u32 1 -#define fs_param_is_s32 2 -#define fs_param_is_u64 3 -#define fs_param_is_enum 4 -#define fs_param_is_string 5 -#define fs_param_is_blob 6 -#define fs_param_is_fd 7 -#define fs_param_is_uid 8 -#define fs_param_is_gid 9 -#define fs_param_is_blockdev 10 - -/* fsparam_* macros for mount option parsing - use literal values */ -#define fsparam_flag(name, opt) \ - {(name), (opt), 0, NULL} -#define fsparam_u32(name, opt) \ - {(name), (opt), 1, NULL} -#define fsparam_s32(name, opt) \ - {(name), (opt), 2, NULL} -#define fsparam_u64(name, opt) \ - {(name), (opt), 3, NULL} -#define fsparam_string(name, opt) \ - {(name), (opt), 5, NULL} -#define fsparam_string_empty(name, opt) \ - {(name), (opt), 5, NULL} -#define fsparam_enum(name, opt, array) \ - {(name), (opt), 4, (array)} -#define fsparam_bdev(name, opt) \ - {(name), (opt), 10, NULL} -#define fsparam_uid(name, opt) \ - {(name), (opt), 8, NULL} -#define fsparam_gid(name, opt) \ - {(name), (opt), 9, NULL} -#define __fsparam(type, name, opt, flags, data) \ - {(name), (opt), (type), (data)} - /* Quota format constants */ #define QFMT_VFS_OLD 1 #define QFMT_VFS_V0 2 #define QFMT_VFS_V1 4 -struct fs_context; -struct fs_parameter; - -struct fs_context_operations { - int (*parse_param)(struct fs_context *, struct fs_parameter *); - int (*get_tree)(struct fs_context *); - int (*reconfigure)(struct fs_context *); - void (*free)(struct fs_context *); -}; - -struct file_system_type { - struct module *owner; - const char *name; - int (*init_fs_context)(struct fs_context *); - const struct fs_parameter_spec *parameters; - void (*kill_sb)(struct super_block *); - int fs_flags; - struct list_head fs_supers; -}; - -#define FS_REQUIRES_DEV 1 -#define FS_BINARY_MOUNTDATA 2 -#define FS_HAS_SUBTYPE 4 -#define FS_USERNS_MOUNT 8 -#define FS_DISALLOW_NOTIFY_PERM 16 -#define FS_ALLOW_IDMAP 32 - /* Buffer read sync */ static inline void end_buffer_read_sync(struct buffer_head *bh, int uptodate) { @@ -1510,82 +1435,11 @@ struct kstatfs { #define EXT4_GOING_FLAGS_LOGFLUSH 1 #define EXT4_GOING_FLAGS_NOLOGFLUSH 2 -/* fs_context stubs */ -/* fs_context_purpose - what the context is for */ -enum fs_context_purpose { - FS_CONTEXT_FOR_MOUNT, - FS_CONTEXT_FOR_SUBMOUNT, - FS_CONTEXT_FOR_RECONFIGURE, -}; - -struct fs_context { - const struct fs_context_operations *ops; - struct file_system_type *fs_type; - void *fs_private; - struct dentry *root; - struct user_namespace *user_ns; - void *s_fs_info; /* Filesystem specific info */ - unsigned int sb_flags; - unsigned int sb_flags_mask; - unsigned int lsm_flags; - enum fs_context_purpose purpose; - bool sloppy; - bool silent; -}; - /* ext4 superblock initialisation and commit */ int ext4_fill_super(struct super_block *sb, struct fs_context *fc); int ext4_commit_super(struct super_block *sb); void ext4_unregister_li_request(struct super_block *sb); -/* fs_parameter stubs */ -struct fs_parameter { - const char *key; - int type; - size_t size; - int dirfd; - union { - char *string; - int boolean; - int integer; - }; -}; - -/* fs_value types - result type from parsing */ -enum fs_value_type { - fs_value_is_undefined, - fs_value_is_flag, - fs_value_is_string, - fs_value_is_blob, - fs_value_is_filename, - fs_value_is_file, -}; - -/* fs_parse_result - result of parsing a parameter */ -struct fs_parse_result { - bool negated; - union { - bool boolean; - int int_32; - unsigned int uint_32; - u64 uint_64; - kuid_t uid; - kgid_t gid; - }; -}; - -/* fs_parse stubs */ -#define fs_parse(fc, desc, param, result) ({ (void)(fc); (void)(desc); (void)(param); (void)(result); -ENOPARAM; }) -#define ENOPARAM 519 -#define fs_lookup_param(fc, p, bdev, fl, path) ({ (void)(fc); (void)(p); (void)(bdev); (void)(fl); (void)(path); -EINVAL; }) - -/* get_tree helpers */ -#define get_tree_bdev(fc, fill_super) ({ (void)(fc); (void)(fill_super); -ENODEV; }) -#define get_tree_nodev(fc, fill_super) ({ (void)(fc); (void)(fill_super); -ENODEV; }) - -/* kill_sb helpers */ -#define kill_block_super(sb) do { } while (0) - /* prandom */ #define get_random_u32() 0 #define prandom_u32_max(max) 0 diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h new file mode 100644 index 00000000000..66cb462c656 --- /dev/null +++ b/include/linux/fs_context.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Filesystem context stubs for U-Boot + * + * Based on Linux fs_context.h - U-Boot doesn't have real mount contexts, + * so these are stubs for compilation. + */ +#ifndef _LINUX_FS_CONTEXT_H +#define _LINUX_FS_CONTEXT_H + +#include <linux/types.h> +#include <linux/list.h> + +/* Forward declarations */ +struct dentry; +struct fs_parameter; +struct module; +struct super_block; +struct user_namespace; + +/** + * enum fs_context_purpose - what the context is for + * @FS_CONTEXT_FOR_MOUNT: New superblock for explicit mount + * @FS_CONTEXT_FOR_SUBMOUNT: New superblock for automatic submount + * @FS_CONTEXT_FOR_RECONFIGURE: Superblock reconfiguration (remount) + */ +enum fs_context_purpose { + FS_CONTEXT_FOR_MOUNT, + FS_CONTEXT_FOR_SUBMOUNT, + FS_CONTEXT_FOR_RECONFIGURE, +}; + +/** + * enum fs_value_type - type of parameter value + * @fs_value_is_undefined: Value not specified + * @fs_value_is_flag: Value not given a value + * @fs_value_is_string: Value is a string + * @fs_value_is_blob: Value is a binary blob + * @fs_value_is_filename: Value is a filename + dirfd + * @fs_value_is_file: Value is a file pointer + */ +enum fs_value_type { + fs_value_is_undefined, + fs_value_is_flag, + fs_value_is_string, + fs_value_is_blob, + fs_value_is_filename, + fs_value_is_file, +}; + +struct fs_context; + +/** + * struct fs_context_operations - filesystem context operations + * @parse_param: parse a single parameter + * @get_tree: get the superblock + * @reconfigure: reconfigure the superblock + * @free: free the context + */ +struct fs_context_operations { + int (*parse_param)(struct fs_context *, struct fs_parameter *); + int (*get_tree)(struct fs_context *); + int (*reconfigure)(struct fs_context *); + void (*free)(struct fs_context *); +}; + +/** + * struct file_system_type - filesystem type descriptor + * @owner: module owner + * @name: filesystem name + * @init_fs_context: initialise a filesystem context + * @parameters: mount parameter specification + * @kill_sb: destroy a superblock + * @fs_flags: filesystem flags + * @fs_supers: list of superblocks of this type + */ +struct file_system_type { + struct module *owner; + const char *name; + int (*init_fs_context)(struct fs_context *); + const struct fs_parameter_spec *parameters; + void (*kill_sb)(struct super_block *); + int fs_flags; + struct list_head fs_supers; +}; + +/* Filesystem type flags */ +#define FS_REQUIRES_DEV 1 +#define FS_BINARY_MOUNTDATA 2 +#define FS_HAS_SUBTYPE 4 +#define FS_USERNS_MOUNT 8 +#define FS_DISALLOW_NOTIFY_PERM 16 +#define FS_ALLOW_IDMAP 32 + +/** + * struct fs_context - filesystem context for mount/reconfigure + * @ops: operations for this context + * @fs_type: filesystem type + * @fs_private: filesystem private data + * @root: root dentry (for reconfigure) + * @user_ns: user namespace for this mount + * @s_fs_info: proposed s_fs_info + * @sb_flags: proposed superblock flags + * @sb_flags_mask: superblock flags that changed + * @lsm_flags: LSM flags + * @purpose: what this context is for + * @sloppy: permit unrecognised options + * @silent: suppress mount errors + */ +struct fs_context { + const struct fs_context_operations *ops; + struct file_system_type *fs_type; + void *fs_private; + struct dentry *root; + struct user_namespace *user_ns; + void *s_fs_info; + unsigned int sb_flags; + unsigned int sb_flags_mask; + unsigned int lsm_flags; + enum fs_context_purpose purpose; + bool sloppy; + bool silent; +}; + +/** + * struct fs_parameter - filesystem mount parameter + * @key: parameter name + * @type: value type + * @size: size of value + * @dirfd: directory fd for filename values + * @string: string value + * @boolean: boolean value + * @integer: integer value + */ +struct fs_parameter { + const char *key; + int type; + size_t size; + int dirfd; + union { + char *string; + int boolean; + int integer; + }; +}; + +/* get_tree helpers - stubs */ +#define get_tree_bdev(fc, fill_super) ({ (void)(fc); (void)(fill_super); -ENODEV; }) +#define get_tree_nodev(fc, fill_super) ({ (void)(fc); (void)(fill_super); -ENODEV; }) + +/* kill_sb helpers - stubs */ +#define kill_block_super(sb) do { } while (0) + +#endif /* _LINUX_FS_CONTEXT_H */ diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h new file mode 100644 index 00000000000..b3f1014fb98 --- /dev/null +++ b/include/linux/fs_parser.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Filesystem parameter parser stubs for U-Boot + * + * Based on Linux fs_parser.h - U-Boot doesn't have real mount option + * parsing, so these are stubs for compilation. + */ +#ifndef _LINUX_FS_PARSER_H +#define _LINUX_FS_PARSER_H + +#include <linux/fs_context.h> + +/** + * struct constant_table - table of named constants + * @name: constant name + * @value: constant value + */ +struct constant_table { + const char *name; + int value; +}; + +/** + * struct fs_parameter_spec - mount parameter specification + * @name: parameter name + * @opt: option number returned by fs_parse() + * @type: parameter type (fs_param_is_* constants) + * @data: type-specific data (e.g., enum table) + */ +struct fs_parameter_spec { + const char *name; + int opt; + unsigned short type; + const struct constant_table *data; +}; + +/* fs_parameter spec types - simplified numeric types for U-Boot */ +#define fs_param_is_flag 0 +#define fs_param_is_u32 1 +#define fs_param_is_s32 2 +#define fs_param_is_u64 3 +#define fs_param_is_enum 4 +#define fs_param_is_string 5 +#define fs_param_is_blob 6 +#define fs_param_is_fd 7 +#define fs_param_is_uid 8 +#define fs_param_is_gid 9 +#define fs_param_is_blockdev 10 + +/** + * struct fs_parse_result - result of parsing a parameter + * @negated: true if param was "noxxx" + * @boolean: boolean result + * @int_32: 32-bit signed integer result + * @uint_32: 32-bit unsigned integer result + * @uint_64: 64-bit unsigned integer result + * @uid: UID result + * @gid: GID result + */ +struct fs_parse_result { + bool negated; + union { + bool boolean; + int int_32; + unsigned int uint_32; + u64 uint_64; + kuid_t uid; + kgid_t gid; + }; +}; + +/* + * fsparam_* macros for mount option parsing - use literal type values + * These macros build fs_parameter_spec entries. + */ +#define fsparam_flag(name, opt) \ + {(name), (opt), 0, NULL} +#define fsparam_u32(name, opt) \ + {(name), (opt), 1, NULL} +#define fsparam_s32(name, opt) \ + {(name), (opt), 2, NULL} +#define fsparam_u64(name, opt) \ + {(name), (opt), 3, NULL} +#define fsparam_string(name, opt) \ + {(name), (opt), 5, NULL} +#define fsparam_string_empty(name, opt) \ + {(name), (opt), 5, NULL} +#define fsparam_enum(name, opt, array) \ + {(name), (opt), 4, (array)} +#define fsparam_bdev(name, opt) \ + {(name), (opt), 10, NULL} +#define fsparam_uid(name, opt) \ + {(name), (opt), 8, NULL} +#define fsparam_gid(name, opt) \ + {(name), (opt), 9, NULL} +#define __fsparam(type, name, opt, flags, data) \ + {(name), (opt), (type), (data)} + +/* ENOPARAM - parameter not found */ +#define ENOPARAM 519 + +/* fs_parse - parse a mount option - stub */ +#define fs_parse(fc, desc, param, result) \ + ({ (void)(fc); (void)(desc); (void)(param); (void)(result); -ENOPARAM; }) + +/* fs_lookup_param - lookup parameter path - stub */ +#define fs_lookup_param(fc, p, bdev, fl, path) \ + ({ (void)(fc); (void)(p); (void)(bdev); (void)(fl); (void)(path); -EINVAL; }) + +#endif /* _LINUX_FS_PARSER_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move dentry and directory cache stubs to a dedicated header file that mirrors the Linux kernel organisation. dcache.h provides: - struct qstr and QSTR_INIT() for quick strings - dotdot_name constant for ".." lookups - struct dentry with minimal fields for ext4l - struct name_snapshot for dentry name snapshots - d_inode() accessor - Dentry operation stubs: d_find_any_alias(), dget_parent(), dput(), d_splice_alias(), d_obtain_alias(), d_instantiate_new(), d_instantiate(), d_tmpfile(), d_invalidate(), d_alloc(), d_drop() - Name snapshot operations: take_dentry_name_snapshot(), release_dentry_name_snapshot() - Declarations for generic_set_sb_d_ops() and d_make_root() Also update ext4_fscrypt.h to include dcache.h instead of defining its own struct qstr, avoiding duplication. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_fscrypt.h | 9 +--- fs/ext4l/ext4_uboot.h | 47 ++++----------------- include/linux/dcache.h | 94 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 47 deletions(-) create mode 100644 include/linux/dcache.h diff --git a/fs/ext4l/ext4_fscrypt.h b/fs/ext4l/ext4_fscrypt.h index da91af74343..91f08229e32 100644 --- a/fs/ext4l/ext4_fscrypt.h +++ b/fs/ext4l/ext4_fscrypt.h @@ -13,6 +13,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/string.h> +#include <linux/dcache.h> /* Forward declarations */ struct inode; @@ -21,16 +22,8 @@ struct page; struct folio; struct bio; struct buffer_head; -struct dentry; struct super_block; -/* qstr - quick string for filenames (needed by fscrypt_name) */ -struct qstr { - u32 hash; - u32 len; - const unsigned char *name; -}; - /* fscrypt_str - encrypted filename string */ struct fscrypt_str { unsigned char *name; diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index a1047607e79..9423c92169e 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -86,6 +86,7 @@ #include <linux/blk_types.h> #include <linux/fs_context.h> #include <linux/fs_parser.h> +#include <linux/dcache.h> /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */ @@ -300,8 +301,7 @@ struct buffer_head *sb_getblk(struct super_block *sb, sector_t block); /* icount - inode reference count */ #define icount_read(inode) (1) -/* d_inode - get inode from dentry */ -#define d_inode(dentry) ((dentry) ? (dentry)->d_inode : NULL) +/* d_inode is now in linux/dcache.h */ /* Random number functions */ #define get_random_u32_below(max) (0) @@ -444,18 +444,7 @@ struct ratelimit_state { /* IS_NOQUOTA - stub */ #define IS_NOQUOTA(inode) (0) -/* dentry - stub */ -struct dentry { - struct qstr d_name; - struct inode *d_inode; - struct super_block *d_sb; - struct dentry *d_parent; -}; - -/* name_snapshot - for dentry name snapshots */ -struct name_snapshot { - struct qstr name; -}; +/* dentry, name_snapshot are now in linux/dcache.h */ /* VM types - use linux/mm_types.h */ #include <linux/mm_types.h> @@ -758,10 +747,7 @@ static inline void inode_state_assign(struct inode *inode, unsigned long flags) inode->i_state = flags; } -#define QSTR_INIT(n, l) { .name = (const unsigned char *)(n), .len = (l) } - -/* dotdot_name for ".." lookups */ -static const struct qstr dotdot_name = QSTR_INIT("..", 2); +/* QSTR_INIT and dotdot_name are now in linux/dcache.h */ /* * Hash info structure - defined in ext4.h. @@ -999,16 +985,7 @@ typedef unsigned int projid_t; /* hash_64 - simple 64-bit hash */ #define hash_64(val, bits) ((unsigned long)((val) >> (64 - (bits)))) -/* Dentry operations - stubs */ -#define d_find_any_alias(i) ({ (void)(i); (struct dentry *)NULL; }) -#define dget_parent(d) ({ (void)(d); (struct dentry *)NULL; }) -#define dput(d) do { (void)(d); } while (0) -#define d_splice_alias(i, d) ({ (d)->d_inode = (i); (d); }) -#define d_obtain_alias(i) ({ (void)(i); (struct dentry *)NULL; }) -#define d_instantiate_new(d, i) ((void)((d)->d_inode = (i))) -#define d_instantiate(d, i) ((void)((d)->d_inode = (i))) -#define d_tmpfile(f, i) do { (void)(f); (void)(i); } while (0) -#define d_invalidate(d) do { (void)(d); } while (0) +/* Dentry operations are now in linux/dcache.h */ #define finish_open_simple(f, e) (e) #define ihold(i) do { (void)(i); } while (0) @@ -1678,9 +1655,7 @@ struct mb_cache_entry { #define PF_MEMALLOC_NOFS 0x00040000 #endif -/* Dentry operations - declarations for stub.c */ -void generic_set_sb_d_ops(struct super_block *sb); -struct dentry *d_make_root(struct inode *inode); +/* generic_set_sb_d_ops, d_make_root are now in linux/dcache.h */ /* strreplace is in linux/string.h */ @@ -1909,11 +1884,7 @@ struct wait_bit_entry { #define finish_wait(wq, wait) \ do { (void)(wq); (void)(wait); } while (0) -/* Dentry name snapshot operations */ -#define take_dentry_name_snapshot(snap, dentry) \ - do { (snap)->name = (dentry)->d_name; } while (0) -#define release_dentry_name_snapshot(snap) \ - do { (void)(snap); } while (0) +/* Dentry name snapshot operations are now in linux/dcache.h */ /* lockdep_assert_not_held is in linux/lockdep.h */ @@ -1924,9 +1895,7 @@ struct wait_bit_entry { /* wake_up_bit - wake up threads waiting on a bit */ #define wake_up_bit(word, bit) do { (void)(word); (void)(bit); } while (0) -/* Dentry allocation stubs */ -#define d_alloc(parent, name) ({ (void)(parent); (void)(name); (struct dentry *)NULL; }) -#define d_drop(dentry) do { (void)(dentry); } while (0) +/* d_alloc, d_drop are now in linux/dcache.h */ /* get_current_ioprio - I/O priority (not used in U-Boot) */ #define get_current_ioprio() (0) diff --git a/include/linux/dcache.h b/include/linux/dcache.h new file mode 100644 index 00000000000..bf8d1e4755e --- /dev/null +++ b/include/linux/dcache.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Dentry cache stubs for U-Boot + * + * Based on Linux dcache.h - U-Boot doesn't have a real dentry cache, + * so these are stubs for compilation. + */ +#ifndef _LINUX_DCACHE_H +#define _LINUX_DCACHE_H + +#include <linux/types.h> +#include <linux/list.h> + +/* Forward declarations */ +struct inode; +struct super_block; + +/** + * struct qstr - quick string for filenames + * @hash: filename hash + * @len: filename length + * @name: filename + * + * Note: Also defined in ext4_fscrypt.h for fscrypt support. + */ +struct qstr { + u32 hash; + u32 len; + const unsigned char *name; +}; + +/** + * QSTR_INIT - initialise a qstr + * @n: name string + * @l: length + */ +#define QSTR_INIT(n, l) { .name = (const unsigned char *)(n), .len = (l) } + +/* dotdot_name for ".." lookups */ +static const struct qstr dotdot_name = QSTR_INIT("..", 2); + +/** + * struct dentry - directory entry + * @d_name: filename + * @d_inode: associated inode + * @d_sb: superblock + * @d_parent: parent directory + * + * U-Boot stub - minimal fields for ext4l. + */ +struct dentry { + struct qstr d_name; + struct inode *d_inode; + struct super_block *d_sb; + struct dentry *d_parent; +}; + +/** + * struct name_snapshot - dentry name snapshot + * @name: snapshot of the name + * + * Used for safe name access during operations. + */ +struct name_snapshot { + struct qstr name; +}; + +/* d_inode - get inode from dentry */ +#define d_inode(dentry) ((dentry) ? (dentry)->d_inode : NULL) + +/* Dentry operations - stubs */ +#define d_find_any_alias(i) ({ (void)(i); (struct dentry *)NULL; }) +#define dget_parent(d) ({ (void)(d); (struct dentry *)NULL; }) +#define dput(d) do { (void)(d); } while (0) +#define d_splice_alias(i, d) ({ (d)->d_inode = (i); (d); }) +#define d_obtain_alias(i) ({ (void)(i); (struct dentry *)NULL; }) +#define d_instantiate_new(d, i) ((void)((d)->d_inode = (i))) +#define d_instantiate(d, i) ((void)((d)->d_inode = (i))) +#define d_tmpfile(f, i) do { (void)(f); (void)(i); } while (0) +#define d_invalidate(d) do { (void)(d); } while (0) +#define d_alloc(parent, name) ({ (void)(parent); (void)(name); (struct dentry *)NULL; }) +#define d_drop(dentry) do { (void)(dentry); } while (0) + +/* Name snapshot operations */ +#define take_dentry_name_snapshot(sn, d) \ + do { (sn)->name = (d)->d_name; } while (0) +#define release_dentry_name_snapshot(sn) \ + do { (void)(sn); } while (0) + +/* Dentry operations - declarations for stub.c */ +void generic_set_sb_d_ops(struct super_block *sb); +struct dentry *d_make_root(struct inode *inode); + +#endif /* _LINUX_DCACHE_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move UUID and GUID type definitions to a dedicated header file that mirrors the Linux kernel organisation. uuid.h provides: - uuid_t type for big-endian UUIDs - guid_t type for little-endian GUIDs - UUID_SIZE and UUID_STRING_LEN constants - GUID_INIT() and UUID_INIT() macros - Comparison functions: guid_equal(), uuid_equal() - Copy functions: guid_copy(), uuid_copy() - Import/export: import_uuid(), export_uuid() These types are used by ext4l for filesystem UUID handling. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 6 +-- include/linux/uuid.h | 120 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 include/linux/uuid.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 9423c92169e..3ce94750fcf 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -87,6 +87,7 @@ #include <linux/fs_context.h> #include <linux/fs_parser.h> #include <linux/dcache.h> +#include <linux/uuid.h> /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */ @@ -490,10 +491,7 @@ struct fstrim_range { /* SB_RDONLY, SB_I_VERSION, etc. superblock flags are in linux/fs.h */ -/* UUID type */ -typedef struct { - __u8 b[16]; -} uuid_t; +/* uuid_t is now in linux/uuid.h */ /* Forward declarations for super_block */ struct super_operations; diff --git a/include/linux/uuid.h b/include/linux/uuid.h new file mode 100644 index 00000000000..810cf1d735d --- /dev/null +++ b/include/linux/uuid.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * UUID/GUID definitions for U-Boot + * + * Based on Linux uuid.h + */ +#ifndef _LINUX_UUID_H_ +#define _LINUX_UUID_H_ + +#include <linux/types.h> +#include <linux/string.h> + +#define UUID_SIZE 16 + +/** + * typedef guid_t - GUID type (little-endian) + * + * GUIDs are stored in little-endian byte order. + */ +typedef struct { + __u8 b[UUID_SIZE]; +} guid_t; + +/** + * typedef uuid_t - UUID type (big-endian / network order) + * + * UUIDs are stored in big-endian byte order. + */ +typedef struct { + __u8 b[UUID_SIZE]; +} uuid_t; + +/** + * GUID_INIT - initialise a GUID (little-endian) + */ +#define GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ +((guid_t) \ +{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) + +/** + * UUID_INIT - initialise a UUID (big-endian) + */ +#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ +((uuid_t) \ +{{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \ + ((b) >> 8) & 0xff, (b) & 0xff, \ + ((c) >> 8) & 0xff, (c) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) + +/* Length of UUID string without NUL */ +#define UUID_STRING_LEN 36 + +/** + * guid_equal - compare two GUIDs + * @u1: first GUID + * @u2: second GUID + * + * Return: true if equal, false otherwise + */ +static inline bool guid_equal(const guid_t *u1, const guid_t *u2) +{ + return memcmp(u1, u2, sizeof(guid_t)) == 0; +} + +/** + * guid_copy - copy a GUID + * @dst: destination + * @src: source + */ +static inline void guid_copy(guid_t *dst, const guid_t *src) +{ + memcpy(dst, src, sizeof(guid_t)); +} + +/** + * uuid_equal - compare two UUIDs + * @u1: first UUID + * @u2: second UUID + * + * Return: true if equal, false otherwise + */ +static inline bool uuid_equal(const uuid_t *u1, const uuid_t *u2) +{ + return memcmp(u1, u2, sizeof(uuid_t)) == 0; +} + +/** + * uuid_copy - copy a UUID + * @dst: destination + * @src: source + */ +static inline void uuid_copy(uuid_t *dst, const uuid_t *src) +{ + memcpy(dst, src, sizeof(uuid_t)); +} + +/** + * import_uuid - import a UUID from raw bytes + * @dst: destination UUID + * @src: source bytes + */ +static inline void import_uuid(uuid_t *dst, const __u8 *src) +{ + memcpy(dst, src, sizeof(uuid_t)); +} + +/** + * export_uuid - export a UUID to raw bytes + * @dst: destination bytes + * @src: source UUID + */ +static inline void export_uuid(__u8 *dst, const uuid_t *src) +{ + memcpy(dst, src, sizeof(uuid_t)); +} + +#endif /* _LINUX_UUID_H_ */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the cmpxchg (compare and exchange) macro to the asm-generic atomic header where it belongs alongside other atomic operations. This is a single-threaded implementation for U-Boot that atomically compares *ptr with old and if equal, stores new. Returns the original value of *ptr. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 10 +--------- include/asm-generic/atomic.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 3ce94750fcf..f26006f9291 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -94,15 +94,7 @@ /* 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)) __cmpxchg_old = (old); \ - typeof(*(ptr)) __cmpxchg_new = (new); \ - typeof(*(ptr)) __cmpxchg_ret = *(ptr); \ - if (__cmpxchg_ret == __cmpxchg_old) \ - *(ptr) = __cmpxchg_new; \ - __cmpxchg_ret; \ -}) +/* cmpxchg is now in asm-generic/atomic.h */ /* Reference count type */ typedef struct { atomic_t refs; } refcount_t; diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 7825258922a..3fa749bf012 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -200,4 +200,22 @@ static inline void atomic64_dec(volatile atomic64_t *v) local_irq_restore(flags); } +/** + * cmpxchg - compare and exchange + * @ptr: pointer to the value + * @old: expected old value + * @new: new value to store if current equals old + * + * Single-threaded version for U-Boot. Atomically compares *ptr with old + * and if equal, stores new. Returns the original value of *ptr. + */ +#define cmpxchg(ptr, old, new) ({ \ + typeof(*(ptr)) __cmpxchg_old = (old); \ + typeof(*(ptr)) __cmpxchg_new = (new); \ + typeof(*(ptr)) __cmpxchg_ret = *(ptr); \ + if (__cmpxchg_ret == __cmpxchg_old) \ + *(ptr) = __cmpxchg_new; \ + __cmpxchg_ret; \ +}) + #endif -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move SMP-related stubs to a dedicated header file that mirrors the Linux kernel organisation. smp.h provides: - raw_smp_processor_id() and smp_processor_id() - always return 0 - smp_rmb(), smp_wmb(), smp_mb() - memory barriers (no-ops) - smp_mb__after_atomic() - post-atomic memory barrier (no-op) These are all stubs since U-Boot is single-threaded. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 13 +++------- include/linux/smp.h | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 include/linux/smp.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index f26006f9291..57d967965da 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -88,13 +88,11 @@ #include <linux/fs_parser.h> #include <linux/dcache.h> #include <linux/uuid.h> +#include <linux/smp.h> /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */ - -/* SMP stubs - U-Boot is single-threaded */ -#define raw_smp_processor_id() 0 - /* cmpxchg is now in asm-generic/atomic.h */ +/* SMP stubs (raw_smp_processor_id, smp_*mb) are now in linux/smp.h */ /* Reference count type */ typedef struct { atomic_t refs; } refcount_t; @@ -255,10 +253,7 @@ struct buffer_head *sb_getblk(struct super_block *sb, sector_t block); /* inode_needs_sync - stub */ #define inode_needs_sync(inode) (0) -/* Memory barriers - stubs for single-threaded */ -#define smp_rmb() do { } while (0) -#define smp_wmb() do { } while (0) -#define smp_mb() do { } while (0) +/* Memory barriers are now in linux/smp.h */ /* * set_bit/clear_bit are declared extern in asm/bitops.h but not implemented. @@ -1897,7 +1892,7 @@ struct wait_bit_entry { /* JBD2 commit.c stubs (folio_trylock is in linux/pagemap.h) */ #define clear_bit_unlock(nr, addr) clear_bit(nr, addr) -#define smp_mb__after_atomic() do { } while (0) +/* smp_mb__after_atomic is now in linux/smp.h */ #define ktime_get_coarse_real_ts64(ts) do { (ts)->tv_sec = 0; (ts)->tv_nsec = 0; } while (0) #define filemap_fdatawait_range_keep_errors(m, s, e) \ ({ (void)(m); (void)(s); (void)(e); 0; }) diff --git a/include/linux/smp.h b/include/linux/smp.h new file mode 100644 index 00000000000..15fb7fa656f --- /dev/null +++ b/include/linux/smp.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * SMP stubs for U-Boot + * + * U-Boot is single-threaded, so all SMP operations are stubs. + */ +#ifndef _LINUX_SMP_H +#define _LINUX_SMP_H + +#include <linux/types.h> + +/** + * raw_smp_processor_id() - get current processor ID + * + * U-Boot stub - always returns 0 (single CPU). + */ +#define raw_smp_processor_id() 0 + +/** + * smp_processor_id() - get current processor ID + * + * U-Boot stub - always returns 0 (single CPU). + */ +#define smp_processor_id() 0 + +/* Memory barriers - stubs for single-threaded U-Boot */ + +/** + * smp_rmb() - read memory barrier + * + * Ensures that all reads before this point are completed before + * any reads after this point. No-op in single-threaded U-Boot. + */ +#define smp_rmb() do { } while (0) + +/** + * smp_wmb() - write memory barrier + * + * Ensures that all writes before this point are completed before + * any writes after this point. No-op in single-threaded U-Boot. + */ +#define smp_wmb() do { } while (0) + +/** + * smp_mb() - full memory barrier + * + * Ensures that all memory operations before this point are completed + * before any memory operations after this point. No-op in single-threaded + * U-Boot. + */ +#define smp_mb() do { } while (0) + +/** + * smp_mb__after_atomic() - memory barrier after atomic operation + * + * No-op in single-threaded U-Boot. + */ +#define smp_mb__after_atomic() do { } while (0) + +#endif /* _LINUX_SMP_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move reference count type and operations to a dedicated header file that mirrors the Linux kernel organisation. refcount.h provides: - refcount_t type (wrapper around atomic_t) - REFCOUNT_INIT() macro for static initialisation - refcount_set(), refcount_read() - set/get value - refcount_inc(), refcount_dec() - increment/decrement - refcount_dec_and_test() - decrement and test if zero - refcount_inc_not_zero() - increment unless zero These are simplified versions for single-threaded U-Boot, mapping directly to atomic_t operations. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 10 ++---- include/linux/refcount.h | 70 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 include/linux/refcount.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 57d967965da..4fe7d40c37f 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -89,13 +89,12 @@ #include <linux/dcache.h> #include <linux/uuid.h> #include <linux/smp.h> +#include <linux/refcount.h> /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */ /* cmpxchg is now in asm-generic/atomic.h */ /* SMP stubs (raw_smp_processor_id, smp_*mb) are now in linux/smp.h */ - -/* Reference count type */ -typedef struct { atomic_t refs; } refcount_t; +/* refcount_t and operations are now in linux/refcount.h */ /* rwlock_t and read_lock/read_unlock are now in linux/spinlock.h */ #include <linux/spinlock.h> @@ -1790,10 +1789,7 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, */ #include <linux/bio.h> -/* refcount operations - map to atomic */ -#define refcount_set(r, v) atomic_set((atomic_t *)(r), v) -#define refcount_dec_and_test(r) atomic_dec_and_test((atomic_t *)(r)) -#define refcount_inc(r) atomic_inc((atomic_t *)(r)) +/* refcount operations are now in linux/refcount.h */ /* xchg - exchange value atomically */ #define xchg(ptr, new) ({ typeof(*(ptr)) __old = *(ptr); *(ptr) = (new); __old; }) diff --git a/include/linux/refcount.h b/include/linux/refcount.h new file mode 100644 index 00000000000..ce001b437bf --- /dev/null +++ b/include/linux/refcount.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Reference count type stubs for U-Boot + * + * Based on Linux refcount.h - simplified for single-threaded U-Boot. + */ +#ifndef _LINUX_REFCOUNT_H +#define _LINUX_REFCOUNT_H + +#include <asm-generic/atomic.h> + +/** + * typedef refcount_t - reference count type + * + * Variant of atomic_t for reference counting with saturation semantics. + * In U-Boot this is a simple wrapper around atomic_t. + */ +typedef struct { + atomic_t refs; +} refcount_t; + +#define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), } + +/** + * refcount_set() - set a refcount's value + * @r: the refcount + * @n: value to set + */ +#define refcount_set(r, n) atomic_set(&(r)->refs, (n)) + +/** + * refcount_read() - get a refcount's value + * @r: the refcount + * + * Return: the refcount's value + */ +#define refcount_read(r) atomic_read(&(r)->refs) + +/** + * refcount_inc() - increment a refcount + * @r: the refcount to increment + */ +#define refcount_inc(r) atomic_inc(&(r)->refs) + +/** + * refcount_dec() - decrement a refcount + * @r: the refcount to decrement + */ +#define refcount_dec(r) atomic_dec(&(r)->refs) + +/** + * refcount_dec_and_test() - decrement a refcount and test if it is 0 + * @r: the refcount + * + * Return: true if the resulting refcount is 0, false otherwise + */ +#define refcount_dec_and_test(r) atomic_dec_and_test(&(r)->refs) + +/** + * refcount_inc_not_zero() - increment a refcount unless it is 0 + * @r: the refcount to increment + * + * Return: true if the increment succeeded, false if refcount was 0 + */ +static inline bool refcount_inc_not_zero(refcount_t *r) +{ + return atomic_add_unless(&r->refs, 1, 0); +} + +#endif /* _LINUX_REFCOUNT_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move kobject type and related stubs to a dedicated header file that mirrors the Linux kernel organisation. kobject.h provides: - struct kobject with minimal fields (just name) - kobject_put() declaration - super_set_sysfs_name_bdev() stub macro These are minimal stubs since U-Boot doesn't have sysfs or the full kobject infrastructure. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 11 ++++------- include/linux/kobject.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 include/linux/kobject.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 4fe7d40c37f..655d64398d5 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -112,10 +112,8 @@ typedef struct { unsigned int val; } kprojid_t; #define from_kprojid(ns, kprojid) ((kprojid).val) #define projid_eq(a, b) ((a).val == (b).val) -/* kobject - stub */ -struct kobject { - const char *name; -}; +/* kobject is now in linux/kobject.h */ +#include <linux/kobject.h> /* lockdep stubs - needed before jbd2.h is included */ #include <linux/lockdep.h> @@ -1489,8 +1487,7 @@ struct block_device *file_bdev(struct file *file); int sync_blockdev(struct block_device *bdev); void invalidate_bdev(struct block_device *bdev); -/* Kobject - declarations for stub.c */ -void kobject_put(struct kobject *kobj); +/* kobject_put is now in linux/kobject.h */ /* wait_for_completion is now a macro in linux/completion.h */ /* DAX - declaration for stub.c */ @@ -1591,7 +1588,7 @@ static inline void super_set_uuid(struct super_block *sb, const u8 *uuid, memcpy(sb->s_uuid.b, uuid, len); } -#define super_set_sysfs_name_bdev(sb) do { } while (0) +/* super_set_sysfs_name_bdev is now in linux/kobject.h */ /* * mb_cache - metadata block cache stubs for xattr.c diff --git a/include/linux/kobject.h b/include/linux/kobject.h new file mode 100644 index 00000000000..f6427724d00 --- /dev/null +++ b/include/linux/kobject.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Kobject stubs for U-Boot + * + * U-Boot doesn't have sysfs or the full kobject infrastructure, + * so these are minimal stubs. + */ +#ifndef _LINUX_KOBJECT_H +#define _LINUX_KOBJECT_H + +#include <linux/types.h> + +/** + * struct kobject - kernel object + * @name: name of the object + * + * U-Boot stub - minimal structure for filesystem code. + */ +struct kobject { + const char *name; +}; + +/** + * kobject_put() - decrement refcount on kobject + * @kobj: object to release + * + * U-Boot stub - declared here, implemented in stub.c. + */ +void kobject_put(struct kobject *kobj); + +/* sysfs stubs */ +#define super_set_sysfs_name_bdev(sb) do { } while (0) + +#endif /* _LINUX_KOBJECT_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move XArray type and operation stubs to a dedicated header file that mirrors the Linux kernel organisation. xarray.h provides: - xa_mark_t type for XArray marks - struct xarray (empty stub) - xa_init(), xa_destroy() - initialisation stubs - xa_load(), xa_erase(), xa_insert() - access stubs - xa_empty() - always returns true - xa_for_each(), xa_for_each_range() - iteration macros (iterate zero times) These are stubs since U-Boot doesn't use the XArray data structure. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 26 +++------------------- include/linux/xarray.h | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 include/linux/xarray.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 655d64398d5..97bcc48d922 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -915,10 +915,9 @@ static inline int in_range(unsigned long val, unsigned long start, /* folio and pagemap - use linux/pagemap.h */ #include <linux/pagemap.h> +#include <linux/xarray.h> -/* xa_mark_t - xarray mark type */ -typedef unsigned int xa_mark_t; - +/* wbc_to_tag - convert writeback control to pagecache tag */ static inline xa_mark_t wbc_to_tag(struct writeback_control *wbc) { if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) @@ -1673,28 +1672,9 @@ struct buffer_head *__bread(struct block_device *bdev, sector_t block, unsigned * Stubs for mballoc.c */ -/* XArray stub structure */ -struct xarray { - int dummy; -}; - +/* XArray is now in linux/xarray.h */ /* Per-CPU stubs are in linux/percpu.h */ -/* XArray function stubs */ -#define xa_init(xa) do { } while (0) -#define xa_destroy(xa) do { } while (0) -#define xa_load(xa, index) ((void *)NULL) -#define xa_erase(xa, index) do { (void)(xa); (void)(index); } while (0) -#define xa_insert(xa, index, entry, gfp) ({ (void)(xa); (void)(index); (void)(entry); (void)(gfp); 0; }) -#define xa_empty(xa) ({ (void)(xa); 1; }) - -/* XArray iteration stubs - iterate zero times */ -#define xa_for_each(xa, index, entry) \ - for ((index) = 0, (entry) = NULL; 0; ) - -#define xa_for_each_range(xa, index, entry, start, end) \ - for ((index) = (start), (entry) = NULL; 0; ) - /* Bit operations for little-endian bitmaps */ #define __clear_bit_le(bit, addr) clear_bit_le(bit, addr) diff --git a/include/linux/xarray.h b/include/linux/xarray.h new file mode 100644 index 00000000000..49c00ed9380 --- /dev/null +++ b/include/linux/xarray.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * XArray stubs for U-Boot + * + * U-Boot doesn't have the XArray data structure, so these are stubs. + */ +#ifndef _LINUX_XARRAY_H +#define _LINUX_XARRAY_H + +#include <linux/types.h> + +/** + * typedef xa_mark_t - XArray mark type + * + * Used to tag entries in an XArray. + */ +typedef unsigned int xa_mark_t; + +/** + * struct xarray - XArray data structure + * + * U-Boot stub - the XArray is not used. + */ +struct xarray { + int dummy; +}; + +/* XArray initialisation/destruction stubs */ +#define xa_init(xa) do { } while (0) +#define xa_destroy(xa) do { } while (0) + +/* XArray lookup stubs - always return NULL */ +#define xa_load(xa, index) ((void *)NULL) + +/* XArray modification stubs */ +#define xa_erase(xa, index) do { (void)(xa); (void)(index); } while (0) +#define xa_insert(xa, index, entry, gfp) \ + ({ (void)(xa); (void)(index); (void)(entry); (void)(gfp); 0; }) + +/* XArray query stubs - always empty */ +#define xa_empty(xa) ({ (void)(xa); 1; }) + +/* XArray iteration stubs - iterate zero times */ +#define xa_for_each(xa, index, entry) \ + for ((index) = 0, (entry) = NULL; 0; ) + +#define xa_for_each_range(xa, index, entry, start, end) \ + for ((index) = (start), (entry) = NULL; 0; ) + +#endif /* _LINUX_XARRAY_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move memory pool type and operation stubs to a dedicated header file that mirrors the Linux kernel organisation. mempool.h provides: - mempool_t type - mempool_alloc() - allocate from pool (stub returns NULL) - mempool_free() - free to pool (stub no-op) - mempool_create_slab_pool() - create pool (stub returns NULL) - mempool_destroy() - destroy pool (stub no-op) These are stubs since U-Boot doesn't use memory pools. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 8 ++---- include/linux/mempool.h | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 include/linux/mempool.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 97bcc48d922..f77891835cb 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1795,12 +1795,8 @@ bool __folio_start_writeback(struct folio *folio, bool keep_write); * Stubs for readpage.c */ -/* mempool - memory pool stubs */ -typedef void *mempool_t; -#define mempool_alloc(pool, gfp) ({ (void)(pool); (void)(gfp); (void *)NULL; }) -#define mempool_free(elem, pool) do { (void)(elem); (void)(pool); } while (0) -#define mempool_create_slab_pool(n, c) ({ (void)(n); (void)(c); (mempool_t *)NULL; }) -#define mempool_destroy(pool) do { (void)(pool); } while (0) +/* mempool is now in linux/mempool.h */ +#include <linux/mempool.h> /* folio read operations */ #define folio_end_read(f, success) do { (void)(f); (void)(success); } while (0) diff --git a/include/linux/mempool.h b/include/linux/mempool.h new file mode 100644 index 00000000000..feb99a1455c --- /dev/null +++ b/include/linux/mempool.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Memory pool stubs for U-Boot + * + * U-Boot doesn't have memory pools, so these are stubs. + */ +#ifndef _LINUX_MEMPOOL_H +#define _LINUX_MEMPOOL_H + +#include <linux/types.h> + +/** + * typedef mempool_t - memory pool handle + * + * U-Boot stub - memory pools are not used. + */ +typedef void *mempool_t; + +/** + * mempool_alloc() - allocate element from pool + * @pool: memory pool + * @gfp: allocation flags + * + * U-Boot stub - always returns NULL. + */ +#define mempool_alloc(pool, gfp) \ + ({ (void)(pool); (void)(gfp); (void *)NULL; }) + +/** + * mempool_free() - free element back to pool + * @elem: element to free + * @pool: memory pool + * + * U-Boot stub - no-op. + */ +#define mempool_free(elem, pool) \ + do { (void)(elem); (void)(pool); } while (0) + +/** + * mempool_create_slab_pool() - create a memory pool backed by a slab cache + * @min_nr: minimum number of elements + * @cache: slab cache + * + * U-Boot stub - always returns NULL. + */ +#define mempool_create_slab_pool(min_nr, cache) \ + ({ (void)(min_nr); (void)(cache); (mempool_t *)NULL; }) + +/** + * mempool_destroy() - destroy a memory pool + * @pool: memory pool to destroy + * + * U-Boot stub - no-op. + */ +#define mempool_destroy(pool) do { (void)(pool); } while (0) + +#endif /* _LINUX_MEMPOOL_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move device-number-encoding macros to a dedicated header file that mirrors the Linux kernel organisation. kdev_t.h provides: - MINORBITS, MINORMASK - minor number parameters - MAJOR(), MINOR() - extract major/minor from dev_t - MKDEV() - create dev_t from major/minor - old_valid_dev(), old_encode_dev(), old_decode_dev() - old 8:8 format - new_encode_dev(), new_decode_dev() - new format (pass-through) Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 24 ++---------------- include/linux/kdev_t.h | 56 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 include/linux/kdev_t.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index f77891835cb..aa357599449 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1086,28 +1086,8 @@ static inline unsigned int i_gid_read(const struct inode *inode) #define i_uid_update(m, a, i) do { } while (0) #define i_gid_update(m, a, i) do { } while (0) -/* Device encoding helpers */ -#ifndef MINORBITS -#define MINORBITS 20 -#endif -#ifndef MINORMASK -#define MINORMASK ((1U << MINORBITS) - 1) -#endif -#ifndef MAJOR -#define MAJOR(dev) ((unsigned int)((dev) >> MINORBITS)) -#endif -#ifndef MINOR -#define MINOR(dev) ((unsigned int)((dev) & MINORMASK)) -#endif -#ifndef MKDEV -#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi)) -#endif - -#define old_valid_dev(dev) (MAJOR(dev) < 256 && MINOR(dev) < 256) -#define old_encode_dev(dev) ((MAJOR(dev) << 8) | MINOR(dev)) -#define old_decode_dev(dev) MKDEV((dev) >> 8, (dev) & 0xff) -#define new_encode_dev(dev) ((unsigned int)(dev)) -#define new_decode_dev(dev) ((dev_t)(dev)) +/* Device encoding helpers are now in linux/kdev_t.h */ +#include <linux/kdev_t.h> /* UID/GID bit helpers */ #define low_16_bits(x) ((x) & 0xFFFF) diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h new file mode 100644 index 00000000000..1aa524b9dca --- /dev/null +++ b/include/linux/kdev_t.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Device number macros for U-Boot + * + * Based on Linux kdev_t.h + */ +#ifndef _LINUX_KDEV_T_H +#define _LINUX_KDEV_T_H + +#include <linux/types.h> + +/* Number of minor bits */ +#ifndef MINORBITS +#define MINORBITS 20 +#endif + +/* Minor number mask */ +#ifndef MINORMASK +#define MINORMASK ((1U << MINORBITS) - 1) +#endif + +/** + * MAJOR - extract major number from dev_t + * @dev: device number + */ +#ifndef MAJOR +#define MAJOR(dev) ((unsigned int)((dev) >> MINORBITS)) +#endif + +/** + * MINOR - extract minor number from dev_t + * @dev: device number + */ +#ifndef MINOR +#define MINOR(dev) ((unsigned int)((dev) & MINORMASK)) +#endif + +/** + * MKDEV - create dev_t from major and minor numbers + * @ma: major number + * @mi: minor number + */ +#ifndef MKDEV +#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi)) +#endif + +/* Old-style device number encoding (8:8) */ +#define old_valid_dev(dev) (MAJOR(dev) < 256 && MINOR(dev) < 256) +#define old_encode_dev(dev) ((MAJOR(dev) << 8) | MINOR(dev)) +#define old_decode_dev(dev) MKDEV((dev) >> 8, (dev) & 0xff) + +/* New-style device number encoding (pass-through) */ +#define new_encode_dev(dev) ((unsigned int)(dev)) +#define new_decode_dev(dev) ((dev_t)(dev)) + +#endif /* _LINUX_KDEV_T_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move block I/O plugging stubs to linux/blkdev.h where they belong in the Linux kernel organisation. Add to blkdev.h: - struct blk_plug - block I/O plug structure - blk_start_plug() - start plugging (stub no-op) - blk_finish_plug() - finish plugging (stub no-op) These are stubs since U-Boot doesn't use block I/O plugging. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 7 +------ include/linux/blkdev.h | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index aa357599449..979af9ed22a 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -925,12 +925,7 @@ static inline xa_mark_t wbc_to_tag(struct writeback_control *wbc) return PAGECACHE_TAG_DIRTY; } -/* blk_plug - block I/O plugging stub */ -struct blk_plug { - int dummy; -}; -#define blk_start_plug(p) do { (void)(p); } while (0) -#define blk_finish_plug(p) do { (void)(p); } while (0) +/* blk_plug is now in linux/blkdev.h */ /* Writeback reasons */ #define WB_REASON_FS_FREE_SPACE 0 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 92878b01c3e..8c848139a7e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -18,4 +18,29 @@ struct gendisk; /* Block size helpers */ #define bdev_logical_block_size(bdev) 512 +/** + * struct blk_plug - block I/O plug + * + * U-Boot stub - block I/O plugging is not used. + */ +struct blk_plug { + int dummy; +}; + +/** + * blk_start_plug() - start plugging block I/O + * @plug: plug structure + * + * U-Boot stub - no-op. + */ +#define blk_start_plug(plug) do { (void)(plug); } while (0) + +/** + * blk_finish_plug() - finish plugging and submit I/O + * @plug: plug structure + * + * U-Boot stub - no-op. + */ +#define blk_finish_plug(plug) do { (void)(plug); } while (0) + #endif /* _LINUX_BLKDEV_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move filesystem map (fsmap) structure and constants to a dedicated header file that mirrors the Linux kernel organisation. fsmap.h provides: - struct fsmap - filesystem extent mapping structure - FMR_OWN_FREE, FMR_OWN_UNKNOWN - special owner values - FMR_OWNER() - construct owner from type and code - FMR_OF_SPECIAL_OWNER - flag for special owners - FMH_IF_VALID, FMH_OF_DEV_T - head flags These are used by the ext4l fsmap.c for the FS_IOC_GETFSMAP ioctl. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/ext4_uboot.h | 19 ++---------------- include/linux/fsmap.h | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 include/linux/fsmap.h diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 979af9ed22a..a4d863b86e1 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1976,23 +1976,8 @@ int ext4_update_overhead(struct super_block *sb, bool force); * Stubs for fsmap.c */ -/* fsmap.c stubs - struct fsmap from linux/fsmap.h */ -struct fsmap { - __u32 fmr_device; /* device id */ - __u32 fmr_flags; /* mapping flags */ - __u64 fmr_physical; /* device offset of segment */ - __u64 fmr_owner; /* owner id */ - __u64 fmr_offset; /* file offset of segment */ - __u64 fmr_length; /* length of segment */ - __u64 fmr_reserved[3]; /* must be zero */ -}; - -#define FMR_OWN_FREE (-1ULL) -#define FMR_OWN_UNKNOWN (-2ULL) -#define FMR_OWNER(type, code) (((__u64)(type) << 32) | (__u64)(code)) -#define FMR_OF_SPECIAL_OWNER (1 << 0) -#define FMH_IF_VALID 0 -#define FMH_OF_DEV_T (1 << 0) +/* fsmap is now in linux/fsmap.h */ +#include <linux/fsmap.h> /* list_sort and sort stubs for fsmap.c */ #define list_sort(priv, head, cmp) \ diff --git a/include/linux/fsmap.h b/include/linux/fsmap.h new file mode 100644 index 00000000000..6b5ef9e2faa --- /dev/null +++ b/include/linux/fsmap.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Filesystem map definitions for U-Boot + * + * Based on Linux fsmap.h - for FS_IOC_GETFSMAP ioctl. + */ +#ifndef _LINUX_FSMAP_H +#define _LINUX_FSMAP_H + +#include <linux/types.h> + +/** + * struct fsmap - filesystem extent mapping + * @fmr_device: device identifier + * @fmr_flags: mapping flags + * @fmr_physical: physical offset on device + * @fmr_owner: owner identifier + * @fmr_offset: logical offset in file + * @fmr_length: length of the extent + * @fmr_reserved: reserved (must be zero) + */ +struct fsmap { + __u32 fmr_device; + __u32 fmr_flags; + __u64 fmr_physical; + __u64 fmr_owner; + __u64 fmr_offset; + __u64 fmr_length; + __u64 fmr_reserved[3]; +}; + +/* Special owner values */ +#define FMR_OWN_FREE (-1ULL) +#define FMR_OWN_UNKNOWN (-2ULL) + +/* Construct owner value from type and code */ +#define FMR_OWNER(type, code) (((__u64)(type) << 32) | (__u64)(code)) + +/* fsmap flags */ +#define FMR_OF_SPECIAL_OWNER (1 << 0) + +/* fsmap head flags */ +#define FMH_IF_VALID 0 +#define FMH_OF_DEV_T (1 << 0) + +#endif /* _LINUX_FSMAP_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move xchg and try_cmpxchg macros to asm-generic/atomic.h alongside cmpxchg, as they are all atomic exchange operations. Add: - try_cmpxchg() - compare and exchange with boolean return and old value update on failure - xchg() - atomic exchange, stores new value and returns old These are single-threaded implementations for U-Boot. Add #ifndef guards to all three macros (cmpxchg, try_cmpxchg, xchg) to avoid redefinition warnings on architectures like MIPS that provide their own implementations. Signed-off-by: Simon Glass <simon.glass@canonical.com> Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> --- fs/ext4l/ext4_uboot.h | 12 ++---------- include/asm-generic/atomic.h | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index a4d863b86e1..a4baac6fc86 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -949,14 +949,7 @@ typedef unsigned int projid_t; * Additional stubs for inode.c */ -/* try_cmpxchg - compare and exchange with return value */ -#define try_cmpxchg(ptr, old, new) ({ \ - typeof(*(old)) __old = *(old); \ - typeof(*(ptr)) __ret = cmpxchg(ptr, __old, (new)); \ - if (__ret != __old) \ - *(old) = __ret; \ - __ret == __old; \ -}) +/* try_cmpxchg is now in asm-generic/atomic.h */ /* hash_64 - simple 64-bit hash */ #define hash_64(val, bits) ((unsigned long)((val) >> (64 - (bits)))) @@ -1743,8 +1736,7 @@ static inline unsigned long ext4_find_next_bit_le(const void *addr, /* refcount operations are now in linux/refcount.h */ -/* xchg - exchange value atomically */ -#define xchg(ptr, new) ({ typeof(*(ptr)) __old = *(ptr); *(ptr) = (new); __old; }) +/* xchg is now in asm-generic/atomic.h */ /* printk_ratelimited is in linux/printk.h */ diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 3fa749bf012..3f72ae39ee1 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -209,6 +209,7 @@ static inline void atomic64_dec(volatile atomic64_t *v) * Single-threaded version for U-Boot. Atomically compares *ptr with old * and if equal, stores new. Returns the original value of *ptr. */ +#ifndef cmpxchg #define cmpxchg(ptr, old, new) ({ \ typeof(*(ptr)) __cmpxchg_old = (old); \ typeof(*(ptr)) __cmpxchg_new = (new); \ @@ -217,5 +218,41 @@ static inline void atomic64_dec(volatile atomic64_t *v) *(ptr) = __cmpxchg_new; \ __cmpxchg_ret; \ }) +#endif + +/** + * try_cmpxchg - compare and exchange with boolean return + * @ptr: pointer to the value + * @oldp: pointer to expected old value (updated on failure) + * @new: new value to store if current equals old + * + * Returns true if exchange succeeded, false otherwise. + * On failure, *oldp is updated with the current value. + */ +#ifndef try_cmpxchg +#define try_cmpxchg(ptr, oldp, new) ({ \ + typeof(*(oldp)) __old = *(oldp); \ + typeof(*(ptr)) __ret = cmpxchg(ptr, __old, (new)); \ + if (__ret != __old) \ + *(oldp) = __ret; \ + __ret == __old; \ +}) +#endif + +/** + * xchg - exchange value atomically + * @ptr: pointer to the value + * @new: new value to store + * + * Atomically stores new value and returns the old value. + * Single-threaded version for U-Boot. + */ +#ifndef xchg +#define xchg(ptr, new) ({ \ + typeof(*(ptr)) __xchg_old = *(ptr); \ + *(ptr) = (new); \ + __xchg_old; \ +}) +#endif #endif -- 2.43.0
participants (1)
-
Simon Glass