[Concept,01/10] ext4l: Add file.c to build

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

Commit Message

Simon Glass Dec. 21, 2025, 11:38 a.m. UTC
  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(-)
  

Patch

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;