From patchwork Sun Dec 21 11:38:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1008 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766317133; bh=NETGzJvM7uETgaqpoJpucLIb5msj6+TmZ/swKaUaVrg=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=I5OyqUXyOpqRh/VZls6MnqCpEGM6bTs1JMNMOxTYw8OSSoDmZYU/UwPiAt22luJNv rX7V1vxqnnmJRGcUIPs16pH8oZq1hAtaWLiMNuLTnSTNpmlGth7zM+vUbGVsXFBUCk Qhuc+bN9BjHPW4DA+mRgzX71sAI8Xa2mBTNib4aXffJhp65sYmSguOXCJQYHT13ovk mgcpnBjP3JvZl4aIzRNywjeyyeV204RvV3m+G1XHOeSqo/1dNFfeow8lm1jdza7Xgp SwZzCLvg6gycmQS3sUcgqT6dBOr7TP3PM4Bl3ctFDYACndgOi+OTI+V+w0wbcTf2Q5 x7B0H/lhmSDXA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B6D6964CEE for ; Sun, 21 Dec 2025 04:38:53 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id a5h8x8k1k4Yi for ; Sun, 21 Dec 2025 04:38:53 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766317132; bh=NETGzJvM7uETgaqpoJpucLIb5msj6+TmZ/swKaUaVrg=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=SVWHVY46GV7wkuIQibQEHF+ofOFZYnDT/xk5Xx4G7rmEp6Al/O5m1xdSvauDbxq/C HIX7g+ED6PRjEi6qO6Hi+GWZa54amJ1MI78RfzYzSXIY65nZTuJdiswSl4VlJp75wq cUfjG5wS38fm43SteOCSWt564SM5HS/tiD5XMMgSJzePFyALonb5xiexHNGh7Vh19b 4lJuUr3uAWmmCxFcbebFv2oBVlcTuu0MlPjqAqQgMvdEiTBvAmv9U8v+in0/P4xQ+R pj1tfxo35eXqj3UuGh0gcrsoFUNIDExvJHu62N66VcBI7+11Mn0sYFDrsR0cOlIQKO 3iPIPyLgvqv+A== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B668E64CEC for ; Sun, 21 Dec 2025 04:38:52 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766317130; bh=q4HIIf54fjPZStpATqT6ouu23chf6wU3/L2JulFU69Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pfwRcw8KNKzXInJhlS7jU6CV/XOAqXVcLjFAsqh2flSFJPX2lQVkfxYV/qtFV89mY qmCHXPlUsmihF1MlfqhGDSL36pY4n93y8DglMRLv5a8KNytp12SypBdz4yQIEb6hLV oqBniyKppoZrRf5UO/Osf4x69a1+OdY9v2xYXOnCraxyWX8rlRAh8VRPH15GyeSEjQ JaEadj1yDAJ5dro5gzErJoCo2NwU/mQt0pg2C8LiE4HIxaiRW+/Ph6j3+NHlcIpB4j 3061+SXNHzbSP5VKBBhieQz/zLbyQfUtVMkuzDdBV1W+durBwIdC5pCne7CN40r+uH r2WF8HkFYJDPA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 14A6B64CC8; Sun, 21 Dec 2025 04:38:50 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id lKbns2uVdvBZ; Sun, 21 Dec 2025 04:38:50 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766317129; bh=Q2UooXGj6lMBPoF5ScLg4OZai1E4K3IFLI3hsJ0Mq+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rcVNmPQu5B3d8mUfC/+Dw2bkAn32rpq2IWfy6VPP2sGsqioVOIuCvQJgmok/Uwm6d 7sFT0TRBTcemwcb6b84ZMGn9lWh2O548c1lJ0XFP6kd7XUcZiiJ/DFP+5Hk7TcTNum dbLihpFM7lfHzzSDvZOXi4ZuJ42FGDpcZLLLh9BXLSmkyVxSQxI8nxcsFwFwZvsBNI 4T9MAOApfaZCdLtTMt+gl/ihXWzeNSyNCza2iRv1rmmumkKF0ZgU8dPATDfEeDO5gq 1ll/BDTycJ6mwzHu4nc5WhN/v2Bh+cTRkkkLVJuZbbSE6P+RdlFV+UWQm5tjcJBC2y W1W03/Gpq5mDA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 47FF864CE9; Sun, 21 Dec 2025 04:38:49 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Sun, 21 Dec 2025 04:38:10 -0700 Message-ID: <20251221113820.812060-5-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251221113820.812060-1-sjg@u-boot.org> References: <20251221113820.812060-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: IKPCIPRI2YZOR7XI2GNI5DMNY42A7LVY X-Message-ID-Hash: IKPCIPRI2YZOR7XI2GNI5DMNY42A7LVY X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 04/10] ext4l: Add namei.c to build List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass 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 Signed-off-by: Simon Glass --- 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "ext4_uboot.h" #include "ext4.h" #include "ext4_jbd2.h" - #include "xattr.h" #include "acl.h" - -#include /* * 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)