@@ -7,6 +7,6 @@ obj-y := interface.o stub.o
obj-y += balloc.o bitmap.o block_validity.o ext4_jbd2.o extents.o \
extents_status.o hash.o ialloc.o \
- indirect.o \
+ indirect.o inode.o \
xattr_hurd.o xattr_trusted.o \
xattr_user.o orphan.o
@@ -20,6 +20,8 @@
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/cred.h>
+#include <linux/fs.h>
+#include <linux/iomap.h>
/* Rotate left - not available in U-Boot */
static inline u32 rol32(u32 word, unsigned int shift)
@@ -165,16 +167,6 @@ typedef unsigned long pgoff_t;
#define PAGE_SHIFT 12
#endif
-/* File readahead state - stub */
-struct file_ra_state {
- pgoff_t start;
- unsigned int size;
- unsigned int async_size;
- unsigned int ra_pages;
- unsigned int mmap_miss;
- loff_t prev_pos;
-};
-
/* File mode flags */
#define FMODE_32BITHASH 0x00000001
#define FMODE_64BITHASH 0x00000002
@@ -212,7 +204,7 @@ struct dir_context {
};
/* iomap types - only define if linux/iomap.h not included */
-#ifndef _LINUX_IOMAP_H
+#ifndef LINUX_IOMAP_H
#define IOMAP_MAPPED 0
#define IOMAP_INLINE 1
#define IOMAP_UNWRITTEN 2
@@ -235,7 +227,7 @@ struct iomap_ops {
int (*iomap_end)(struct inode *inode, loff_t pos, loff_t length,
ssize_t written, unsigned flags, struct iomap *iomap);
};
-#endif /* _LINUX_IOMAP_H */
+#endif /* LINUX_IOMAP_H */
/* fiemap types */
#define FIEMAP_FLAG_SYNC 0x00000001
@@ -625,8 +617,125 @@ static inline int bdev_read_only(struct block_device *bdev)
/* Inode state bits */
#define I_NEW (1 << 0)
#define I_FREEING (1 << 1)
+#define I_DIRTY_DATASYNC (1 << 2)
+
+/* Inode flags for i_flags */
+#define S_SYNC 1
+#define S_NOATIME 2
+#define S_APPEND 4
+#define S_IMMUTABLE 8
+#define S_DAX 16
+#define S_DIRSYNC 32
+#define S_ENCRYPTED 64
+#define S_CASEFOLD 128
+#define S_VERITY 256
+
+/* Inode dirty state flags */
+#define I_DIRTY_TIME (1 << 3)
+
+/* Superblock flags */
+#define SB_LAZYTIME (1 << 25)
+
+/* iattr valid flags */
+#define ATTR_MODE (1 << 0)
+#define ATTR_UID (1 << 1)
+#define ATTR_GID (1 << 2)
+#define ATTR_SIZE (1 << 3)
+#define ATTR_ATIME (1 << 4)
+#define ATTR_MTIME (1 << 5)
+#define ATTR_CTIME (1 << 6)
+#define ATTR_ATIME_SET (1 << 7)
+#define ATTR_MTIME_SET (1 << 8)
+#define ATTR_FORCE (1 << 9)
+#define ATTR_KILL_SUID (1 << 11)
+#define ATTR_KILL_SGID (1 << 12)
+#define ATTR_TIMES_SET ((1 << 7) | (1 << 8))
+
+/* STATX flags and attributes */
+#define STATX_BTIME 0x00000800U
+#define STATX_DIOALIGN 0x00002000U
+#define STATX_WRITE_ATOMIC 0x00004000U
+#define STATX_ATTR_COMPRESSED 0x00000004
+#define STATX_ATTR_IMMUTABLE 0x00000010
+#define STATX_ATTR_APPEND 0x00000020
+#define STATX_ATTR_NODUMP 0x00000040
+#define STATX_ATTR_ENCRYPTED 0x00000800
+#define STATX_ATTR_VERITY 0x00100000
+
+/* VM fault return values */
+#define VM_FAULT_SIGBUS 0x0002
+#define VM_FAULT_NOPAGE 0x0010
+#define VM_FAULT_LOCKED 0x0200
+
+/* struct path - filesystem path */
+struct path {
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+};
+
+/* struct kstat - stat buffer */
+struct kstat {
+ u64 ino;
+ dev_t dev;
+ umode_t mode;
+ unsigned int nlink;
+ uid_t uid;
+ gid_t gid;
+ dev_t rdev;
+ loff_t size;
+ struct timespec64 atime;
+ struct timespec64 mtime;
+ struct timespec64 ctime;
+ struct timespec64 btime;
+ u64 blocks;
+ u32 blksize;
+ u64 attributes;
+ u64 attributes_mask;
+ u32 result_mask;
+ u32 dio_mem_align;
+ u32 dio_offset_align;
+ u32 atomic_write_unit_min;
+ u32 atomic_write_unit_max;
+ u32 atomic_write_segments_max;
+};
+
+/* struct vm_area_struct - virtual memory area */
+struct vm_area_struct {
+ unsigned long vm_start;
+ unsigned long vm_end;
+ struct file *vm_file;
+ unsigned long vm_flags;
+};
-/* inode - minimal stub */
+/* struct page - minimal stub */
+struct page {
+ unsigned long flags;
+};
+
+/* struct vm_fault - virtual memory fault info */
+struct vm_fault {
+ struct vm_area_struct *vma;
+ unsigned long address;
+ unsigned int flags;
+ pgoff_t pgoff;
+ struct folio *folio;
+ struct page *page;
+};
+
+/* Forward declaration for swap */
+struct swap_info_struct;
+
+/* MAX_PAGECACHE_ORDER - maximum order for page cache allocations */
+#define MAX_PAGECACHE_ORDER 12
+
+/* Process flags */
+#define PF_MEMALLOC 0x00000800
+
+/* Forward declarations for inode operations */
+struct inode_operations;
+struct file_operations;
+
+/* inode - extended for inode.c */
struct inode {
struct super_block *i_sb;
unsigned long i_ino;
@@ -634,6 +743,7 @@ struct inode {
unsigned int i_nlink;
loff_t i_size;
struct address_space *i_mapping;
+ struct address_space i_data;
kuid_t i_uid;
kgid_t i_gid;
unsigned long i_blocks;
@@ -644,9 +754,18 @@ struct inode {
struct timespec64 i_atime;
struct timespec64 i_mtime;
struct timespec64 i_ctime;
+ struct list_head i_io_list;
+ dev_t i_rdev;
+ const struct inode_operations *i_op;
+ const struct file_operations *i_fop;
};
/* Inode time accessors */
+static inline struct timespec64 inode_get_atime(const struct inode *inode)
+{
+ return inode->i_atime;
+}
+
static inline struct timespec64 inode_get_mtime(const struct inode *inode)
{
return inode->i_mtime;
@@ -657,6 +776,11 @@ static inline struct timespec64 inode_get_ctime(const struct inode *inode)
return inode->i_ctime;
}
+static inline time_t inode_get_atime_sec(const struct inode *inode)
+{
+ return inode->i_atime.tv_sec;
+}
+
static inline void simple_inode_init_ts(struct inode *inode)
{
struct timespec64 ts = { .tv_sec = 0, .tv_nsec = 0 };
@@ -905,4 +1029,377 @@ static inline ktime_t ktime_sub(ktime_t a, ktime_t b)
/* seq_file tokens */
#define SEQ_START_TOKEN ((void *)1)
+/* folio - memory page container stub */
+struct folio {
+ struct address_space *mapping;
+ unsigned long index;
+};
+
+/* folio_batch - batch of folios */
+struct folio_batch {
+ unsigned int nr;
+ struct folio *folios[16];
+};
+
+/* folio operations - stubs */
+#define folio_mark_dirty(f) do { (void)(f); } while (0)
+#define offset_in_folio(f, p) ({ (void)(f); (unsigned int)((p) & (PAGE_SIZE - 1)); })
+#define folio_buffers(f) ({ (void)(f); (struct buffer_head *)NULL; })
+#define folio_test_uptodate(f) ({ (void)(f); 1; })
+#define folio_pos(f) ({ (void)(f); 0LL; })
+#define folio_size(f) ({ (void)(f); PAGE_SIZE; })
+#define folio_unlock(f) do { (void)(f); } while (0)
+#define folio_put(f) do { (void)(f); } while (0)
+#define folio_lock(f) do { (void)(f); } while (0)
+#define folio_batch_init(fb) do { (fb)->nr = 0; } while (0)
+#define filemap_get_folios(m, i, e, fb) ({ (void)(m); (void)(i); (void)(e); (void)(fb); 0U; })
+
+/* xa_mark_t - xarray mark type */
+typedef unsigned int xa_mark_t;
+
+/* Page cache tags */
+#define PAGECACHE_TAG_DIRTY 0
+#define PAGECACHE_TAG_TOWRITE 1
+#define PAGECACHE_TAG_WRITEBACK 2
+
+/* blk_plug - block I/O plugging stub */
+struct blk_plug {
+ int dummy;
+};
+#define blk_start_plug(p) do { (void)(p); } while (0)
+#define blk_finish_plug(p) do { (void)(p); } while (0)
+
+/* Writeback reasons */
+#define WB_REASON_FS_FREE_SPACE 0
+
+/* readahead_control stub */
+struct readahead_control {
+ struct address_space *mapping;
+ struct file *file;
+ unsigned long _index;
+ unsigned int _batch_count;
+};
+
+#define readahead_pos(rac) ({ (void)(rac); 0LL; })
+#define readahead_length(rac) ({ (void)(rac); 0UL; })
+
+/* Forward declarations for address_space_operations */
+struct writeback_control;
+struct swap_info_struct;
+
+/* address_space_operations stub */
+struct address_space_operations {
+ int (*read_folio)(struct file *, struct folio *);
+ void (*readahead)(struct readahead_control *);
+ sector_t (*bmap)(struct address_space *, sector_t);
+ void (*invalidate_folio)(struct folio *, unsigned long, unsigned long);
+ bool (*release_folio)(struct folio *, gfp_t);
+ int (*write_begin)(const struct kiocb *, struct address_space *, loff_t, unsigned, struct folio **, void **);
+ int (*write_end)(const struct kiocb *, struct address_space *, loff_t, unsigned, unsigned, struct folio *, void *);
+ int (*writepages)(struct address_space *, struct writeback_control *);
+ bool (*dirty_folio)(struct address_space *, struct folio *);
+ bool (*is_partially_uptodate)(struct folio *, size_t, size_t);
+ int (*error_remove_folio)(struct address_space *, struct folio *);
+ int (*migrate_folio)(struct address_space *, struct folio *, struct folio *, int);
+ int (*swap_activate)(struct swap_info_struct *, struct file *, sector_t *);
+};
+
+/* Stub for buffer_migrate_folio */
+static inline int buffer_migrate_folio(struct address_space *mapping,
+ struct folio *dst, struct folio *src, int mode)
+{
+ return -EOPNOTSUPP;
+}
+
+/* Stub for buffer_migrate_folio_norefs */
+static inline int buffer_migrate_folio_norefs(struct address_space *mapping,
+ struct folio *dst, struct folio *src, int mode)
+{
+ return -EOPNOTSUPP;
+}
+
+/* Stub for noop_dirty_folio */
+static inline bool noop_dirty_folio(struct address_space *mapping,
+ struct folio *folio)
+{
+ return false;
+}
+
+/* Stub implementations for address_space_operations callbacks */
+static inline bool block_is_partially_uptodate(struct folio *folio,
+ size_t from, size_t count)
+{
+ return false;
+}
+
+static inline int generic_error_remove_folio(struct address_space *mapping,
+ struct folio *folio)
+{
+ return 0;
+}
+
+/* FGP flags for folio_grab_cache */
+#define FGP_ACCESSED 0x00000001
+#define FGP_LOCK 0x00000002
+#define FGP_CREAT 0x00000004
+#define FGP_WRITE 0x00000008
+#define FGP_NOFS 0x00000010
+#define FGP_NOWAIT 0x00000020
+#define FGP_FOR_MMAP 0x00000040
+#define FGP_STABLE 0x00000080
+
+/* __filemap_get_folio stub */
+static inline struct folio *__filemap_get_folio(struct address_space *mapping,
+ pgoff_t index, unsigned int fgp_flags,
+ gfp_t gfp)
+{
+ return NULL;
+}
+
+/* projid_t - project ID type */
+typedef unsigned int projid_t;
+
+/*
+ * Additional stubs for inode.c
+ */
+
+/* try_cmpxchg - compare and exchange with return value */
+#define try_cmpxchg(ptr, old, new) ({ \
+ typeof(*(old)) __old = *(old); \
+ typeof(*(ptr)) __ret = cmpxchg(ptr, __old, (new)); \
+ if (__ret != __old) \
+ *(old) = __ret; \
+ __ret == __old; \
+})
+
+/* ilog2 - log base 2 */
+#include <log.h>
+#define ilog2(n) (fls(n) - 1)
+
+/* Trace stubs for inode.c */
+#define trace_ext4_begin_ordered_truncate(...) do { } while (0)
+#define trace_ext4_evict_inode(...) do { } while (0)
+#define trace_ext4_da_update_reserve_space(...) do { } while (0)
+#define trace_ext4_da_reserve_space(...) do { } while (0)
+#define trace_ext4_da_release_space(...) do { } while (0)
+#define trace_ext4_da_write_pages_extent(...) do { } while (0)
+#define trace_ext4_writepages(...) do { } while (0)
+#define trace_ext4_da_write_folios_start(...) do { } while (0)
+#define trace_ext4_da_write_folios_end(...) do { } while (0)
+#define trace_ext4_writepages_result(...) do { } while (0)
+#define trace_ext4_da_write_begin(...) do { } while (0)
+#define trace_ext4_da_write_end(...) do { } while (0)
+#define trace_ext4_alloc_da_blocks(...) do { } while (0)
+#define trace_ext4_read_folio(...) do { } while (0)
+#define trace_ext4_invalidate_folio(...) do { } while (0)
+#define trace_ext4_journalled_invalidate_folio(...) do { } while (0)
+#define trace_ext4_release_folio(...) do { } while (0)
+#define trace_ext4_punch_hole(...) do { } while (0)
+#define trace_ext4_truncate_enter(...) do { } while (0)
+#define trace_ext4_truncate_exit(...) do { } while (0)
+#define trace_ext4_load_inode(...) do { } while (0)
+#define trace_ext4_other_inode_update_time(...) do { } while (0)
+#define trace_ext4_mark_inode_dirty(...) do { } while (0)
+#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)
+
+/* DAX stubs - DAX not supported in U-Boot */
+#define IS_DAX(inode) (0)
+#define dax_break_layout_final(inode) do { } while (0)
+#define dax_writeback_mapping_range(m, bd, wb) ({ (void)(m); (void)(bd); (void)(wb); 0; })
+#define dax_zero_range(i, p, l, d, op) ({ (void)(i); (void)(p); (void)(l); (void)(d); (void)(op); -EOPNOTSUPP; })
+#define dax_break_layout_inode(i, m) ({ (void)(i); (void)(m); 0; })
+
+/* 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_pagefault(sb) do { (void)(sb); } while (0)
+#define sb_end_pagefault(sb) do { (void)(sb); } while (0)
+
+/* Inode I/O list management */
+#define inode_io_list_del(inode) do { } while (0)
+#define inode_is_open_for_write(i) (0)
+#define inode_is_dirtytime_only(i) (0)
+
+/* Folio operations - additional stubs */
+#define folio_zero_segments(f, s1, e1, s2, e2) do { } while (0)
+#define folio_zero_new_buffers(f, f2, t) do { } while (0)
+#define folio_wait_stable(f) do { } while (0)
+#define folio_zero_range(f, s, l) do { } while (0)
+#define folio_mark_uptodate(f) do { } while (0)
+#define folio_next_index(f) ((f)->index + 1)
+#define folio_mapped(f) (0)
+#define folio_clear_dirty_for_io(f) ({ (void)(f); 1; })
+#define folio_clear_uptodate(f) do { } while (0)
+#define folio_batch_release(fb) do { } while (0)
+#define folio_nr_pages(f) (1UL)
+#define folio_contains(f, idx) ({ (void)(f); (void)(idx); 1; })
+#define folio_clear_checked(f) do { } while (0)
+#define folio_test_dirty(f) (0)
+#define folio_test_writeback(f) (0)
+#define folio_wait_writeback(f) do { } while (0)
+#define folio_clear_dirty(f) do { } while (0)
+#define folio_test_checked(f) (0)
+#define folio_maybe_dma_pinned(f) (0)
+#define folio_set_checked(f) do { } while (0)
+#define folio_test_locked(f) (0)
+#define folio_mkclean(f) (0)
+#define page_folio(page) ((struct folio *)(page))
+
+/* Quota stubs - additional */
+#define dquot_claim_block(i, n) ({ (void)(i); (void)(n); 0; })
+#define dquot_reserve_block(i, n) ({ (void)(i); (void)(n); 0; })
+#define dquot_release_reservation_block(i, n) do { } while (0)
+#define dquot_initialize_needed(i) (0)
+#define dquot_transfer(m, i, a) ({ (void)(m); (void)(i); (void)(a); 0; })
+#define is_quota_modification(m, i, a) ({ (void)(m); (void)(i); (void)(a); 0; })
+
+/* Percpu counter sub */
+#define percpu_counter_sub(fbc, amount) ((fbc)->count -= (amount))
+
+/* Filemap operations - additional */
+#define filemap_get_folio(m, i) ((struct folio *)NULL)
+#define filemap_get_folios_tag(m, s, e, t, fb) ({ (void)(m); (void)(s); (void)(e); (void)(t); (void)(fb); 0U; })
+#define filemap_flush(m) ({ (void)(m); 0; })
+#define filemap_write_and_wait(m) ({ (void)(m); 0; })
+#define filemap_dirty_folio(m, f) ({ (void)(m); (void)(f); false; })
+#define filemap_lock_folio(m, i) ((struct folio *)NULL)
+#define filemap_invalidate_lock_shared(m) do { } while (0)
+#define filemap_invalidate_unlock_shared(m) do { } while (0)
+#define mapping_tagged(m, t) (0)
+#define tag_pages_for_writeback(m, s, e) do { } while (0)
+#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)
+
+/* Buffer operations - additional */
+#define getblk_unmovable(bd, b, s) ((struct buffer_head *)NULL)
+#define create_empty_buffers(f, s, flags) ({ (void)(f); (void)(s); (void)(flags); (struct buffer_head *)NULL; })
+#define bh_offset(bh) (0UL)
+#define block_invalidate_folio(f, o, l) do { } while (0)
+#define block_write_end(pos, len, copied, folio) ({ (void)(pos); (void)(len); (void)(folio); (copied); })
+#define block_dirty_folio(m, f) ({ (void)(m); (void)(f); false; })
+#define try_to_free_buffers(f) ({ (void)(f); true; })
+#define block_commit_write(f, f2, t) do { } while (0)
+#define block_page_mkwrite(v, f, g) ((vm_fault_t)0)
+#define map_bh(bh, sb, block) do { } while (0)
+#define write_begin_get_folio(iocb, m, idx, l) ({ (void)(iocb); (void)(m); (void)(idx); (void)(l); (struct folio *)NULL; })
+
+/* 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_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; })
+#define fscrypt_dio_supported(i) (1)
+
+/* fsverity stubs */
+#define fsverity_prepare_setattr(d, a) ({ (void)(d); (void)(a); 0; })
+#define fsverity_active(i) (0)
+
+/* Inode time setters - needed for ext4.h */
+static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode,
+ struct timespec64 ts)
+{
+ inode->i_atime = ts;
+ return ts;
+}
+
+static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode,
+ struct timespec64 ts)
+{
+ inode->i_ctime = ts;
+ return ts;
+}
+
+/* Inode version operations */
+#define inode_peek_iversion_raw(i) (0ULL)
+#define inode_peek_iversion(i) (0ULL)
+#define inode_set_flags(i, f, m) do { } while (0)
+#define inode_set_iversion_raw(i, v) do { } while (0)
+#define inode_set_iversion_queried(i, v) do { } while (0)
+#define inode_inc_iversion(i) do { } while (0)
+
+/* Inode credential helpers */
+static inline unsigned int i_uid_read(const struct inode *inode)
+{
+ return inode->i_uid.val;
+}
+
+static inline unsigned int i_gid_read(const struct inode *inode)
+{
+ return inode->i_gid.val;
+}
+
+#define i_uid_needs_update(m, a, i) ({ (void)(m); (void)(a); (void)(i); 0; })
+#define i_gid_needs_update(m, a, i) ({ (void)(m); (void)(a); (void)(i); 0; })
+#define i_uid_update(m, a, i) do { } while (0)
+#define i_gid_update(m, a, i) do { } while (0)
+
+/* Device encoding helpers */
+#ifndef MINORBITS
+#define MINORBITS 20
+#endif
+#ifndef MINORMASK
+#define MINORMASK ((1U << MINORBITS) - 1)
+#endif
+#ifndef MAJOR
+#define MAJOR(dev) ((unsigned int)((dev) >> MINORBITS))
+#endif
+#ifndef MINOR
+#define MINOR(dev) ((unsigned int)((dev) & MINORMASK))
+#endif
+#ifndef MKDEV
+#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi))
+#endif
+
+#define old_valid_dev(dev) (MAJOR(dev) < 256 && MINOR(dev) < 256)
+#define old_encode_dev(dev) ((MAJOR(dev) << 8) | MINOR(dev))
+#define old_decode_dev(dev) MKDEV((dev) >> 8, (dev) & 0xff)
+#define new_encode_dev(dev) ((unsigned int)(dev))
+#define new_decode_dev(dev) ((dev_t)(dev))
+
+/* UID/GID bit helpers */
+#define low_16_bits(x) ((x) & 0xFFFF)
+#define high_16_bits(x) (((x) >> 16) & 0xFFFF)
+#define fs_high2lowuid(uid) ((uid) & 0xFFFF)
+#define fs_high2lowgid(gid) ((gid) & 0xFFFF)
+
+/* 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 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)
+#define iget_failed(i) do { } while (0)
+#define find_inode_by_ino_rcu(sb, ino) ((struct inode *)NULL)
+#define mark_inode_dirty(i) do { } while (0)
+
+/* Attribute operations */
+#define setattr_prepare(m, d, a) ({ (void)(m); (void)(d); (void)(a); 0; })
+#define setattr_copy(m, i, a) do { } while (0)
+#define posix_acl_chmod(m, i, mo) ({ (void)(m); (void)(i); (void)(mo); 0; })
+#define generic_fillattr(m, req, i, s) do { } while (0)
+#define generic_fill_statx_atomic_writes(s, u_m, u_M, g) do { } while (0)
+
+/* Inode flag macros */
+#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
+#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
+
+/* File operations */
+#define file_update_time(f) do { } while (0)
+#define vmf_fs_error(e) ((vm_fault_t)VM_FAULT_SIGBUS)
+
+/* 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; })
+
+/* Block device alignment */
+#define bdev_dma_alignment(bd) (0)
+
+/* Truncation */
+#define truncate_inode_pages_final(m) do { } while (0)
+#define truncate_pagecache_range(i, s, e) do { } while (0)
+
#endif /* __EXT4_UBOOT_H__ */
@@ -20,16 +20,8 @@
*/
#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/iomap.h>
-#include <linux/mount.h>
-#include <linux/path.h>
-#include <linux/dax.h>
-#include <linux/quotaops.h>
-#include <linux/pagevec.h>
-#include <linux/uio.h>
+#include "ext4_uboot.h"
#include <linux/mman.h>
-#include <linux/backing-dev.h>
#include "ext4.h"
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -69,7 +61,7 @@ static bool ext4_should_use_dio(struct kiocb *iocb, struct iov_iter *iter)
static ssize_t ext4_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
ssize_t ret;
- struct inode *inode = file_inode(iocb->ki_filp);
+ struct inode *inode __maybe_unused = file_inode(iocb->ki_filp);
if (iocb->ki_flags & IOCB_NOWAIT) {
if (!inode_trylock_shared(inode))
@@ -286,7 +278,7 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
struct iov_iter *from)
{
ssize_t ret;
- struct inode *inode = file_inode(iocb->ki_filp);
+ struct inode *inode __maybe_unused = file_inode(iocb->ki_filp);
if (iocb->ki_flags & IOCB_NOWAIT)
return -EOPNOTSUPP;
@@ -402,7 +394,7 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
return error < 0 ? error : 0;
}
-static const struct iomap_dio_ops ext4_dio_write_ops = {
+static const struct iomap_dio_ops __maybe_unused ext4_dio_write_ops = {
.end_io = ext4_dio_write_end_io,
};
@@ -809,7 +801,7 @@ static int ext4_file_mmap_prepare(struct vm_area_desc *desc)
int ret;
struct file *file = desc->file;
struct inode *inode = file->f_mapping->host;
- struct dax_device *dax_dev = EXT4_SB(inode->i_sb)->s_daxdev;
+ struct dax_device *dax_dev __maybe_unused = EXT4_SB(inode->i_sb)->s_daxdev;
if (file->f_mode & FMODE_WRITE)
ret = ext4_emergency_state(inode->i_sb);
@@ -935,7 +927,7 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
{
struct inode *inode = file->f_mapping->host;
- loff_t maxbytes = ext4_get_maxbytes(inode);
+ loff_t maxbytes __maybe_unused = ext4_get_maxbytes(inode);
switch (whence) {
default:
@@ -19,29 +19,7 @@
* Assorted race fixes, rewrite of ext4_get_block() by Al Viro, 2000
*/
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/time.h>
-#include <linux/highuid.h>
-#include <linux/pagemap.h>
-#include <linux/dax.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/rmap.h>
-#include <linux/namei.h>
-#include <linux/uio.h>
-#include <linux/bio.h>
-#include <linux/workqueue.h>
-#include <linux/kernel.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include <linux/iomap.h>
-#include <linux/iversion.h>
+#include "ext4_uboot.h"
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -1763,9 +1741,9 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
static void ext4_print_free_blocks(struct inode *inode)
{
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ struct ext4_sb_info *sbi __maybe_unused = EXT4_SB(inode->i_sb);
struct super_block *sb = inode->i_sb;
- struct ext4_inode_info *ei = EXT4_I(inode);
+ struct ext4_inode_info *ei __maybe_unused = EXT4_I(inode);
ext4_msg(sb, KERN_CRIT, "Total free blocks count %lld",
EXT4_C2B(EXT4_SB(inode->i_sb),
@@ -2758,7 +2736,7 @@ static int ext4_do_writepages(struct mpage_da_data *mpd)
{
struct writeback_control *wbc = mpd->wbc;
pgoff_t writeback_index = 0;
- long nr_to_write = wbc->nr_to_write;
+ __maybe_unused long nr_to_write = wbc->nr_to_write;
int range_whole = 0;
int cycled = 1;
handle_t *handle = NULL;
@@ -3055,7 +3033,7 @@ static int ext4_dax_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
int ret;
- long nr_to_write = wbc->nr_to_write;
+ __maybe_unused long nr_to_write = wbc->nr_to_write;
struct inode *inode = mapping->host;
int alloc_ctx;
@@ -4541,7 +4519,7 @@ int ext4_inode_attach_jinode(struct inode *inode)
*/
int ext4_truncate(struct inode *inode)
{
- struct ext4_inode_info *ei = EXT4_I(inode);
+ __maybe_unused struct ext4_inode_info *ei = EXT4_I(inode);
unsigned int credits;
int err = 0, err2;
handle_t *handle;
@@ -4646,7 +4624,7 @@ out_trace:
static inline u64 ext4_inode_peek_iversion(const struct inode *inode)
{
- if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
+ if (unlikely(EXT4_I((struct inode *)inode)->i_flags & EXT4_EA_INODE_FL))
return inode_peek_iversion_raw(inode);
else
return inode_peek_iversion(inode);
@@ -6094,7 +6072,8 @@ int ext4_getattr(struct mnt_idmap *idmap, const struct path *path,
stat->result_mask |= STATX_DIOALIGN;
if (dio_align == 1) {
- struct block_device *bdev = inode->i_sb->s_bdev;
+ __maybe_unused struct block_device *bdev =
+ inode->i_sb->s_bdev;
/* iomap defaults */
stat->dio_mem_align = bdev_dma_alignment(bdev) + 1;
@@ -9,6 +9,7 @@
* DO NOT use this file as a reference - these are temporary placeholders only.
*/
+#include "ext4_uboot.h"
#include <linux/types.h>
struct super_block;
@@ -37,18 +38,6 @@ unsigned long ext4_inode_table(struct super_block *sb, void *gdp)
return 0;
}
-struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
- int flags, const char *func, unsigned int line)
-{
- return NULL;
-}
-
-int ext4_map_blocks(void *handle, struct inode *inode,
- struct ext4_map_blocks *map, int flags)
-{
- return 0;
-}
-
void __ext4_error_inode(struct inode *inode, const char *func,
unsigned int line, unsigned long block,
int error, const char *fmt, ...)
@@ -250,194 +239,344 @@ struct extent_status;
/* ext4_es_cache_extent is now in extents_status.c */
-int ext4_issue_zeroout(struct inode *inode, unsigned long long lblk,
- unsigned long long pblk, unsigned long long len)
+/* ext4_es_insert_extent is now in extents_status.c */
+
+/* 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)
+{
+}
+
+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_es_insert_extent is now in extents_status.c */
+void ext4_fc_mark_ineligible(struct super_block *sb, int reason,
+ void *handle)
+{
+}
-/* ext4_remove_pending is now in extents_status.c */
+/* ext4_es_lookup_extent is now in extents_status.c */
+
+/* ext4_es_remove_extent is now in extents_status.c */
-void ext4_da_release_space(struct inode *inode, int to_free)
+/* 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)
{
}
-void ext4_da_update_reserve_space(struct inode *inode, int used, int quota_claim)
+void ext4_fc_record_regions(struct super_block *sb, int ino,
+ unsigned long lblk, unsigned long long pblk,
+ int len, int mapped)
{
}
-int ext4_get_inode_loc(struct inode *inode, void *iloc)
+int ext4_read_bh(struct buffer_head *bh, unsigned int op_flags,
+ bh_end_io_t *end_io, bool simu_fail)
{
- return -1;
+ return 0;
}
-void ext4_free_blocks(void *handle, struct inode *inode,
- struct buffer_head *bh, unsigned long long block,
- unsigned long count, int flags)
+struct buffer_head *ext4_sb_bread_nofail(struct super_block *sb,
+ unsigned long long block)
{
+ return NULL;
}
-int __ext4_mark_inode_dirty(void *handle, struct inode *inode, int flags)
+/*
+ * 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;
}
-void ext4_discard_preallocations(struct inode *inode, unsigned int needed)
+/* 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;
+}
+
+/*
+ * Stubs for orphan.c
+ */
+struct ext4_iloc;
+
+void ext4_superblock_csum_set(struct super_block *sb)
+{
+}
+
+int ext4_feature_set_ok(struct super_block *sb, int readonly)
+{
+ return 1;
+}
+
+/*
+ * Stubs for inode.c
+ */
+#include <linux/sched.h>
+
+/* JBD2 stubs for inode.c */
+int jbd2_journal_blocks_per_folio(struct inode *inode)
+{
+ return 1;
+}
+
+int jbd2_transaction_committed(void *journal, unsigned int tid)
+{
+ return 1;
+}
+
+
+void __ext4_warning_inode(struct inode *inode, const char *func,
+ unsigned int line, const char *fmt, ...)
{
}
-int ext4_check_map_extents_env(struct inode *inode)
+
+/* Readahead */
+int ext4_mpage_readpages(void *mapping, void *rac, void *folio)
{
return 0;
}
-int ext4_chunk_trans_extent(struct inode *inode, int nrblocks)
+int ext4_readpage_inline(struct inode *inode, void *folio)
{
return 0;
}
-int ext4_chunk_trans_blocks(struct inode *inode, int nrblocks)
+/* Xattr */
+int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
+ void *raw_inode, void *handle)
{
return 0;
}
-/* ext4_is_pending is now in extents_status.c */
+void ext4_evict_ea_inode(struct inode *inode)
+{
+}
-int ext4_meta_trans_blocks(struct inode *inode, int lblk, int pblk)
+
+/* More JBD2 stubs */
+int jbd2_journal_inode_ranged_write(void *handle, struct inode *inode,
+ loff_t start, loff_t len)
{
return 0;
}
-int ext4_zero_partial_blocks(void *handle, struct inode *inode,
- loff_t lstart, loff_t length)
+
+int ext4_read_bh_lock(struct buffer_head *bh, int op_flags, int nowait)
{
return 0;
}
-int ext4_convert_inline_data(struct inode *inode)
+
+/* Fast commit */
+int ext4_fc_commit(void *journal, unsigned int tid)
{
return 0;
}
-int ext4_break_layouts(struct inode *inode)
+int ext4_force_commit(struct super_block *sb)
{
return 0;
}
-int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
+
+/* Inline data */
+int ext4_destroy_inline_data(void *handle, struct inode *inode)
{
return 0;
}
-void ext4_fc_mark_ineligible(struct super_block *sb, int reason,
- void *handle)
+/* I/O submit */
+void ext4_io_submit_init(void *io, void *wbc)
{
}
-void ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
- loff_t len)
+
+void *ext4_init_io_end(struct inode *inode, int gfp)
{
+ return NULL;
}
-void ext4_truncate_page_cache_block_range(struct inode *inode, loff_t start,
- loff_t len)
+void ext4_io_submit(void *io)
{
}
-/* ext4_iomap_report_ops - just a symbol needed for linking */
-char ext4_iomap_report_ops;
+void ext4_put_io_end_defer(void *io_end)
+{
+}
-/* ext4_es_lookup_extent is now in extents_status.c */
+void ext4_put_io_end(void *io_end)
+{
+}
-/* ext4_es_remove_extent is now in extents_status.c */
+void *ext4_alloc_io_end_vec(void *io_end, unsigned long num)
+{
+ return NULL;
+}
-/* 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)
+/* JBD2 ordered truncate */
+int jbd2_journal_begin_ordered_truncate(void *ji, loff_t new_size)
{
+ return 0;
}
-void ext4_fc_record_regions(struct super_block *sb, int ino,
- unsigned long lblk, unsigned long long pblk,
- int len, int mapped)
+void jbd2_journal_invalidate_folio(void *journal, void *folio,
+ unsigned long off, unsigned int len)
{
}
-int ext4_read_bh(struct buffer_head *bh, unsigned int op_flags,
- bh_end_io_t *end_io, bool simu_fail)
+int jbd2_log_wait_commit(void *journal, unsigned int tid)
{
return 0;
}
-struct buffer_head *ext4_sb_bread_nofail(struct super_block *sb,
- unsigned long long block)
+/* Fast commit */
+void ext4_fc_track_range(void *handle, struct inode *inode,
+ unsigned long long start, unsigned long long end)
{
- return NULL;
}
-/*
- * 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)
+
+/* JBD2 journal update locking */
+void jbd2_journal_lock_updates(void *journal)
+{
+}
+
+void jbd2_journal_unlock_updates(void *journal)
+{
+}
+
+int jbd2_journal_flush(void *journal, unsigned int flags)
{
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)
+/* Fast commit */
+void ext4_fc_track_inode(void *handle, struct inode *inode)
{
- return -1;
}
-int ext4_xattr_set(struct inode *inode, int name_index, const char *name,
- const void *value, size_t value_len, int flags)
+void ext4_fc_init_inode(void **head, struct inode *inode)
{
- return -1;
}
-/*
- * Stubs for orphan.c
- */
-struct ext4_iloc;
+/* JBD2 */
+int jbd2_journal_inode_ranged_wait(void *handle, struct inode *inode,
+ loff_t start, loff_t len)
+{
+ return 0;
+}
-int ext4_reserve_inode_write(void *handle, struct inode *inode,
- struct ext4_iloc *iloc)
+/* Inline data */
+int ext4_inline_data_iomap(struct inode *inode, void *iomap)
{
return 0;
}
-void ext4_superblock_csum_set(struct super_block *sb)
+
+/* xattr */
+int __xattr_check_inode(struct inode *inode, void *entry, void *end,
+ unsigned int size, int check_block)
{
+ return 0;
}
-int ext4_mark_iloc_dirty(void *handle, struct inode *inode,
- struct ext4_iloc *iloc)
+int ext4_find_inline_data_nolock(struct inode *inode)
{
return 0;
}
-int ext4_truncate(struct inode *inode)
+
+/* File and inode operations symbols */
+char ext4_file_inode_operations;
+char ext4_file_operations;
+char ext4_dir_inode_operations;
+char ext4_dir_operations;
+char ext4_special_inode_operations;
+char ext4_symlink_inode_operations;
+char ext4_fast_symlink_inode_operations;
+
+
+void ext4_update_dynamic_rev(struct super_block *sb)
{
+}
+
+
+/* Inline data */
+int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+{
+ *has_inline = 0;
return 0;
}
-int ext4_feature_set_ok(struct super_block *sb, int readonly)
+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;
+}
+
+/* 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)
+{
+}
+
+/* JBD2 stubs for inode.c */
+struct kmem_cache *jbd2_inode_cache;
+
+int jbd2_journal_try_to_free_buffers(journal_t *journal, struct folio *folio)
{
return 1;
}
-struct buffer_head *ext4_bread(void *handle, struct inode *inode,
- unsigned long long block, int create)
+void jbd2_journal_init_jbd_inode(void *jinode, struct inode *inode)
{
- return NULL;
}
new file mode 100644
@@ -15,6 +15,7 @@
struct inode;
struct super_block;
struct buffer_head;
+struct address_space_operations;
/* errseq_t - error sequence type */
typedef u32 errseq_t;
@@ -29,16 +30,21 @@ typedef unsigned int fmode_t;
/* Buffer operations are in buffer_head.h */
-/* address_space - minimal stub */
+/* address_space - extended for inode.c */
struct address_space {
struct inode *host;
- errseq_t wb_err; /* For jbd2 error tracking */
+ errseq_t wb_err;
+ unsigned long nrpages;
+ unsigned long writeback_index;
+ struct list_head i_private_list;
+ const struct address_space_operations *a_ops;
};
/* block_device - minimal stub */
struct block_device {
struct address_space *bd_mapping;
void *bd_disk;
+ struct super_block *bd_super;
};
/* errseq functions - stubs */
@@ -52,12 +58,24 @@ static inline int errseq_check_and_advance(errseq_t *eseq, errseq_t *since)
return 0;
}
+/* File readahead state - stub */
+struct file_ra_state {
+ unsigned long start;
+ unsigned int size;
+ unsigned int async_size;
+ unsigned int ra_pages;
+ unsigned int mmap_miss;
+ long long prev_pos;
+};
+
/* file - minimal stub */
struct file {
fmode_t f_mode;
struct inode *f_inode;
unsigned int f_flags;
struct address_space *f_mapping;
+ void *private_data;
+ struct file_ra_state f_ra;
};
/* Get inode from file */
@@ -5,6 +5,7 @@
#include <linux/types.h>
struct bio;
+struct dax_device;
struct inode;
struct iomap_iter;
struct kiocb;
@@ -37,6 +38,13 @@ struct vm_fault;
#define IOMAP_OVERWRITE_ONLY (1 << 6)
#define IOMAP_UNSHARE (1 << 7)
#define IOMAP_DAX (1 << 8)
+#define IOMAP_ATOMIC (1 << 9)
+
+/* IOMAP_NULL_ADDR indicates a hole/unwritten block address */
+#define IOMAP_NULL_ADDR ((u64)-1)
+
+/* Additional iomap flags */
+#define IOMAP_F_ATOMIC_BIO (1U << 6)
struct iomap {
u64 addr;
@@ -33,6 +33,9 @@
#include <linux/init.h>
#endif
+/* Transaction ID type */
+typedef unsigned int tid_t;
+
#define journal_oom_retry 1
/*
new file mode 100644
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * include/linux/mpage.h
+ *
+ * Contains declarations related to preparing and submitting BIOS which contain
+ * multiple pagecache pages.
+ */
+
+#ifndef _LINUX_MPAGE_H
+#define _LINUX_MPAGE_H
+
+/* Stub for linux/mpage.h - U-Boot doesn't support multi-page I/O */
+
+#endif /* _LINUX_MPAGE_H */
new file mode 100644
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_RMAP_H
+#define _LINUX_RMAP_H
+
+/* Stub for linux/rmap.h - U-Boot doesn't support reverse mapping */
+
+#endif /* _LINUX_RMAP_H */
@@ -15,6 +15,7 @@ struct task_struct {
int pid;
char comm[16];
void *journal_info; /* For jbd2 */
+ unsigned int flags; /* PF_* flags */
};
extern struct task_struct *current;