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