[PATCH 00/10] ext4l: Add more ext4 files to the build (part E)
From: Simon Glass <simon.glass@canonical.com> This adds more files to the build. Most are fairly small but some still require a fair few additions to ext4_uboot.h and the stub.c files. At this point, we are close to having all the files in place, so can move on to actually making ext4 work. Simon Glass (10): ext4l: Add file.c to build ext4l: Add fsync.c to build ext4l: Add symlink.c to build ext4l: Add namei.c to build ext4l: Add xattr.c to build ext4l: Add inline.c to build ext4l: Add mballoc.c to build ext4l: Add page-io.c to build ext4l: Add readpage.c to build ext4l: Add fast_commit.c to build fs/ext4l/Makefile | 10 +- fs/ext4l/ext4_uboot.h | 774 ++++++++++++++++++++++++++++++++++++-- fs/ext4l/fast_commit.c | 6 +- fs/ext4l/file.c | 35 +- fs/ext4l/fsync.c | 9 +- fs/ext4l/inline.c | 6 +- fs/ext4l/mballoc.c | 10 +- fs/ext4l/namei.c | 15 +- fs/ext4l/page-io.c | 15 +- fs/ext4l/readpage.c | 16 +- fs/ext4l/stub.c | 340 ++++++----------- fs/ext4l/symlink.c | 7 +- fs/ext4l/xattr.c | 8 +- include/linux/fs.h | 21 ++ include/linux/iomap.h | 8 + include/linux/seq_file.h | 7 +- include/linux/slab.h | 2 +- include/linux/workqueue.h | 4 + 18 files changed, 936 insertions(+), 357 deletions(-) -- 2.43.0 base-commit: a637211647fe0233e09de05c180511194e30a1c4 branch: exte
From: Simon Glass <simon.glass@canonical.com> Add file.c which provides file operations for ext4l filesystem. Changes needed for file.c support: - Add i_writecount and i_rwsem fields to struct inode - Add IOMAP_DIO_* flags to linux/iomap.h - Add vm_operations_struct definition - Add VM flags (VM_SHARED, VM_HUGEPAGE, etc.) - Add vm_area_desc and pipe_inode_info structures - Add FMODE_* flags and SEEK_HOLE/SEEK_DATA to linux/fs.h - Add vfsmount, path structs and f_path to struct file - Add inode_trylock*, lockdep_assert_held_write macros - Add filemap_fault, filemap_map_pages stubs - Add inode_operations struct definition - Add various stubs: d_path, fscrypt_file_open, fsverity_file_open, dquot_file_open, sb_start_intwrite_trylock, ext4_listxattr Simplify ext4_file_operations and ext4_file_inode_operations initializers to use only the members defined in U-Boot's structs. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 105 ++++++++++++++++++++++++++++++++++++++++-- fs/ext4l/file.c | 20 +------- fs/ext4l/stub.c | 14 +++--- include/linux/fs.h | 21 +++++++++ include/linux/iomap.h | 8 ++++ 6 files changed, 140 insertions(+), 30 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index c4fe972d426..73083e82cd8 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -6,7 +6,7 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ - extents_status.o hash.o ialloc.o \ + extents_status.o file.o hash.o ialloc.o \ indirect.o inode.o \ super.o xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 4f0cb4cf13d..5f466dbf005 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -237,6 +237,10 @@ struct iomap_ops { int (*iomap_end)(struct inode *inode, loff_t pos, loff_t length, ssize_t written, unsigned flags, struct iomap *iomap); }; + +/* iomap DIO flags */ +#define IOMAP_DIO_UNWRITTEN (1 << 0) +#define IOMAP_DIO_FORCE_WAIT (1 << 1) #endif /* LINUX_IOMAP_H */ /* fiemap types */ @@ -549,6 +553,22 @@ struct dentry { /* 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 + +/* 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 */ struct kstat; struct path; @@ -698,11 +718,7 @@ static inline int bdev_read_only(struct block_device *bdev) #define VM_FAULT_NOPAGE 0x0010 #define VM_FAULT_LOCKED 0x0200 -/* struct path - filesystem path */ -struct path { - struct vfsmount *mnt; - struct dentry *dentry; -}; +/* struct path is defined in linux/fs.h */ /* struct kstat - stat buffer */ struct kstat { @@ -753,6 +769,15 @@ struct vm_fault { 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); +}; + /* Forward declaration for swap */ struct swap_info_struct; @@ -789,6 +814,8 @@ struct inode { dev_t i_rdev; const struct inode_operations *i_op; const struct file_operations *i_fop; + atomic_t i_writecount; /* Count of writers */ + struct rw_semaphore i_rwsem; /* inode lock */ }; /* Inode time accessors */ @@ -941,17 +968,45 @@ static inline unsigned long memweight(const void *ptr, size_t bytes) #define inode_unlock(inode) do { } while (0) #define inode_lock_shared(inode) do { } while (0) #define inode_unlock_shared(inode) do { } while (0) +#define inode_trylock(inode) (1) +#define inode_trylock_shared(inode) (1) #define inode_dio_wait(inode) do { } while (0) +/* Lock debugging - no-ops in U-Boot */ +#define lockdep_assert_held_write(l) do { } while (0) +#define lockdep_assert_held(l) do { } while (0) + /* File operations */ #define file_modified(file) ({ (void)(file); 0; }) +#define file_accessed(file) do { (void)(file); } while (0) + +/* 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 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; +} + +/* DAX device mapping check - always false in U-Boot */ +#define daxdev_mapping_supported(f, i, d) ({ (void)(f); (void)(i); (void)(d); 1; }) /* Inode time/size operations */ #define inode_newsize_ok(i, s) ({ (void)(i); (void)(s); 0; }) @@ -1245,9 +1300,25 @@ typedef unsigned int projid_t; /* Superblock freezing stubs */ #define sb_start_intwrite(sb) do { (void)(sb); } while (0) #define sb_end_intwrite(sb) do { (void)(sb); } while (0) +#define sb_start_intwrite_trylock(sb) ({ (void)(sb); 1; }) #define sb_start_pagefault(sb) do { (void)(sb); } while (0) #define sb_end_pagefault(sb) do { (void)(sb); } while (0) +/* d_path - get pathname - stub returns empty path */ +static inline char *d_path(const struct path *path, char *buf, int buflen) +{ + if (buflen > 0) + buf[0] = '\0'; + return buf; +} + +/* fscrypt/fsverity stubs */ +#define fscrypt_file_open(i, f) ({ (void)(i); (void)(f); 0; }) +#define fsverity_file_open(i, f) ({ (void)(i); (void)(f); 0; }) + +/* Quota file open - stub */ +#define dquot_file_open(i, f) ({ (void)(i); (void)(f); 0; }) + /* Inode I/O list management */ #define inode_io_list_del(inode) do { } while (0) #define inode_is_open_for_write(i) (0) @@ -1428,6 +1499,15 @@ static inline unsigned int i_gid_read(const struct inode *inode) #define file_update_time(f) do { } while (0) #define vmf_fs_error(e) ((vm_fault_t)VM_FAULT_SIGBUS) +/* VFS file operations for file.c */ +#define generic_file_read_iter(iocb, to) ({ (void)(iocb); (void)(to); 0; }) +#define filemap_splice_read(f, p, pipe, l, fl) ({ (void)(f); (void)(p); (void)(pipe); (void)(l); (void)(fl); 0; }) +#define generic_write_checks(iocb, from) ({ (void)(iocb); (void)(from); 0; }) +#define generic_perform_write(iocb, from) ({ (void)(iocb); (void)(from); 0; }) +#define generic_write_sync(iocb, count) ({ (void)(iocb); (count); }) +#define generic_atomic_write_valid(iocb, from) ({ (void)(iocb); (void)(from); true; }) +#define vfs_setpos(file, offset, maxsize) ({ (void)(file); (void)(maxsize); (offset); }) + /* iomap stubs */ #define iomap_bmap(m, b, o) ({ (void)(m); (void)(b); (void)(o); 0UL; }) #define iomap_swapfile_activate(s, f, sp, o) ({ (void)(s); (void)(f); (void)(sp); (void)(o); -EOPNOTSUPP; }) @@ -1485,6 +1565,21 @@ struct file_operations { int (*release)(struct inode *, struct file *); }; +/* inode_operations - for file and directory operations */ +struct inode_operations { + int (*getattr)(struct mnt_idmap *, const struct path *, + struct kstat *, u32, unsigned int); + ssize_t (*listxattr)(struct dentry *, char *, size_t); + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64, u64); + int (*setattr)(struct mnt_idmap *, struct dentry *, struct iattr *); + struct posix_acl *(*get_inode_acl)(struct inode *, int, bool); + int (*set_acl)(struct mnt_idmap *, struct dentry *, + struct posix_acl *, int); + int (*fileattr_get)(struct dentry *, struct file_kattr *); + int (*fileattr_set)(struct mnt_idmap *, struct dentry *, + struct file_kattr *); +}; + /* file open helper */ #define simple_open(i, f) ({ (void)(i); (void)(f); 0; }) diff --git a/fs/ext4l/file.c b/fs/ext4l/file.c index 6cff27e7029..b4127dbe913 100644 --- a/fs/ext4l/file.c +++ b/fs/ext4l/file.c @@ -952,36 +952,20 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int whence) return vfs_setpos(file, offset, maxbytes); } +/* U-Boot simplified file operations */ const struct file_operations ext4_file_operations = { .llseek = ext4_llseek, - .read_iter = ext4_file_read_iter, - .write_iter = ext4_file_write_iter, - .iopoll = iocb_bio_iopoll, .unlocked_ioctl = ext4_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ext4_compat_ioctl, -#endif - .mmap_prepare = ext4_file_mmap_prepare, .open = ext4_file_open, .release = ext4_release_file, .fsync = ext4_sync_file, - .get_unmapped_area = thp_get_unmapped_area, - .splice_read = ext4_file_splice_read, - .splice_write = iter_file_splice_write, - .fallocate = ext4_fallocate, - .fop_flags = FOP_MMAP_SYNC | FOP_BUFFER_RASYNC | - FOP_DIO_PARALLEL_WRITE | - FOP_DONTCACHE, }; +/* U-Boot simplified inode operations */ const struct inode_operations ext4_file_inode_operations = { .setattr = ext4_setattr, .getattr = ext4_file_getattr, .listxattr = ext4_listxattr, - .get_inode_acl = ext4_get_acl, - .set_acl = ext4_set_acl, .fiemap = ext4_fiemap, - .fileattr_get = ext4_fileattr_get, - .fileattr_set = ext4_fileattr_set, }; diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index f452357953e..b378eab97a3 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -236,6 +236,11 @@ int ext4_xattr_set(struct inode *inode, int name_index, const char *name, return -1; } +ssize_t ext4_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) +{ + return 0; +} + /* * Stubs for orphan.c */ @@ -414,8 +419,8 @@ int ext4_find_inline_data_nolock(struct inode *inode) /* File and inode operations symbols */ -char ext4_file_inode_operations; -char ext4_file_operations; +/* ext4_file_inode_operations is now in file.c */ +/* ext4_file_operations is now in file.c */ char ext4_dir_inode_operations; /* ext4_dir_operations is now in dir.c */ char ext4_special_inode_operations; @@ -485,10 +490,7 @@ ssize_t generic_read_dir(struct file *f, char *buf, size_t count, loff_t *ppos) /* __ext4_error_file is now in super.c */ -loff_t ext4_llseek(struct file *file, loff_t offset, int whence) -{ - return 0; -} +/* ext4_llseek is now in file.c */ int ext4_htree_fill_tree(struct file *dir_file, unsigned long long pos, unsigned long long start_hash, diff --git a/include/linux/fs.h b/include/linux/fs.h index 0af81af5644..ae34b1f7356 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -27,6 +27,26 @@ typedef unsigned int fmode_t; #define FMODE_READ ((__force fmode_t)(1 << 0)) #define FMODE_WRITE ((__force fmode_t)(1 << 1)) #define FMODE_LSEEK ((__force fmode_t)(1 << 2)) +#define FMODE_NOWAIT ((__force fmode_t)(1 << 20)) +#define FMODE_CAN_ODIRECT ((__force fmode_t)(1 << 21)) +#define FMODE_CAN_ATOMIC_WRITE ((__force fmode_t)(1 << 22)) + +/* Seek constants */ +#ifndef SEEK_HOLE +#define SEEK_HOLE 4 +#define SEEK_DATA 3 +#endif + +/* vfsmount - mount point */ +struct vfsmount { + struct dentry *mnt_root; +}; + +/* path - pathname components */ +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; /* Buffer operations are in buffer_head.h */ @@ -76,6 +96,7 @@ struct file { struct address_space *f_mapping; void *private_data; struct file_ra_state f_ra; + struct path f_path; }; /* Get inode from file */ diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 3bd4070cfdb..a426cf35f40 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -46,6 +46,14 @@ struct vm_fault; /* Additional iomap flags */ #define IOMAP_F_ATOMIC_BIO (1U << 6) +/* iomap DIO end_io flags */ +#define IOMAP_DIO_UNWRITTEN (1 << 0) +#define IOMAP_DIO_COW (1 << 1) + +/* iomap_dio_rw flags */ +#define IOMAP_DIO_FORCE_WAIT (1 << 0) +#define IOMAP_DIO_OVERWRITE_ONLY (1 << 1) + struct iomap { u64 addr; loff_t offset; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add fsync.c which provides filesystem sync operations. Changes needed: - Add ext4_uboot.h include to fsync.c - Remove redundant Linux header includes - Add trace_ext4_sync_file_enter/exit stubs - Add dentry operation stubs (d_find_any_alias, dget_parent) - Add sync operation stubs (sync_mapping_buffers, sync_inode_metadata, generic_buffers_fsync_noflush, file_write_and_wait_range, file_check_and_advance_wb_err) - Add jbd2_trans_will_send_data_barrier stub - Remove ext4_sync_file stub from stub.c (now in fsync.c) Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 13 +++++++++++++ fs/ext4l/fsync.c | 9 +-------- fs/ext4l/stub.c | 10 ++++++---- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 73083e82cd8..96caa289be0 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -6,7 +6,7 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ - extents_status.o file.o hash.o ialloc.o \ + extents_status.o file.o fsync.o hash.o ialloc.o \ indirect.o inode.o \ super.o xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 5f466dbf005..0f0e9c91a12 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1289,6 +1289,19 @@ typedef unsigned int projid_t; #define trace_ext4_write_begin(...) do { } while (0) #define trace_ext4_write_end(...) do { } while (0) #define trace_ext4_journalled_write_end(...) do { } while (0) +#define trace_ext4_sync_file_enter(...) do { } while (0) +#define trace_ext4_sync_file_exit(...) do { } while (0) + +/* Dentry operations - stubs */ +#define d_find_any_alias(i) ({ (void)(i); (struct dentry *)NULL; }) +#define dget_parent(d) ({ (void)(d); (struct dentry *)NULL; }) + +/* Sync operations - stubs */ +#define sync_mapping_buffers(m) ({ (void)(m); 0; }) +#define sync_inode_metadata(i, w) ({ (void)(i); (void)(w); 0; }) +#define generic_buffers_fsync_noflush(f, s, e, d) ({ (void)(f); (void)(s); (void)(e); (void)(d); 0; }) +#define file_write_and_wait_range(f, s, e) ({ (void)(f); (void)(s); (void)(e); 0; }) +#define file_check_and_advance_wb_err(f) ({ (void)(f); 0; }) /* DAX stubs - DAX not supported in U-Boot */ #define IS_DAX(inode) (0) diff --git a/fs/ext4l/fsync.c b/fs/ext4l/fsync.c index e476c6de307..42a9e2bdbff 100644 --- a/fs/ext4l/fsync.c +++ b/fs/ext4l/fsync.c @@ -23,18 +23,11 @@ * we can depend on generic_block_fdatasync() to sync the data blocks. */ -#include <linux/time.h> -#include <linux/fs.h> -#include <linux/sched.h> -#include <linux/writeback.h> -#include <linux/blkdev.h> -#include <linux/buffer_head.h> +#include "ext4_uboot.h" #include "ext4.h" #include "ext4_jbd2.h" -#include <trace/events/ext4.h> - /* * If we're not journaling and this is a just-created file, we have to * sync our parent directory (if it was freshly created) since diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index b378eab97a3..4dac514340c 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -107,6 +107,11 @@ int jbd2__journal_restart(void *handle, int nblocks, int revoke_records, return 0; } +int jbd2_trans_will_send_data_barrier(journal_t *journal, unsigned long tid) +{ + return 0; +} + /* * Stubs for balloc.c */ @@ -512,10 +517,7 @@ int ext4_dirblock_csum_verify(struct inode *inode, struct buffer_head *bh) /* ext4_ioctl is now in super.c */ -int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) -{ - return 0; -} +/* ext4_sync_file is now in fsync.c */ /* * Stubs for super.c -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add symlink.c which provides symlink inode operations. Changes needed: - Add ext4_uboot.h include to symlink.c - Add delayed_call struct and set_delayed_call macro - Add kfree_link definition - Add nd_terminate_link helper function - Add get_link member to inode_operations struct - Add simple_get_link function for fast symlinks - Add i_link field to struct inode - Add fscrypt_get_symlink and fscrypt_symlink_getattr stubs - Add ext4_read_inline_link stub - Remove ext4_symlink_inode_operations and ext4_fast_symlink_inode_operations stubs from stub.c Drop some duplicate declarations in ext4_uboot.h Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 4 +-- fs/ext4l/ext4_uboot.h | 77 ++++++++++++++++++++++++++++++------------- fs/ext4l/file.c | 15 +++++---- fs/ext4l/stub.c | 15 +++++---- fs/ext4l/symlink.c | 7 ++-- 5 files changed, 78 insertions(+), 40 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 96caa289be0..fe6d9ccafe8 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -7,6 +7,6 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ - indirect.o inode.o \ - super.o xattr_hurd.o xattr_trusted.o \ + indirect.o inode.o super.o symlink.o \ + xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 0f0e9c91a12..83a714f78a0 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -816,6 +816,7 @@ struct inode { const struct file_operations *i_fop; atomic_t i_writecount; /* Count of writers */ struct rw_semaphore i_rwsem; /* inode lock */ + const char *i_link; /* Symlink target for fast symlinks */ }; /* Inode time accessors */ @@ -916,6 +917,16 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir, #define WARN_ON_ONCE(cond) ({ (void)(cond); 0; }) #define WARN_ON(cond) ({ (void)(cond); 0; }) +/* strtomem_pad - copy string to fixed-size buffer with padding */ +#define strtomem_pad(dest, src, pad) do { \ + size_t _len = strlen(src); \ + if (_len >= sizeof(dest)) \ + _len = sizeof(dest); \ + memcpy(dest, src, _len); \ + if (_len < sizeof(dest)) \ + memset((char *)(dest) + _len, (pad), sizeof(dest) - _len); \ +} while (0) + /* Memory weight - count set bits */ static inline unsigned long memweight(const void *ptr, size_t bytes) { @@ -980,6 +991,14 @@ static inline unsigned long memweight(const void *ptr, size_t bytes) #define file_modified(file) ({ (void)(file); 0; }) #define file_accessed(file) do { (void)(file); } while (0) +/* Generic file operations - stubs for file.c */ +#define generic_file_read_iter(iocb, to) ({ (void)(iocb); (void)(to); 0L; }) +#define generic_write_checks(iocb, from) ({ (void)(iocb); (void)(from); 0L; }) +#define generic_perform_write(iocb, from) ({ (void)(iocb); (void)(from); 0L; }) +#define generic_write_sync(iocb, count) ({ (void)(iocb); (count); }) +#define generic_atomic_write_valid(iocb, from) ({ (void)(iocb); (void)(from); 0; }) +#define vfs_setpos(file, offset, maxsize) ({ (void)(file); (void)(maxsize); (offset); }) + /* Security checks - no security in U-Boot */ #define IS_NOSEC(inode) (1) @@ -1295,6 +1314,7 @@ typedef unsigned int projid_t; /* 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) /* Sync operations - stubs */ #define sync_mapping_buffers(m) ({ (void)(m); 0; }) @@ -1393,6 +1413,7 @@ static inline char *d_path(const struct path *path, char *buf, int buflen) #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(bd, b, s) ((struct buffer_head *)NULL) @@ -1512,15 +1533,6 @@ static inline unsigned int i_gid_read(const struct inode *inode) #define file_update_time(f) do { } while (0) #define vmf_fs_error(e) ((vm_fault_t)VM_FAULT_SIGBUS) -/* VFS file operations for file.c */ -#define generic_file_read_iter(iocb, to) ({ (void)(iocb); (void)(to); 0; }) -#define filemap_splice_read(f, p, pipe, l, fl) ({ (void)(f); (void)(p); (void)(pipe); (void)(l); (void)(fl); 0; }) -#define generic_write_checks(iocb, from) ({ (void)(iocb); (void)(from); 0; }) -#define generic_perform_write(iocb, from) ({ (void)(iocb); (void)(from); 0; }) -#define generic_write_sync(iocb, count) ({ (void)(iocb); (count); }) -#define generic_atomic_write_valid(iocb, from) ({ (void)(iocb); (void)(from); true; }) -#define vfs_setpos(file, offset, maxsize) ({ (void)(file); (void)(maxsize); (offset); }) - /* iomap stubs */ #define iomap_bmap(m, b, o) ({ (void)(m); (void)(b); (void)(o); 0UL; }) #define iomap_swapfile_activate(s, f, sp, o) ({ (void)(s); (void)(f); (void)(sp); (void)(o); -EOPNOTSUPP; }) @@ -1578,8 +1590,30 @@ struct file_operations { int (*release)(struct inode *, struct file *); }; +/* delayed_call - for delayed freeing of symlink data */ +typedef void (*delayed_call_func_t)(const void *); +struct delayed_call { + delayed_call_func_t fn; + const void *arg; +}; + +#define set_delayed_call(dc, func, data) do { \ + (dc)->fn = (func); \ + (dc)->arg = (data); \ +} while (0) + +#define kfree_link kfree + +/* nd_terminate_link - terminate symlink string */ +static inline void nd_terminate_link(void *name, loff_t len, int maxlen) +{ + ((char *)name)[min_t(loff_t, len, maxlen)] = '\0'; +} + /* inode_operations - for file and directory operations */ struct inode_operations { + const char *(*get_link)(struct dentry *, struct inode *, + struct delayed_call *); int (*getattr)(struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); ssize_t (*listxattr)(struct dentry *, char *, size_t); @@ -1596,6 +1630,18 @@ struct inode_operations { /* file open helper */ #define simple_open(i, f) ({ (void)(i); (void)(f); 0; }) +/* simple_get_link - for fast symlinks stored in inode */ +static inline const char *simple_get_link(struct dentry *dentry, + struct inode *inode, + struct delayed_call *callback) +{ + return inode->i_link; +} + +/* fscrypt symlink stubs */ +#define fscrypt_get_symlink(i, c, m, d) ({ (void)(i); (void)(c); (void)(m); (void)(d); ERR_PTR(-EOPNOTSUPP); }) +#define fscrypt_symlink_getattr(p, s) ({ (void)(p); (void)(s); 0; }) + /* * Additional stubs for super.c */ @@ -2118,23 +2164,10 @@ void set_task_ioprio(void *task, int ioprio); /* Dentry operations - declarations for stub.c */ void generic_set_sb_d_ops(struct super_block *sb); struct dentry *d_make_root(struct inode *inode); -void dput(void *dentry); /* String operations - declarations for stub.c */ char *strreplace(const char *str, char old, char new); -/* strtomem_pad - copy string with padding (Linux kernel macro) */ -#define strtomem_pad(dest, src, pad) do { \ - const char *__src = (src); \ - size_t __len = strlen(__src); \ - if (__len >= sizeof(dest)) { \ - memcpy((dest), __src, sizeof(dest)); \ - } else { \ - memcpy((dest), __src, __len); \ - memset((char *)(dest) + __len, (pad), sizeof(dest) - __len); \ - } \ -} while (0) - /* Ratelimit - declaration for stub.c */ void ratelimit_state_init(void *rs, int interval, int burst); diff --git a/fs/ext4l/file.c b/fs/ext4l/file.c index b4127dbe913..8cbc8c5f785 100644 --- a/fs/ext4l/file.c +++ b/fs/ext4l/file.c @@ -119,7 +119,8 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) } #endif -static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to) +static ssize_t __maybe_unused ext4_file_read_iter(struct kiocb *iocb, + struct iov_iter *to) { struct inode *inode = file_inode(iocb->ki_filp); @@ -139,9 +140,11 @@ static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to) return generic_file_read_iter(iocb, to); } -static ssize_t ext4_file_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, - size_t len, unsigned int flags) +static ssize_t __maybe_unused ext4_file_splice_read(struct file *in, + loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, + unsigned int flags) { struct inode *inode = file_inode(in); @@ -682,7 +685,7 @@ out: } #endif -static ssize_t +static ssize_t __maybe_unused ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { int ret; @@ -796,7 +799,7 @@ static const struct vm_operations_struct ext4_file_vm_ops = { .page_mkwrite = ext4_page_mkwrite, }; -static int ext4_file_mmap_prepare(struct vm_area_desc *desc) +static int __maybe_unused ext4_file_mmap_prepare(struct vm_area_desc *desc) { int ret; struct file *file = desc->file; diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 4dac514340c..2c15ffce5b1 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -429,8 +429,8 @@ int ext4_find_inline_data_nolock(struct inode *inode) char ext4_dir_inode_operations; /* ext4_dir_operations is now in dir.c */ char ext4_special_inode_operations; -char ext4_symlink_inode_operations; -char ext4_fast_symlink_inode_operations; +/* ext4_symlink_inode_operations is now in symlink.c */ +/* ext4_fast_symlink_inode_operations is now in symlink.c */ /* ext4_update_dynamic_rev is now in super.c */ @@ -485,6 +485,12 @@ void jbd2_journal_init_jbd_inode(void *jinode, struct inode *inode) { } +/* symlink.c stub */ +void *ext4_read_inline_link(struct inode *inode) +{ + return ERR_PTR(-EOPNOTSUPP); +} + /* * Stubs for dir.c */ @@ -870,10 +876,7 @@ int ext4_register_sysfs(void *sb) return 0; } -/* dentry put */ -void dput(void *dentry) -{ -} +/* dput - now provided as macro in ext4_uboot.h */ /* timer_delete_sync is now a macro in linux/timer.h */ diff --git a/fs/ext4l/symlink.c b/fs/ext4l/symlink.c index 645240cc022..2e4d0942a3b 100644 --- a/fs/ext4l/symlink.c +++ b/fs/ext4l/symlink.c @@ -18,8 +18,7 @@ * ext4 symlink handling code */ -#include <linux/fs.h> -#include <linux/namei.h> +#include "ext4_uboot.h" #include "ext4.h" #include "xattr.h" @@ -65,9 +64,9 @@ static int ext4_encrypted_symlink_getattr(struct mnt_idmap *idmap, return fscrypt_symlink_getattr(path, stat); } -static void ext4_free_link(void *bh) +static void ext4_free_link(const void *bh) { - brelse(bh); + brelse((struct buffer_head *)bh); } static const char *ext4_get_link(struct dentry *dentry, struct inode *inode, -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add directory name operations (lookup, create, link, unlink, symlink, mkdir, rmdir, mknod, rename, tmpfile) to the ext4l filesystem. Add stubs for: - fscrypt name operations (match, prepare symlink/link/rename) - Dentry operations (d_splice_alias, d_obtain_alias, d_instantiate, etc) - Fast commit tracking functions - Inline directory functions - Fileattr get/set Extend inode_operations struct with directory operation members. Add permission mode constants (S_IRWXUGO) and rename flags. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 70 +++++++++++++++++++++++++++- fs/ext4l/namei.c | 15 +----- fs/ext4l/stub.c | 105 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 162 insertions(+), 30 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index fe6d9ccafe8..363cd913336 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -7,6 +7,6 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ - indirect.o inode.o super.o symlink.o \ + indirect.o inode.o namei.o super.o symlink.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 83a714f78a0..c8c8b3c702d 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -124,6 +124,7 @@ typedef struct { unsigned int val; } kprojid_t; #define make_kprojid(ns, id) ((kprojid_t){ .val = (id) }) #define from_kprojid(ns, kprojid) ((kprojid).val) +#define projid_eq(a, b) ((a).val == (b).val) /* kobject - stub */ struct kobject { @@ -396,7 +397,7 @@ extern struct user_namespace init_user_ns; #define insert_inode_locked(inode) (0) #define unlock_new_inode(inode) do { } while (0) #define clear_nlink(inode) do { } while (0) -#define IS_DIRSYNC(inode) (0) +#define IS_DIRSYNC(inode) ({ (void)(inode); 0; }) /* fscrypt stubs */ #define fscrypt_prepare_new_inode(dir, i, e) ({ (void)(dir); (void)(i); (void)(e); 0; }) @@ -548,6 +549,7 @@ struct dentry { struct qstr d_name; struct inode *d_inode; struct super_block *d_sb; + struct dentry *d_parent; }; /* vm_fault_t - stub */ @@ -681,6 +683,18 @@ static inline int bdev_read_only(struct block_device *bdev) #define S_CASEFOLD 128 #define S_VERITY 256 +/* Permission mode constants */ +#define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) + +/* Whiteout mode for overlayfs */ +#define WHITEOUT_DEV 0 +#define WHITEOUT_MODE 0 + +/* Rename flags */ +#define RENAME_NOREPLACE (1 << 0) +#define RENAME_EXCHANGE (1 << 1) +#define RENAME_WHITEOUT (1 << 2) + /* Inode dirty state flags */ #define I_DIRTY_TIME (1 << 3) @@ -851,6 +865,9 @@ static inline void simple_inode_init_ts(struct inode *inode) #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); + /* * Hash info structure - defined in ext4.h. * Only defined here for files that don't include ext4.h (like hash.c) @@ -1036,6 +1053,10 @@ static inline vm_fault_t filemap_map_pages(struct vm_fault *vmf, /* IS_SYNC macro */ #define IS_SYNC(inode) (0) +/* Case-folding stubs - not supported in U-Boot */ +#define sb_no_casefold_compat_fallback(sb) ({ (void)(sb); 1; }) +#define generic_ci_validate_strict_name(d, n) ({ (void)(d); (void)(n); 1; }) + /* in_range helper - check if value is in range [start, start+len) */ static inline int in_range(unsigned long val, unsigned long start, unsigned long len) @@ -1310,11 +1331,21 @@ typedef unsigned int projid_t; #define trace_ext4_journalled_write_end(...) do { } while (0) #define trace_ext4_sync_file_enter(...) do { } while (0) #define trace_ext4_sync_file_exit(...) do { } while (0) +#define trace_ext4_unlink_enter(...) do { } while (0) +#define trace_ext4_unlink_exit(...) do { } while (0) /* 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) ({ (void)(i); (void)(d); (struct dentry *)NULL; }) +#define d_obtain_alias(i) ({ (void)(i); (struct dentry *)NULL; }) +#define d_instantiate_new(d, i) do { (void)(d); (void)(i); } while (0) +#define d_instantiate(d, i) do { (void)(d); (void)(i); } while (0) +#define d_tmpfile(f, i) do { (void)(f); (void)(i); } while (0) +#define d_invalidate(d) do { (void)(d); } while (0) +#define finish_open_simple(f, e) (e) +#define ihold(i) do { (void)(i); } while (0) /* Sync operations - stubs */ #define sync_mapping_buffers(m) ({ (void)(m); 0; }) @@ -1435,6 +1466,22 @@ static inline char *d_path(const struct path *path, char *buf, int buflen) #define fscrypt_limit_io_blocks(i, lb, l) (l) #define fscrypt_prepare_setattr(d, a) ({ (void)(d); (void)(a); 0; }) #define fscrypt_dio_supported(i) (1) +#define fscrypt_match_name(f, n, l) ({ (void)(f); (void)(n); (void)(l); 1; }) +#define fscrypt_has_permitted_context(p, c) ({ (void)(p); (void)(c); 1; }) +#define fscrypt_is_nokey_name(d) ({ (void)(d); 0; }) +#define fscrypt_prepare_symlink(d, s, l, m, dl) ({ (void)(d); (void)(s); (void)(l); (void)(m); (void)(dl); 0; }) +#define fscrypt_encrypt_symlink(i, s, l, d) ({ (void)(i); (void)(s); (void)(l); (void)(d); 0; }) +#define fscrypt_prepare_link(o, d, n) ({ (void)(o); (void)(d); (void)(n); 0; }) +#define fscrypt_prepare_rename(od, ode, nd, nde, f) ({ (void)(od); (void)(ode); (void)(nd); (void)(nde); (void)(f); 0; }) + +/* fscrypt_name - stub structure for encrypted filenames */ +struct fscrypt_name { + const struct qstr *usr_fname; + struct fscrypt_str disk_name; + u32 hash; + u32 minor_hash; + bool is_nokey_name; +}; /* fsverity stubs */ #define fsverity_prepare_setattr(d, a) ({ (void)(d); (void)(a); 0; }) @@ -1511,6 +1558,8 @@ static inline unsigned int i_gid_read(const struct inode *inode) /* Inode allocation/state operations */ #define iget_locked(sb, ino) ((struct inode *)NULL) #define set_nlink(i, n) do { (i)->i_nlink = (n); } while (0) +#define inc_nlink(i) do { (i)->i_nlink++; } while (0) +#define drop_nlink(i) do { (i)->i_nlink--; } while (0) #define inode_set_cached_link(i, l, len) do { } while (0) #define init_special_inode(i, m, d) do { } while (0) #define make_bad_inode(i) do { } while (0) @@ -1612,8 +1661,10 @@ static inline void nd_terminate_link(void *name, loff_t len, int maxlen) /* inode_operations - for file and directory operations */ struct inode_operations { + /* Symlink operations */ const char *(*get_link)(struct dentry *, struct inode *, struct delayed_call *); + /* Common operations */ int (*getattr)(struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); ssize_t (*listxattr)(struct dentry *, char *, size_t); @@ -1625,6 +1676,23 @@ struct inode_operations { int (*fileattr_get)(struct dentry *, struct file_kattr *); int (*fileattr_set)(struct mnt_idmap *, struct dentry *, struct file_kattr *); + /* Directory operations */ + struct dentry *(*lookup)(struct inode *, struct dentry *, unsigned int); + int (*create)(struct mnt_idmap *, struct inode *, struct dentry *, + umode_t, bool); + int (*link)(struct dentry *, struct inode *, struct dentry *); + int (*unlink)(struct inode *, struct dentry *); + int (*symlink)(struct mnt_idmap *, struct inode *, struct dentry *, + const char *); + struct dentry *(*mkdir)(struct mnt_idmap *, struct inode *, + struct dentry *, umode_t); + int (*rmdir)(struct inode *, struct dentry *); + int (*mknod)(struct mnt_idmap *, struct inode *, struct dentry *, + umode_t, dev_t); + int (*rename)(struct mnt_idmap *, struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); + int (*tmpfile)(struct mnt_idmap *, struct inode *, struct file *, + umode_t); }; /* file open helper */ diff --git a/fs/ext4l/namei.c b/fs/ext4l/namei.c index 2cd36f59c9e..7ef20d02235 100644 --- a/fs/ext4l/namei.c +++ b/fs/ext4l/namei.c @@ -25,24 +25,11 @@ * Theodore Ts'o, 2002 */ -#include <linux/fs.h> -#include <linux/pagemap.h> -#include <linux/time.h> -#include <linux/fcntl.h> -#include <linux/stat.h> -#include <linux/string.h> -#include <linux/quotaops.h> -#include <linux/buffer_head.h> -#include <linux/bio.h> -#include <linux/iversion.h> -#include <linux/unicode.h> +#include "ext4_uboot.h" #include "ext4.h" #include "ext4_jbd2.h" - #include "xattr.h" #include "acl.h" - -#include <trace/events/ext4.h> /* * define how far ahead to read directories while searching them. */ diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 2c15ffce5b1..af6efa892b5 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -426,9 +426,9 @@ int ext4_find_inline_data_nolock(struct inode *inode) /* File and inode operations symbols */ /* ext4_file_inode_operations is now in file.c */ /* ext4_file_operations is now in file.c */ -char ext4_dir_inode_operations; +/* ext4_dir_inode_operations is now in namei.c */ /* ext4_dir_operations is now in dir.c */ -char ext4_special_inode_operations; +/* ext4_special_inode_operations is now in namei.c */ /* ext4_symlink_inode_operations is now in symlink.c */ /* ext4_fast_symlink_inode_operations is now in symlink.c */ @@ -503,24 +503,105 @@ ssize_t generic_read_dir(struct file *f, char *buf, size_t count, loff_t *ppos) /* ext4_llseek is now in file.c */ -int ext4_htree_fill_tree(struct file *dir_file, unsigned long long pos, - unsigned long long start_hash, - unsigned long long start_minor_hash, - unsigned long long *next_hash) +/* ext4_htree_fill_tree is now in namei.c */ + +int ext4_read_inline_dir(struct file *file, void *ctx, void *f_pos) { return 0; } -int ext4_read_inline_dir(struct file *file, void *ctx, void *f_pos) +struct buffer_head *ext4_find_inline_entry(struct inode *dir, void *fname, + void *res_dir, int *has_inline_data) +{ + *has_inline_data = 0; + return NULL; +} + +int ext4_try_add_inline_entry(void *handle, void *fname, void *dentry) +{ + return -ENOENT; +} + +int ext4_delete_inline_entry(void *handle, struct inode *dir, + void *de_del, struct buffer_head *bh, + int *has_inline_data) +{ + *has_inline_data = 0; + return -ENOENT; +} + +void ext4_update_final_de(void *de, int de_len, int new_de_len) { - return 0; } -int ext4_dirblock_csum_verify(struct inode *inode, struct buffer_head *bh) +int ext4_try_create_inline_dir(void *handle, struct inode *parent, + struct inode *inode) { + return -ENOENT; +} + +int empty_inline_dir(struct inode *dir, int *has_inline_data) +{ + *has_inline_data = 0; return 1; } +/* Inline dir stubs */ +int ext4_get_first_inline_block(struct inode *inode, void **de, + int *inline_size) +{ + return 0; +} + +int ext4_inlinedir_to_tree(struct file *dir, struct inode *inode, + unsigned long long start_hash, + unsigned long long *next_hash, + int has_inline_data) +{ + return 0; +} + +/* Fast commit stubs */ +void ext4_fc_track_unlink(void *handle, struct dentry *dentry) +{ +} + +void ext4_fc_track_link(void *handle, struct dentry *dentry) +{ +} + +void ext4_fc_track_create(void *handle, struct dentry *dentry) +{ +} + +void __ext4_fc_track_link(void *handle, struct inode *inode, + struct dentry *dentry) +{ +} + +void __ext4_fc_track_unlink(void *handle, struct inode *inode, + struct dentry *dentry) +{ +} + +void __ext4_fc_track_create(void *handle, struct inode *inode, + struct dentry *dentry) +{ +} + +/* fileattr stubs */ +int ext4_fileattr_get(struct dentry *dentry, void *fa) +{ + return 0; +} + +int ext4_fileattr_set(void *idmap, struct dentry *dentry, void *fa) +{ + return 0; +} + +/* ext4_dirblock_csum_verify is now in namei.c */ + /* ext4_ioctl is now in super.c */ /* ext4_sync_file is now in fsync.c */ @@ -880,11 +961,7 @@ int ext4_register_sysfs(void *sb) /* timer_delete_sync is now a macro in linux/timer.h */ -/* Get parent */ -void *ext4_get_parent(void *dentry) -{ - return (void *)-ESTALE; -} +/* ext4_get_parent is now in namei.c */ /* fsnotify */ void fsnotify_sb_error(struct super_block *sb, struct inode *inode, int error) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the ext4 extended attributes core implementation file to the build. Add stubs and definitions to ext4_uboot.h: - inode_get_ctime_sec, inode_get_mtime_sec, inode_set_ctime, inode_set_atime, inode_set_mtime functions - WARN_ONCE, pr_warn_once macros - lockdep_assert_held_read stub - struct mb_cache, struct mb_cache_entry and mb_cache_* function stubs - xattr_handler_can_list, xattr_prefix stubs - I_MUTEX_* constants and inode_lock_nested stub - PF_MEMALLOC_NOFS constant - struct mnt_idmap definition and nop_mnt_idmap declaration - kvmalloc macro - dquot_alloc_space_nodirty, dquot_free_space_nodirty, dquot_alloc_block, dquot_free_block declarations Add stub implementations: - nop_mnt_idmap global - dquot_* functions for quota operations Remove obsolete xattr stubs from stub.c that are now provided by xattr.c. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 91 ++++++++++++++++++++++++++++++++++++++++++- fs/ext4l/stub.c | 91 +++++++++++++------------------------------ fs/ext4l/xattr.c | 8 +--- 4 files changed, 120 insertions(+), 72 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 363cd913336..efda4ee18b5 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -7,6 +7,6 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ - indirect.o inode.o namei.o super.o symlink.o \ + indirect.o inode.o namei.o super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index c8c8b3c702d..052067981cd 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -605,7 +605,10 @@ typedef void bh_end_io_t(struct buffer_head *bh, int uptodate); #define DT_WHT 14 /* mnt_idmap - stub */ -struct mnt_idmap; +struct mnt_idmap { + int dummy; +}; +extern struct mnt_idmap nop_mnt_idmap; /* fstrim_range - stub */ struct fstrim_range { @@ -854,6 +857,34 @@ static inline time_t inode_get_atime_sec(const struct inode *inode) return inode->i_atime.tv_sec; } +static inline time_t inode_get_ctime_sec(const struct inode *inode) +{ + return inode->i_ctime.tv_sec; +} + +static inline time_t inode_get_mtime_sec(const struct inode *inode) +{ + return inode->i_mtime.tv_sec; +} + +static inline void inode_set_ctime(struct inode *inode, time_t sec, long nsec) +{ + inode->i_ctime.tv_sec = sec; + inode->i_ctime.tv_nsec = nsec; +} + +static inline void inode_set_atime(struct inode *inode, time_t sec, long nsec) +{ + inode->i_atime.tv_sec = sec; + inode->i_atime.tv_nsec = nsec; +} + +static inline void inode_set_mtime(struct inode *inode, time_t sec, long nsec) +{ + inode->i_mtime.tv_sec = sec; + inode->i_mtime.tv_nsec = nsec; +} + static inline void simple_inode_init_ts(struct inode *inode) { struct timespec64 ts = { .tv_sec = 0, .tv_nsec = 0 }; @@ -933,6 +964,11 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir, /* Warning macros - stubs */ #define WARN_ON_ONCE(cond) ({ (void)(cond); 0; }) #define WARN_ON(cond) ({ (void)(cond); 0; }) +#define WARN_ONCE(cond, fmt, ...) ({ (void)(cond); 0; }) +#define pr_warn_once(fmt, ...) do { } while (0) + +/* lockdep stubs */ +#define lockdep_assert_held_read(l) do { (void)(l); } while (0) /* strtomem_pad - copy string to fixed-size buffer with padding */ #define strtomem_pad(dest, src, pad) do { \ @@ -1048,7 +1084,7 @@ static inline vm_fault_t filemap_map_pages(struct vm_fault *vmf, #define inode_newsize_ok(i, s) ({ (void)(i); (void)(s); 0; }) #define inode_set_ctime_current(i) ({ (void)(i); (struct timespec64){}; }) #define inode_set_mtime_to_ts(i, ts) ({ (void)(i); (ts); }) -#define i_blocksize(i) (1UL << (i)->i_blkbits) +#define i_blocksize(i) (1U << (i)->i_blkbits) /* IS_SYNC macro */ #define IS_SYNC(inode) (0) @@ -2172,6 +2208,7 @@ void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, /* Memory allocation - declarations for stub.c */ void *kvzalloc(size_t size, gfp_t flags); +#define kvmalloc(size, flags) kvzalloc(size, flags) unsigned long roundup_pow_of_two(unsigned long n); /* Atomic operations - declarations for stub.c */ @@ -2229,6 +2266,52 @@ void set_task_ioprio(void *task, int ioprio); #define super_set_uuid(sb, uuid, len) do { } while (0) #define super_set_sysfs_name_bdev(sb) do { } while (0) +/* + * mb_cache - metadata block cache stubs for xattr.c + * Not supported in U-Boot - xattr caching disabled + */ +struct mb_cache { + int dummy; +}; + +struct mb_cache_entry { + u64 e_value; + unsigned long e_flags; +}; + +/* MB cache flags */ +#define MBE_REUSABLE_B 0 + +#define mb_cache_create(bits) ((struct mb_cache *)NULL) +#define mb_cache_destroy(cache) do { (void)(cache); } while (0) +#define mb_cache_entry_find_first(c, h) ((struct mb_cache_entry *)NULL) +#define mb_cache_entry_find_next(c, e) ((struct mb_cache_entry *)NULL) +#define mb_cache_entry_delete_or_get(c, k, v) ((struct mb_cache_entry *)NULL) +#define mb_cache_entry_get(c, k, v) ((struct mb_cache_entry *)NULL) +#define mb_cache_entry_put(c, e) do { (void)(c); (void)(e); } while (0) +#define mb_cache_entry_create(c, f, k, v, r) ({ (void)(c); (void)(f); (void)(k); (void)(v); (void)(r); 0; }) +#define mb_cache_entry_delete(c, k, v) do { (void)(c); (void)(k); (void)(v); } while (0) +#define mb_cache_entry_touch(c, e) do { (void)(c); (void)(e); } while (0) +#define mb_cache_entry_wait_unused(e) do { (void)(e); } while (0) + +/* xattr helper stubs for xattr.c */ +#define xattr_handler_can_list(h, d) ({ (void)(h); (void)(d); 0; }) +#define xattr_prefix(h) ({ (void)(h); (const char *)NULL; }) + +/* Inode lock mutex classes */ +#define I_MUTEX_XATTR 5 +#define I_MUTEX_CHILD 4 +#define I_MUTEX_PARENT 3 +#define I_MUTEX_NORMAL 2 + +/* Nested inode locking stub */ +#define inode_lock_nested(i, c) do { (void)(i); (void)(c); } while (0) + +/* Process flags */ +#ifndef PF_MEMALLOC_NOFS +#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); @@ -2249,6 +2332,10 @@ int sync_filesystem(void *sb); /* Quota - declaration for stub.c */ int dquot_suspend(void *sb, int flags); +int dquot_alloc_space_nodirty(struct inode *inode, loff_t size); +void dquot_free_space_nodirty(struct inode *inode, loff_t size); +int dquot_alloc_block(struct inode *inode, loff_t nr); +void dquot_free_block(struct inode *inode, loff_t nr); /* Block device file operations - stubs */ #define set_blocksize(f, size) ({ (void)(f); (void)(size); 0; }) diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index af6efa892b5..4dbc055bb72 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -214,37 +214,8 @@ void ext4_fc_record_regions(struct super_block *sb, int ino, /* ext4_read_bh is now in super.c */ /* ext4_sb_bread_nofail is now in super.c */ -/* - * Stubs for ialloc.c - xattr functions - */ -int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode, - struct buffer_head *block_bh, size_t value_len, - bool is_create) -{ - return 0; -} - /* ext4_init_security stub is provided by xattr.h */ - -/* - * Stubs for xattr_trusted.c - */ -int ext4_xattr_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) -{ - return -1; -} - -int ext4_xattr_set(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len, int flags) -{ - return -1; -} - -ssize_t ext4_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) -{ - return 0; -} +/* xattr functions are now in xattr.c */ /* * Stubs for orphan.c @@ -284,17 +255,7 @@ int ext4_readpage_inline(struct inode *inode, void *folio) return 0; } -/* Xattr */ -int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, - void *raw_inode, void *handle) -{ - return 0; -} - -void ext4_evict_ea_inode(struct inode *inode) -{ -} - +/* Xattr functions are now in xattr.c */ /* More JBD2 stubs */ int jbd2_journal_inode_ranged_write(void *handle, struct inode *inode, @@ -410,12 +371,7 @@ int ext4_inline_data_iomap(struct inode *inode, void *iomap) } -/* xattr */ -int __xattr_check_inode(struct inode *inode, void *entry, void *end, - unsigned int size, int check_block) -{ - return 0; -} +/* __xattr_check_inode is now in xattr.c */ int ext4_find_inline_data_nolock(struct inode *inode) { @@ -462,16 +418,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned int len return copied; } -/* xattr stubs for inode.c */ -int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, - void **array, int extra_credits) -{ - return 0; -} - -void ext4_xattr_inode_array_free(void *array) -{ -} +/* xattr stubs are now in xattr.c */ /* JBD2 stubs for inode.c */ struct kmem_cache *jbd2_inode_cache; @@ -844,10 +791,7 @@ struct block_device *file_bdev(struct file *file) return NULL; } -/* xattr cache */ -void ext4_xattr_destroy_cache(void *cache) -{ -} +/* xattr cache is now in xattr.c */ /* kobject */ void kobject_put(struct kobject *kobj) @@ -899,8 +843,7 @@ u64 sb_bdev_nr_blocks(struct super_block *sb) /* bgl_lock_init is now a macro in ext4_uboot.h */ -/* xattr handlers */ -const void *ext4_xattr_handlers[] = { NULL }; +/* xattr handlers are now in xattr.c */ /* super_set_uuid is now a macro in ext4_uboot.h */ /* super_set_sysfs_name_bdev is now a macro in ext4_uboot.h */ @@ -1005,3 +948,25 @@ void jbd2_journal_abort(void *journal, int error) void jbd2_journal_release_jbd_inode(void *journal, void *jinode) { } + +/* nop_mnt_idmap - no-op mount ID map for xattr.c */ +struct mnt_idmap nop_mnt_idmap; + +/* Quota stubs for xattr.c */ +int dquot_alloc_space_nodirty(struct inode *inode, loff_t size) +{ + return 0; +} + +void dquot_free_space_nodirty(struct inode *inode, loff_t size) +{ +} + +int dquot_alloc_block(struct inode *inode, loff_t nr) +{ + return 0; +} + +void dquot_free_block(struct inode *inode, loff_t nr) +{ +} diff --git a/fs/ext4l/xattr.c b/fs/ext4l/xattr.c index ce7253b3f54..bd89822a682 100644 --- a/fs/ext4l/xattr.c +++ b/fs/ext4l/xattr.c @@ -51,12 +51,8 @@ * by the buffer lock. */ -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/mbcache.h> -#include <linux/quotaops.h> -#include <linux/iversion.h> +#include "ext4_uboot.h" + #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the ext4 inline data implementation file to the build. Add stubs to ext4_uboot.h: - FGP_WRITEBEGIN flag (combined from FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE) - kmap_local_folio, kunmap_local for memory mapping - folio_zero_tail, folio_zero_segment for folio zeroing - mapping_gfp_mask for address space GFP mask Remove obsolete inline data stubs from stub.c that are now provided by inline.c. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 12 +++++ fs/ext4l/inline.c | 6 +-- fs/ext4l/stub.c | 119 +++--------------------------------------- 4 files changed, 21 insertions(+), 118 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index efda4ee18b5..80797722fe2 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -7,6 +7,6 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ - indirect.o inode.o namei.o super.o symlink.o xattr.o \ + indirect.o inline.o inode.o namei.o super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 052067981cd..fc8a2f98bdb 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1309,6 +1309,18 @@ static inline int generic_error_remove_folio(struct address_space *mapping, #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) ({ (void)(folio); (void)(off); (void *)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; }) /* __filemap_get_folio stub */ static inline struct folio *__filemap_get_folio(struct address_space *mapping, diff --git a/fs/ext4l/inline.c b/fs/ext4l/inline.c index 1b094a4f386..1e5dd731388 100644 --- a/fs/ext4l/inline.c +++ b/fs/ext4l/inline.c @@ -4,11 +4,7 @@ * Written by Tao Ma <boyu.mt@taobao.com> */ -#include <linux/iomap.h> -#include <linux/fiemap.h> -#include <linux/namei.h> -#include <linux/iversion.h> -#include <linux/sched/mm.h> +#include "ext4_uboot.h" #include "ext4_jbd2.h" #include "ext4.h" diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 4dbc055bb72..e5cb69be5b1 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -183,11 +183,7 @@ void ext4_discard_preallocations(struct inode *inode, unsigned int needed) } /* ext4_is_pending is now in extents_status.c */ - -int ext4_convert_inline_data(struct inode *inode) -{ - return 0; -} +/* ext4_convert_inline_data is now in inline.c */ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, void *handle) @@ -250,10 +246,7 @@ int ext4_mpage_readpages(void *mapping, void *rac, void *folio) return 0; } -int ext4_readpage_inline(struct inode *inode, void *folio) -{ - return 0; -} +/* ext4_readpage_inline is now in inline.c */ /* Xattr functions are now in xattr.c */ @@ -275,11 +268,7 @@ int ext4_fc_commit(void *journal, unsigned int tid) /* ext4_force_commit is now in super.c */ -/* Inline data */ -int ext4_destroy_inline_data(void *handle, struct inode *inode) -{ - return 0; -} +/* Inline data is now in inline.c */ /* I/O submit */ void ext4_io_submit_init(void *io, void *wbc) @@ -364,21 +353,10 @@ int jbd2_journal_inode_ranged_wait(void *handle, struct inode *inode, return 0; } -/* Inline data */ -int ext4_inline_data_iomap(struct inode *inode, void *iomap) -{ - return 0; -} - +/* Inline data functions are now in inline.c */ /* __xattr_check_inode is now in xattr.c */ -int ext4_find_inline_data_nolock(struct inode *inode) -{ - return 0; -} - - /* File and inode operations symbols */ /* ext4_file_inode_operations is now in file.c */ /* ext4_file_operations is now in file.c */ @@ -391,32 +369,7 @@ int ext4_find_inline_data_nolock(struct inode *inode) /* ext4_update_dynamic_rev is now in super.c */ -/* Inline data */ -int ext4_inline_data_truncate(struct inode *inode, int *has_inline) -{ - *has_inline = 0; - return 0; -} - -int ext4_try_to_write_inline_data(struct address_space *mapping, - struct inode *inode, loff_t pos, - unsigned int len, struct folio **foliop) -{ - return 0; -} - -int ext4_generic_write_inline_data(struct address_space *mapping, - struct inode *inode, loff_t pos, - unsigned int len, struct folio **foliop) -{ - return 0; -} - -int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned int len, - unsigned int copied, struct folio *folio) -{ - return copied; -} +/* Inline data stubs are now in inline.c */ /* xattr stubs are now in xattr.c */ @@ -432,11 +385,7 @@ void jbd2_journal_init_jbd_inode(void *jinode, struct inode *inode) { } -/* symlink.c stub */ -void *ext4_read_inline_link(struct inode *inode) -{ - return ERR_PTR(-EOPNOTSUPP); -} +/* ext4_read_inline_link is now in inline.c */ /* * Stubs for dir.c @@ -452,61 +401,7 @@ ssize_t generic_read_dir(struct file *f, char *buf, size_t count, loff_t *ppos) /* ext4_htree_fill_tree is now in namei.c */ -int ext4_read_inline_dir(struct file *file, void *ctx, void *f_pos) -{ - return 0; -} - -struct buffer_head *ext4_find_inline_entry(struct inode *dir, void *fname, - void *res_dir, int *has_inline_data) -{ - *has_inline_data = 0; - return NULL; -} - -int ext4_try_add_inline_entry(void *handle, void *fname, void *dentry) -{ - return -ENOENT; -} - -int ext4_delete_inline_entry(void *handle, struct inode *dir, - void *de_del, struct buffer_head *bh, - int *has_inline_data) -{ - *has_inline_data = 0; - return -ENOENT; -} - -void ext4_update_final_de(void *de, int de_len, int new_de_len) -{ -} - -int ext4_try_create_inline_dir(void *handle, struct inode *parent, - struct inode *inode) -{ - return -ENOENT; -} - -int empty_inline_dir(struct inode *dir, int *has_inline_data) -{ - *has_inline_data = 0; - return 1; -} - -/* Inline dir stubs */ -int ext4_get_first_inline_block(struct inode *inode, void **de, - int *inline_size) -{ - return 0; -} - -int ext4_inlinedir_to_tree(struct file *dir, struct inode *inode, - unsigned long long start_hash, - unsigned long long *next_hash, - int has_inline_data) -{ - return 0; -} +/* Inline dir stubs are now in inline.c */ /* Fast commit stubs */ void ext4_fc_track_unlink(void *handle, struct dentry *dentry) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the multiblock allocator (mballoc.c) to the build. This implements the ext4 block allocation routines. Stubs added for: - Per-CPU operations (simplified to single-threaded) - XArray operations - RCU list operations - Block device properties - Various trace functions - Atomic operations (atomic_sub, atomic64_sub, atomic_inc_return) - WARN_RATELIMIT, folio_get, array_index_nospec - seq_operations for procfs - DEFINE_RAW_FLEX macro Remove stub functions that are now properly implemented: - ext4_mb_new_blocks - ext4_free_blocks - ext4_discard_preallocations - ext4_mb_mark_bb Add ext4_fc_replay_check_excluded stub for fast commit replay. Add file member to struct seq_file for procfs compatibility. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 3 +- fs/ext4l/ext4_uboot.h | 203 +++++++++++++++++++++++++++++++++++++- fs/ext4l/mballoc.c | 10 +- fs/ext4l/stub.c | 31 ++---- include/linux/seq_file.h | 1 + include/linux/slab.h | 2 +- include/linux/workqueue.h | 4 + 7 files changed, 222 insertions(+), 32 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 80797722fe2..dc3858165c3 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -7,6 +7,7 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ - indirect.o inline.o inode.o namei.o super.o symlink.o xattr.o \ + indirect.o inline.o inode.o mballoc.o \ + namei.o super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index fc8a2f98bdb..9ea3afdd798 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -1193,8 +1193,13 @@ static inline ktime_t ktime_sub(ktime_t a, ktime_t b) /* folio - memory page container stub */ struct folio { - struct address_space *mapping; + struct page *page; unsigned long index; + struct address_space *mapping; + unsigned long flags; + void *data; + struct buffer_head *private; + int _refcount; }; /* folio_batch - batch of folios */ @@ -2364,4 +2369,200 @@ void dquot_free_block(struct inode *inode, loff_t nr); #define dquot_resume(sb, type) do { (void)(sb); (void)(type); } while (0) #define sb_any_quota_suspended(sb) ({ (void)(sb); 0; }) +/* + * Stubs for mballoc.c + */ + +/* XArray stub structure */ +struct xarray { + int dummy; +}; + +/* Per-CPU stubs - U-Boot is single-threaded */ +#define DEFINE_PER_CPU(type, name) type name +#define per_cpu(var, cpu) (var) +#define per_cpu_ptr(ptr, cpu) (ptr) +#define this_cpu_inc(var) ((var)++) +#define this_cpu_read(var) (var) +#define for_each_possible_cpu(cpu) for ((cpu) = 0; (cpu) < 1; (cpu)++) +#define smp_processor_id() 0 + +/* 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) + +static inline void clear_bit_le(int nr, void *addr) +{ + unsigned char *p = (unsigned char *)addr + (nr >> 3); + + *p &= ~(1 << (nr & 7)); +} + +#define find_next_bit_le(addr, size, offset) \ + ext4_find_next_bit_le(addr, size, offset) + +static inline unsigned long ext4_find_next_bit_le(const void *addr, + unsigned long size, + unsigned long offset) +{ + const unsigned char *p = addr; + unsigned long bit; + + for (bit = offset; bit < size; bit++) { + if (p[bit >> 3] & (1 << (bit & 7))) + return bit; + } + return size; +} + +/* Atomic64 operations */ +#define atomic64_inc(v) do { (void)(v); } while (0) +#define atomic64_add(i, v) do { (void)(i); (void)(v); } while (0) + +/* 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) + +/* Trace stubs for mballoc.c */ +#define trace_ext4_mb_bitmap_load(sb, group) \ + do { (void)(sb); (void)(group); } while (0) +#define trace_ext4_mb_buddy_bitmap_load(sb, group) \ + do { (void)(sb); (void)(group); } while (0) +#define trace_ext4_mballoc_alloc(ac) \ + do { (void)(ac); } while (0) +#define trace_ext4_mballoc_prealloc(ac) \ + do { (void)(ac); } while (0) +#define trace_ext4_mballoc_discard(sb, inode, group, start, len) \ + do { (void)(sb); (void)(inode); (void)(group); (void)(start); (void)(len); } while (0) +#define trace_ext4_mballoc_free(sb, inode, group, start, len) \ + do { (void)(sb); (void)(inode); (void)(group); (void)(start); (void)(len); } while (0) +#define trace_ext4_mb_release_inode_pa(pa, block, count) \ + do { (void)(pa); (void)(block); (void)(count); } while (0) +#define trace_ext4_mb_release_group_pa(sb, pa) \ + do { (void)(sb); (void)(pa); } while (0) +#define trace_ext4_mb_new_inode_pa(ac, pa) \ + do { (void)(ac); (void)(pa); } while (0) +#define trace_ext4_mb_new_group_pa(ac, pa) \ + do { (void)(ac); (void)(pa); } while (0) + +/* sb_end_intwrite stub */ +#define sb_end_intwrite(sb) do { (void)(sb); } while (0) + +/* WARN_RATELIMIT - just evaluate condition, no warning in U-Boot */ +#define WARN_RATELIMIT(condition, ...) (condition) + +/* folio_get - increment folio refcount (no-op in U-Boot) */ +#define folio_get(f) do { (void)(f); } while (0) + +/* array_index_nospec - bounds checking without speculation (no-op in U-Boot) */ +#define array_index_nospec(index, size) (index) + +/* atomic_inc_return - increment and return new value */ +static inline int atomic_inc_return(atomic_t *v) +{ + return ++(v->counter); +} + +/* pde_data - proc dir entry data (not supported in U-Boot) */ +#define pde_data(inode) ((void *)NULL) + +/* seq_operations for procfs iteration */ +struct seq_operations { + void *(*start)(struct seq_file *m, loff_t *pos); + void (*stop)(struct seq_file *m, void *v); + void *(*next)(struct seq_file *m, void *v, loff_t *pos); + int (*show)(struct seq_file *m, void *v); +}; + +/* DEFINE_RAW_FLEX - define a flexible array struct on the stack (stubbed to NULL) */ +#define DEFINE_RAW_FLEX(type, name, member, count) \ + type *name = NULL + +/* Block layer constants */ +#define BLK_MAX_SEGMENT_SIZE 65536 + +/* order_base_2 - log2 rounded up */ +#define order_base_2(n) ilog2(roundup_pow_of_two(n)) + +/* num_possible_cpus - number of possible CPUs (always 1 in U-Boot) */ +#define num_possible_cpus() 1 + +/* Per-CPU allocation stubs */ +#define alloc_percpu(type) ((type *)kzalloc(sizeof(type), GFP_KERNEL)) +#define free_percpu(ptr) kfree(ptr) + +/* Block device properties */ +#define bdev_nonrot(bdev) ({ (void)(bdev); 0; }) + +/* Trace stub for discard */ +#define trace_ext4_discard_blocks(sb, blk, count) \ + do { (void)(sb); (void)(blk); (void)(count); } while (0) + +/* sb_issue_discard - issue discard request (no-op in U-Boot) */ +#define sb_issue_discard(sb, sector, nr_sects, gfp, flags) \ + ({ (void)(sb); (void)(sector); (void)(nr_sects); (void)(gfp); (void)(flags); 0; }) + +/* Atomic operations */ +#define atomic_sub(i, v) ((v)->counter -= (i)) +#define atomic64_sub(i, v) ((v)->counter -= (i)) +#define atomic_dec_and_test(v) (--((v)->counter) == 0) + +/* 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) +#define rcu_read_lock() do { } while (0) +#define rcu_read_unlock() do { } while (0) +#define synchronize_rcu() do { } while (0) +#define rcu_assign_pointer(p, v) ((p) = (v)) +#define rcu_dereference(p) (p) + +/* raw_cpu_ptr - get pointer to per-CPU data for current CPU */ +#define raw_cpu_ptr(ptr) (ptr) + +/* Scheduler stubs */ +#define schedule_timeout_uninterruptible(t) do { } while (0) +#define need_resched() (0) + +/* Trace stubs for mballoc.c */ +#define trace_ext4_discard_preallocations(inode, cnt) \ + do { (void)(inode); (void)(cnt); } while (0) +#define trace_ext4_mb_discard_preallocations(sb, needed) \ + do { (void)(sb); (void)(needed); } while (0) +#define trace_ext4_request_blocks(ar) \ + do { (void)(ar); } while (0) +#define trace_ext4_allocate_blocks(ar, block) \ + do { (void)(ar); (void)(block); } while (0) +#define trace_ext4_free_blocks(inode, block, count, flags) \ + do { (void)(inode); (void)(block); (void)(count); (void)(flags); } while (0) +#define trace_ext4_trim_extent(sb, group, start, count) \ + do { (void)(sb); (void)(group); (void)(start); (void)(count); } while (0) +#define trace_ext4_trim_all_free(sb, group, start, max) \ + do { (void)(sb); (void)(group); (void)(start); (void)(max); } while (0) + +/* Block device operations */ +#define sb_find_get_block_nonatomic(sb, block) \ + ({ (void)(sb); (void)(block); (struct buffer_head *)NULL; }) +#define bdev_discard_granularity(bdev) \ + ({ (void)(bdev); 0U; }) + #endif /* __EXT4_UBOOT_H__ */ diff --git a/fs/ext4l/mballoc.c b/fs/ext4l/mballoc.c index 9087183602e..b58d72dfd26 100644 --- a/fs/ext4l/mballoc.c +++ b/fs/ext4l/mballoc.c @@ -9,16 +9,10 @@ * mballoc.c contains the multiblocks allocation routines */ +#include "ext4_uboot.h" + #include "ext4_jbd2.h" #include "mballoc.h" -#include <linux/log2.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/nospec.h> -#include <linux/backing-dev.h> -#include <linux/freezer.h> -#include <trace/events/ext4.h> -#include <kunit/static_stub.h> /* * MUSTDO: diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index e5cb69be5b1..ca8a2bc0f91 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -118,11 +118,7 @@ int jbd2_trans_will_send_data_barrier(journal_t *journal, unsigned long tid) /* ext4_mark_group_bitmap_corrupted is now in super.c */ /* __ext4_warning is now in super.c */ -unsigned long long ext4_mb_new_blocks(void *handle, void *ar, int *errp) -{ - *errp = -1; - return 0; -} +/* ext4_mb_new_blocks is now in mballoc.c */ /* ext4_free_group_clusters is now in super.c */ /* ext4_clear_inode is now in super.c */ @@ -172,15 +168,9 @@ struct extent_status; /* ext4_remove_pending is now in extents_status.c */ -void ext4_free_blocks(void *handle, struct inode *inode, - struct buffer_head *bh, unsigned long long block, - unsigned long count, int flags) -{ -} +/* ext4_free_blocks is now in mballoc.c */ -void ext4_discard_preallocations(struct inode *inode, unsigned int needed) -{ -} +/* ext4_discard_preallocations is now in mballoc.c */ /* ext4_is_pending is now in extents_status.c */ /* ext4_convert_inline_data is now in inline.c */ @@ -196,10 +186,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, /* ext4_es_find_extent_range is now in extents_status.c */ -void ext4_mb_mark_bb(struct super_block *sb, unsigned long long block, - int len, int state) -{ -} +/* ext4_mb_mark_bb is now in mballoc.c */ void ext4_fc_record_regions(struct super_block *sb, int ino, unsigned long lblk, unsigned long long pblk, @@ -207,6 +194,11 @@ void ext4_fc_record_regions(struct super_block *sb, int ino, { } +int ext4_fc_replay_check_excluded(struct super_block *sb, unsigned long long blk) +{ + return 0; +} + /* ext4_read_bh is now in super.c */ /* ext4_sb_bread_nofail is now in super.c */ @@ -773,10 +765,7 @@ void atomic_add(int val, atomic_t *v) v->counter += val; } -void atomic64_add(s64 val, atomic64_t *v) -{ - v->counter += val; -} +/* atomic64_add is now a macro in ext4_uboot.h */ /* Discard */ unsigned int bdev_max_discard_sectors(struct block_device *bdev) diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index fb5dbf97708..5b6495d1003 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -9,6 +9,7 @@ struct seq_file { void *private; + struct file *file; }; #define seq_printf(m, fmt, ...) do { } while (0) diff --git a/include/linux/slab.h b/include/linux/slab.h index e83817cc7ff..2b374641534 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -90,7 +90,7 @@ struct kmem_cache { }; struct kmem_cache *get_mem(int element_sz); -#define kmem_cache_create(a, sz, c, d, e) ({ (void)(e); get_mem(sz); }) +#define kmem_cache_create(a, sz, c, d, e) ({ (void)(a); (void)(e); get_mem(sz); }) void *kmem_cache_alloc(struct kmem_cache *obj, gfp_t flag); static inline void *kmem_cache_zalloc(struct kmem_cache *obj, gfp_t flags) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 1952f62623c..66f61fa6e77 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -79,4 +79,8 @@ static inline void destroy_workqueue(struct workqueue_struct *wq) { } +/* System workqueues - all stubs in U-Boot */ +#define system_dfl_wq ((struct workqueue_struct *)1) +#define system_wq ((struct workqueue_struct *)1) + #endif /* _LINUX_WORKQUEUE_H */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the page I/O module (page-io.c) to the build. This implements ext4's asynchronous page writeback infrastructure. Stubs added for: - bio structure and related operations - folio_iter for bio iteration - refcount operations (mapped to atomic) - fscrypt bounce folio operations - folio writeback operations - writeback control operations - i_write_hint member to inode struct Remove stub functions now implemented in page-io.c: - ext4_io_submit_init, ext4_init_io_end - ext4_io_submit, ext4_put_io_end_defer - ext4_put_io_end, ext4_alloc_io_end_vec Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 99 +++++++++++++++++++++++++++++++++++++++++++ fs/ext4l/page-io.c | 15 +------ fs/ext4l/stub.c | 37 ++++------------ 4 files changed, 110 insertions(+), 43 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index dc3858165c3..506e76b959e 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -8,6 +8,6 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ indirect.o inline.o inode.o mballoc.o \ - namei.o super.o symlink.o xattr.o \ + namei.o page_io.o super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index 9ea3afdd798..c5895dc902a 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -834,6 +834,7 @@ struct inode { atomic_t i_writecount; /* Count of writers */ struct rw_semaphore i_rwsem; /* inode lock */ const char *i_link; /* Symlink target for fast symlinks */ + unsigned short i_write_hint; /* Write life time hint */ }; /* Inode time accessors */ @@ -1515,6 +1516,7 @@ static inline char *d_path(const struct path *path, char *buf, int buflen) /* fscrypt stubs - additional */ #define fscrypt_inode_uses_fs_layer_crypto(i) (0) #define fscrypt_decrypt_pagecache_blocks(f, l, o) ({ (void)(f); (void)(l); (void)(o); 0; }) +#define fscrypt_encrypt_pagecache_blocks(f, l, o, g) ({ (void)(f); (void)(l); (void)(o); (void)(g); (struct page *)NULL; }) #define fscrypt_zeroout_range(i, lb, pb, l) ({ (void)(i); (void)(lb); (void)(pb); (void)(l); 0; }) #define fscrypt_limit_io_blocks(i, lb, l) (l) #define fscrypt_prepare_setattr(d, a) ({ (void)(d); (void)(a); 0; }) @@ -2565,4 +2567,101 @@ struct seq_operations { #define bdev_discard_granularity(bdev) \ ({ (void)(bdev); 0U; }) +/* + * Stubs for page-io.c + */ + +/* 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 *); +}; + +/* 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 + +/* 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)) + +/* xchg - exchange value atomically */ +#define xchg(ptr, new) ({ typeof(*(ptr)) __old = *(ptr); *(ptr) = (new); __old; }) + +/* printk_ratelimited - just use regular printk */ +#define printk_ratelimited(fmt, ...) do { } while (0) + +/* 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 - increment atomic */ +#define atomic_inc(v) ((v)->counter++) + +/* GFP_NOIO - allocation without I/O */ +#define GFP_NOIO 0 + +/* fscrypt stubs for page-io.c */ +#define fscrypt_is_bounce_folio(f) ({ (void)(f); 0; }) +#define fscrypt_pagecache_folio(f) (f) +#define fscrypt_free_bounce_page(p) do { (void)(p); } while (0) +#define fscrypt_set_bio_crypt_ctx_bh(bio, bh, gfp) \ + do { (void)(bio); (void)(bh); (void)(gfp); } while (0) +#define fscrypt_mergeable_bio_bh(bio, bh) \ + ({ (void)(bio); (void)(bh); 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) +bool __folio_start_writeback(struct folio *folio, bool keep_write); + +/* writeback control stubs */ +#define wbc_init_bio(wbc, bio) do { (void)(wbc); (void)(bio); } while (0) +#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; }) + #endif /* __EXT4_UBOOT_H__ */ diff --git a/fs/ext4l/page-io.c b/fs/ext4l/page-io.c index 39abfeec5f3..657c6f4eedb 100644 --- a/fs/ext4l/page-io.c +++ b/fs/ext4l/page-io.c @@ -7,24 +7,11 @@ * Written by Theodore Ts'o, 2010. */ -#include <linux/fs.h> +#include "ext4_uboot.h" #include <linux/time.h> -#include <linux/highuid.h> -#include <linux/pagemap.h> -#include <linux/quotaops.h> #include <linux/string.h> -#include <linux/buffer_head.h> -#include <linux/writeback.h> -#include <linux/pagevec.h> #include <linux/mpage.h> -#include <linux/namei.h> -#include <linux/uio.h> -#include <linux/bio.h> -#include <linux/workqueue.h> #include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/sched/mm.h> #include "ext4_jbd2.h" #include "xattr.h" diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index ca8a2bc0f91..935e93f49f1 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -199,6 +199,14 @@ int ext4_fc_replay_check_excluded(struct super_block *sb, unsigned long long blk return 0; } +/* + * Stubs for page-io.c + */ +bool __folio_start_writeback(struct folio *folio, bool keep_write) +{ + return false; +} + /* ext4_read_bh is now in super.c */ /* ext4_sb_bread_nofail is now in super.c */ @@ -262,34 +270,7 @@ int ext4_fc_commit(void *journal, unsigned int tid) /* Inline data is now in inline.c */ -/* I/O submit */ -void ext4_io_submit_init(void *io, void *wbc) -{ -} - - -void *ext4_init_io_end(struct inode *inode, int gfp) -{ - return NULL; -} - -void ext4_io_submit(void *io) -{ -} - -void ext4_put_io_end_defer(void *io_end) -{ -} - -void ext4_put_io_end(void *io_end) -{ -} - -void *ext4_alloc_io_end_vec(void *io_end, unsigned long num) -{ - return NULL; -} - +/* I/O submit stubs are now in page-io.c */ /* JBD2 ordered truncate */ int jbd2_journal_begin_ordered_truncate(void *ji, loff_t new_size) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the readpage module (readpage.c) to the build. This implements ext4's page reading infrastructure for reading file data. Stubs added for: - mempool operations (mempool_t, mempool_alloc, etc.) - folio read operations (folio_end_read, folio_set_mappedtodisk) - fscrypt read operations (fscrypt_decrypt_bio, etc.) - fsverity operations (fsverity_verify_bio, etc.) - readahead operations (readahead_count, readahead_folio) - prefetchw and block_read_full_folio Remove ext4_mpage_readpages stub now implemented in readpage.c. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 3 ++- fs/ext4l/ext4_uboot.h | 40 ++++++++++++++++++++++++++++++++++++++++ fs/ext4l/readpage.c | 16 +--------------- fs/ext4l/stub.c | 6 +----- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 506e76b959e..3116ac3be39 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -8,6 +8,7 @@ obj-y := interface.o stub.o obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ extents_status.o file.o fsync.o hash.o ialloc.o \ indirect.o inline.o inode.o mballoc.o \ - namei.o page_io.o super.o symlink.o xattr.o \ + namei.o page-io.o readpage.o \ + super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ xattr_user.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index c5895dc902a..a6ffc91b7de 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -2664,4 +2664,44 @@ bool __folio_start_writeback(struct folio *folio, bool keep_write); #define bio_add_folio(bio, folio, len, off) \ ({ (void)(bio); (void)(folio); (void)(len); (void)(off); 1; }) +/* + * 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) + +/* folio read operations */ +#define folio_end_read(f, success) do { (void)(f); (void)(success); } while (0) +#define folio_set_mappedtodisk(f) do { (void)(f); } while (0) + +/* fscrypt stubs for readpage.c */ +#define fscrypt_decrypt_bio(bio) ({ (void)(bio); 0; }) +#define fscrypt_enqueue_decrypt_work(work) do { (void)(work); } while (0) +#define fscrypt_mergeable_bio(bio, inode, blk) \ + ({ (void)(bio); (void)(inode); (void)(blk); 1; }) +#define fscrypt_set_bio_crypt_ctx(bio, inode, blk, gfp) \ + do { (void)(bio); (void)(inode); (void)(blk); (void)(gfp); } while (0) + +/* fsverity stubs */ +#define fsverity_verify_bio(bio) do { (void)(bio); } while (0) +#define fsverity_enqueue_verify_work(work) do { (void)(work); } while (0) +#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; }) + +/* prefetch operations */ +#define prefetchw(addr) do { (void)(addr); } while (0) + +/* block read operations */ +#define block_read_full_folio(folio, get_block) \ + ({ (void)(folio); (void)(get_block); 0; }) + #endif /* __EXT4_UBOOT_H__ */ diff --git a/fs/ext4l/readpage.c b/fs/ext4l/readpage.c index f329daf6e5c..94361c01f08 100644 --- a/fs/ext4l/readpage.c +++ b/fs/ext4l/readpage.c @@ -28,21 +28,7 @@ * */ -#include <linux/kernel.h> -#include <linux/export.h> -#include <linux/mm.h> -#include <linux/kdev_t.h> -#include <linux/gfp.h> -#include <linux/bio.h> -#include <linux/fs.h> -#include <linux/buffer_head.h> -#include <linux/blkdev.h> -#include <linux/highmem.h> -#include <linux/prefetch.h> -#include <linux/mpage.h> -#include <linux/writeback.h> -#include <linux/backing-dev.h> -#include <linux/pagevec.h> +#include "ext4_uboot.h" #include "ext4.h" diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 935e93f49f1..87637ecbd8c 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -240,11 +240,7 @@ int jbd2_transaction_committed(void *journal, unsigned int tid) /* __ext4_warning_inode is now in super.c */ -/* Readahead */ -int ext4_mpage_readpages(void *mapping, void *rac, void *folio) -{ - return 0; -} +/* ext4_mpage_readpages is now in readpage.c */ /* ext4_readpage_inline is now in inline.c */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add the fast commit module (fast_commit.c) to the build. This implements ext4's fast commit journaling feature for improved performance. Stubs added for: - Wait bit operations (DEFINE_WAIT_BIT, bit_waitqueue, etc.) - Dentry name snapshot operations - Fast commit trace functions - JBD2 fast commit functions (jbd2_fc_get_buf, jbd2_fc_begin_commit, etc.) - Dentry allocation (d_alloc, d_drop) - get_current_ioprio, wake_up_bit - REQ_IDLE, REQ_PREFLUSH block I/O flags Move name_snapshot struct definition after qstr is defined. Remove fast commit stub functions now implemented in fast_commit.c. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Makefile | 2 +- fs/ext4l/ext4_uboot.h | 82 ++++++++++++++++++++++++--- fs/ext4l/fast_commit.c | 6 +- fs/ext4l/stub.c | 118 +++++++++++++++++++-------------------- include/linux/seq_file.h | 6 +- 5 files changed, 137 insertions(+), 77 deletions(-) diff --git a/fs/ext4l/Makefile b/fs/ext4l/Makefile index 3116ac3be39..4003a1f2317 100644 --- a/fs/ext4l/Makefile +++ b/fs/ext4l/Makefile @@ -11,4 +11,4 @@ obj-y += balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ namei.o page-io.o readpage.o \ super.o symlink.o xattr.o \ xattr_hurd.o xattr_trusted.o \ - xattr_user.o orphan.o + xattr_user.o fast_commit.o orphan.o diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h index a6ffc91b7de..82b68056953 100644 --- a/fs/ext4l/ext4_uboot.h +++ b/fs/ext4l/ext4_uboot.h @@ -114,11 +114,6 @@ struct rb_root { /* percpu_counter - use Linux header */ #include <linux/percpu_counter.h> -/* name_snapshot - stub */ -struct name_snapshot { - const char *name; -}; - /* Project ID type */ typedef struct { unsigned int val; } kprojid_t; @@ -552,6 +547,11 @@ struct dentry { struct dentry *d_parent; }; +/* name_snapshot - for dentry name snapshots */ +struct name_snapshot { + struct qstr name; +}; + /* vm_fault_t - stub */ typedef unsigned int vm_fault_t; @@ -1968,10 +1968,6 @@ struct kstatfs { /* seq_file stubs */ struct seq_file; -#define seq_printf(m, fmt, ...) do { } while (0) -#define seq_puts(m, s) do { } while (0) -#define seq_putc(m, c) do { } while (0) -#define seq_escape(m, s, esc) do { } while (0) /* Module stubs */ struct module; @@ -2704,4 +2700,72 @@ typedef void *mempool_t; #define block_read_full_folio(folio, get_block) \ ({ (void)(folio); (void)(get_block); 0; }) +/* + * Stubs for fast_commit.c + */ + +/* Wait bit operations - stubbed for single-threaded U-Boot */ +struct wait_bit_entry { + struct list_head wq_entry; +}; +#define DEFINE_WAIT_BIT(name, word, bit) \ + struct wait_bit_entry name = { } +#define bit_waitqueue(word, bit) \ + ({ (void)(word); (void)(bit); (wait_queue_head_t *)NULL; }) +#define prepare_to_wait(wq, wait, state) \ + do { (void)(wq); (void)(wait); (void)(state); } while (0) +#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) + +/* Fast commit trace stubs */ +#define trace_ext4_fc_track_unlink(handle, inode, dentry, ret) \ + do { (void)(handle); (void)(inode); (void)(dentry); (void)(ret); } while (0) +#define trace_ext4_fc_track_link(handle, inode, dentry, ret) \ + do { (void)(handle); (void)(inode); (void)(dentry); (void)(ret); } while (0) +#define trace_ext4_fc_track_create(handle, inode, dentry, ret) \ + do { (void)(handle); (void)(inode); (void)(dentry); (void)(ret); } while (0) +#define trace_ext4_fc_track_inode(handle, inode, ret) \ + do { (void)(handle); (void)(inode); (void)(ret); } while (0) +#define trace_ext4_fc_track_range(handle, inode, start, end, ret) \ + do { (void)(handle); (void)(inode); (void)(start); (void)(end); (void)(ret); } while (0) + +/* lockdep stubs */ +#define lockdep_assert_not_held(lock) do { (void)(lock); } while (0) + +/* Request flags for block I/O */ +#define REQ_IDLE 0 +#define REQ_PREFLUSH 0 + +/* Fast commit trace stubs */ +#define trace_ext4_fc_cleanup(sb, full, reason) \ + do { (void)(sb); (void)(full); (void)(reason); } while (0) +#define trace_ext4_fc_stats(sb) \ + do { (void)(sb); } while (0) +#define trace_ext4_fc_commit_start(sb, tid) \ + do { (void)(sb); (void)(tid); } while (0) +#define trace_ext4_fc_commit_stop(sb, nblks, status, tid) \ + do { (void)(sb); (void)(nblks); (void)(status); (void)(tid); } while (0) + +/* 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) + +/* More fast commit trace stubs */ +#define trace_ext4_fc_replay_scan(sb, err, off) \ + do { (void)(sb); (void)(err); (void)(off); } while (0) +#define trace_ext4_fc_replay(sb, tag, ino, priv1, priv2) \ + do { (void)(sb); (void)(tag); (void)(ino); (void)(priv1); (void)(priv2); } while (0) + +/* get_current_ioprio - I/O priority (not used in U-Boot) */ +#define get_current_ioprio() (0) + #endif /* __EXT4_UBOOT_H__ */ diff --git a/fs/ext4l/fast_commit.c b/fs/ext4l/fast_commit.c index fa66b08de99..ea5be3a079c 100644 --- a/fs/ext4l/fast_commit.c +++ b/fs/ext4l/fast_commit.c @@ -7,12 +7,12 @@ * * Ext4 fast commits routines. */ +#include "ext4_uboot.h" + #include "ext4.h" #include "ext4_jbd2.h" #include "ext4_extents.h" #include "mballoc.h" - -#include <linux/lockdep.h> /* * Ext4 Fast Commits * ----------------- @@ -2291,7 +2291,7 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal) journal->j_fc_cleanup_callback = ext4_fc_cleanup; } -static const char * const fc_ineligible_reasons[] = { +static __maybe_unused const char * const fc_ineligible_reasons[] = { [EXT4_FC_REASON_XATTR] = "Extended attributes changed", [EXT4_FC_REASON_CROSS_RENAME] = "Cross rename", [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed", diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 87637ecbd8c..2b2b777d1f2 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -175,10 +175,7 @@ struct extent_status; /* ext4_is_pending is now in extents_status.c */ /* ext4_convert_inline_data is now in inline.c */ -void ext4_fc_mark_ineligible(struct super_block *sb, int reason, - void *handle) -{ -} +/* ext4_fc_mark_ineligible is now in fast_commit.c */ /* ext4_es_lookup_extent is now in extents_status.c */ @@ -188,17 +185,62 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, /* ext4_mb_mark_bb is now in mballoc.c */ -void ext4_fc_record_regions(struct super_block *sb, int ino, - unsigned long lblk, unsigned long long pblk, - int len, int mapped) +/* ext4_fc_record_regions is now in fast_commit.c */ + +/* ext4_fc_replay_check_excluded is now in fast_commit.c */ + +/* + * JBD2 fast commit stubs + */ +int jbd2_fc_get_buf(void *journal, struct buffer_head **bh_out) +{ + *bh_out = NULL; + return -ENOSPC; +} + +void jbd2_fc_release_bufs(void *journal) { } -int ext4_fc_replay_check_excluded(struct super_block *sb, unsigned long long blk) +int jbd2_fc_begin_commit(void *journal, unsigned int tid) +{ + return -EOPNOTSUPP; +} + +int jbd2_fc_end_commit(void *journal) { return 0; } +int jbd2_fc_end_commit_fallback(void *journal) +{ + return 0; +} + +int jbd2_submit_inode_data(void *journal, void *jinode) +{ + return 0; +} + +int jbd2_wait_inode_data(void *journal, void *jinode) +{ + return 0; +} + +int jbd2_fc_wait_bufs(void *journal, int num) +{ + return 0; +} + +int jbd2_complete_transaction(void *journal, unsigned int tid) +{ + return 0; +} + +void ext4_reset_inode_seed(struct inode *inode) +{ +} + /* * Stubs for page-io.c */ @@ -257,10 +299,7 @@ int jbd2_journal_inode_ranged_write(void *handle, struct inode *inode, /* ext4_read_bh_lock is now in super.c */ /* Fast commit */ -int ext4_fc_commit(void *journal, unsigned int tid) -{ - return 0; -} +/* ext4_fc_commit is now in fast_commit.c */ /* ext4_force_commit is now in super.c */ @@ -284,12 +323,7 @@ int jbd2_log_wait_commit(void *journal, unsigned int tid) return 0; } -/* Fast commit */ -void ext4_fc_track_range(void *handle, struct inode *inode, - unsigned long long start, unsigned long long end) -{ -} - +/* ext4_fc_track_range is now in fast_commit.c */ /* JBD2 journal update locking */ void jbd2_journal_lock_updates(void *journal) @@ -306,14 +340,8 @@ int jbd2_journal_flush(void *journal, unsigned int flags) } -/* Fast commit */ -void ext4_fc_track_inode(void *handle, struct inode *inode) -{ -} - -void ext4_fc_init_inode(void **head, struct inode *inode) -{ -} +/* ext4_fc_track_inode is now in fast_commit.c */ +/* ext4_fc_init_inode is now in fast_commit.c */ /* JBD2 */ int jbd2_journal_inode_ranged_wait(void *handle, struct inode *inode, @@ -372,33 +400,7 @@ ssize_t generic_read_dir(struct file *f, char *buf, size_t count, loff_t *ppos) /* Inline dir stubs are now in inline.c */ -/* Fast commit stubs */ -void ext4_fc_track_unlink(void *handle, struct dentry *dentry) -{ -} - -void ext4_fc_track_link(void *handle, struct dentry *dentry) -{ -} - -void ext4_fc_track_create(void *handle, struct dentry *dentry) -{ -} - -void __ext4_fc_track_link(void *handle, struct inode *inode, - struct dentry *dentry) -{ -} - -void __ext4_fc_track_unlink(void *handle, struct inode *inode, - struct dentry *dentry) -{ -} - -void __ext4_fc_track_create(void *handle, struct inode *inode, - struct dentry *dentry) -{ -} +/* Fast commit stubs are now in fast_commit.c */ /* fileattr stubs */ int ext4_fileattr_get(struct dentry *dentry, void *fa) @@ -603,10 +605,7 @@ void set_task_ioprio(void *task, int ioprio) { } -/* Fast commit */ -void ext4_fc_init(void *sb, void *journal) -{ -} +/* ext4_fc_init is now in fast_commit.c */ /* Filesystem sync */ int sync_filesystem(void *sb) @@ -784,10 +783,7 @@ char *file_path(struct file *file, char *buf, int buflen) return buf; } -/* Fast commit delete */ -void ext4_fc_del(struct inode *inode) -{ -} +/* ext4_fc_del is now in fast_commit.c */ /* invalidate_inode_buffers is now a macro in ext4_uboot.h */ /* clear_inode is now a macro in ext4_uboot.h */ diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 5b6495d1003..e4139f48e16 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -12,8 +12,8 @@ struct seq_file { struct file *file; }; -#define seq_printf(m, fmt, ...) do { } while (0) -#define seq_puts(m, s) do { } while (0) -#define seq_putc(m, c) do { } while (0) +#define seq_printf(m, fmt, ...) do { (void)(m); } while (0) +#define seq_puts(m, s) do { (void)(m); (void)(s); } while (0) +#define seq_putc(m, c) do { (void)(m); (void)(c); } while (0) #endif /* _LINUX_SEQ_FILE_H */ -- 2.43.0
participants (1)
-
Simon Glass