From patchwork Tue Apr 21 18:34:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2230 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=1776796552; bh=6mdk27D8OKoqEq007cx7lw09CkOxWFq7kIqLGnDvZxs=; 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=TZP/hU63xwFi5HpRwu91VS8m1slfhrLQXA5UyNVaFMfFIZU+9F435+tvUtKKuJLXE 01gF9W2mAIJeXy5RxhuFddpKzYOEXnoI7sHAlqZKJOTmXQNw0kuKMpW7mOyPH68k7W jjen3AvXNhRvxiItDa+t/ovDNCQoLn0SKqm0SbdU= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9426D6A613 for ; Tue, 21 Apr 2026 12:35:52 -0600 (MDT) 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 kFnbE3K4Lryf for ; Tue, 21 Apr 2026 12:35:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776796552; bh=6mdk27D8OKoqEq007cx7lw09CkOxWFq7kIqLGnDvZxs=; 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=TZP/hU63xwFi5HpRwu91VS8m1slfhrLQXA5UyNVaFMfFIZU+9F435+tvUtKKuJLXE 01gF9W2mAIJeXy5RxhuFddpKzYOEXnoI7sHAlqZKJOTmXQNw0kuKMpW7mOyPH68k7W jjen3AvXNhRvxiItDa+t/ovDNCQoLn0SKqm0SbdU= Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 7C9336A604 for ; Tue, 21 Apr 2026 12:35:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776796549; bh=TU8vW3sfOsGElFkaXvkkgAI2znq26ZdsTiAt7yJLn8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C9vAyaShvum/L2Ywh4khQi0ZqNEvyrLxnUSFmK2VVXhsJjbVmOYTlTpijnXn66so2 +Vg07xwvz3iqqxyKVuwK1dMKD7+5Mab3jh4LkDK3B556/Qdra1BgR8skGx6wlwcoW3 38C8ZVZG/W2Z+yl8NpWc6A8VPnkUga0Mm27cZaUw= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B9CA26A604; Tue, 21 Apr 2026 12:35:49 -0600 (MDT) 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 JReMZA6a1uH3; Tue, 21 Apr 2026 12:35:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776796544; bh=VTFyW3fC6sIqhu7N+msh59gADGS18iyscaOi6SB5i8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bdJx5cf9AbVP89Z59FEUyGGq5XvtdSdCeiKFQi5qPdIFcGq9EoOwIgI1QHQ3DRob6 ZhBi+D+4HRRbgs7cVr0Gwx6fc3yvET6S+iarerkXDIaN0LMU0W/WbmzTT7Etm0Ko16 zPxq9SwSKQy3z4WA45adaP/lgCHg+yoRxPl765xQ= Received: from u-boot.org (unknown [174.51.25.52]) by mail.u-boot.org (Postfix) with ESMTPSA id 0D3336A603; Tue, 21 Apr 2026 12:35:43 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 21 Apr 2026 12:34:43 -0600 Message-ID: <20260421183511.2044469-3-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260421183511.2044469-1-sjg@u-boot.org> References: <20260421183511.2044469-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: XHJCHDDSZONRJDBQ7C4SHMW4QOOCLCZE X-Message-ID-Hash: XHJCHDDSZONRJDBQ7C4SHMW4QOOCLCZE 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 X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 02/16] fs: Move generic VFS stubs out of ext4l 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 The Linux-port shims alloc_inode_sb(), free_page(), sb_set_blocksize(), d_make_root() and iput() live in fs/ext4l/stub.c, which is only built when CONFIG_FS_EXT4L is set. Nothing in those five functions is ext4-specific; they are also called by code under fs/isofs, so building U-Boot with CONFIG_FS_ISOFS=y and CONFIG_FS_EXT4L=n produces an image with five unresolved externals. Calling into isofs at runtime jumps through a NULL function pointer and triggers a #UD on x86. Move the five functions into fs/linux_fs.c, which is already compiled when CONFIG_FS_LINUX is set (auto-selected by FS_ISOFS or FS_EXT4L). Also add for struct dentry - the behaviour is unchanged for ext4l-only builds. Signed-off-by: Simon Glass --- fs/ext4l/stub.c | 74 +++------------------------------------- fs/linux_fs.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 70 deletions(-) diff --git a/fs/ext4l/stub.c b/fs/ext4l/stub.c index 6fe8398623e..df2a72bc731 100644 --- a/fs/ext4l/stub.c +++ b/fs/ext4l/stub.c @@ -337,11 +337,7 @@ int inode_generic_drop(struct inode *inode) return 0; } -void *alloc_inode_sb(struct super_block *sb, struct kmem_cache *cache, - gfp_t gfp) -{ - return kmem_cache_alloc(cache, gfp); -} +/* alloc_inode_sb() is now in fs/linux_fs.c */ /* inode_set_iversion is now a macro in linux/iversion.h */ @@ -381,10 +377,7 @@ unsigned long get_zeroed_page(gfp_t gfp) return (unsigned long)p; } -void free_page(unsigned long addr) -{ - free((void *)addr); -} +/* free_page() is now in fs/linux_fs.c */ /* Trace stubs */ void trace_ext4_error(struct super_block *sb, const char *func, unsigned int line) @@ -460,19 +453,7 @@ void fs_put_dax(void *dax, void *holder) { } -/* Block size */ -int sb_set_blocksize(struct super_block *sb, int size) -{ - /* Validate block size */ - if (size != 1024 && size != 2048 && size != 4096) - return 0; - - /* Update superblock fields */ - sb->s_blocksize = size; - sb->s_blocksize_bits = ffs(size) - 1; - - return size; -} +/* sb_set_blocksize() is now in fs/linux_fs.c */ /* strscpy_pad is now a macro in linux/string.h */ /* kmemdup_nul is now in lib/string.c */ @@ -501,54 +482,7 @@ void generic_set_sb_d_ops(struct super_block *sb) { } -/** - * d_make_root() - Create a root dentry for an inode - * @inode: Inode to create dentry for - * Return: Allocated dentry or NULL on failure - */ -struct dentry *d_make_root(struct inode *inode) -{ - struct dentry *de; - - if (!inode) - return NULL; - - de = kzalloc(sizeof(struct dentry), GFP_KERNEL); - if (!de) { - iput(inode); - return NULL; - } - - de->d_inode = inode; - de->d_sb = inode->i_sb; - de->d_name.name = "/"; - de->d_name.len = 1; - - return de; -} - -/** - * iput() - Release a reference to an inode - * @inode: Inode to release - * - * Decrements the inode reference count. When the reference count reaches - * zero and the inode has no links, the inode is evicted (freed). - */ -void iput(struct inode *inode) -{ - if (!inode) - return; - - if (atomic_dec_and_test(&inode->i_count)) { - /* Last reference - check if inode should be evicted */ - if (inode->i_nlink == 0 && inode->i_sb && - inode->i_sb->s_op && inode->i_sb->s_op->evict_inode) { - inode->i_sb->s_op->evict_inode(inode); - /* Sync dirty buffers after eviction */ - bh_cache_sync(); - } - } -} +/* d_make_root() and iput() are now in fs/linux_fs.c */ /* percpu_init_rwsem is now in linux/percpu.h */ diff --git a/fs/linux_fs.c b/fs/linux_fs.c index 04f4c551f0b..db2b3b3942a 100644 --- a/fs/linux_fs.c +++ b/fs/linux_fs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -657,3 +658,91 @@ const struct file_operations generic_ro_fops = { const struct inode_operations page_symlink_inode_operations = { }; + +/** + * alloc_inode_sb() - Allocate an inode associated with a super block + * @sb: Super block the inode will belong to + * @cache: kmem_cache to allocate from + * @gfp: Allocation flags + * Return: Newly allocated inode, or NULL on failure + */ +void *alloc_inode_sb(struct super_block *sb, struct kmem_cache *cache, + gfp_t gfp) +{ + return kmem_cache_alloc(cache, gfp); +} + +/** + * free_page() - Free a single page previously obtained via get_zeroed_page() + * @addr: Address returned by get_zeroed_page() + */ +void free_page(unsigned long addr) +{ + free((void *)addr); +} + +/** + * sb_set_blocksize() - Validate and record the block size on a super block + * @sb: Super block to update + * @size: Block size in bytes (must be 1024, 2048 or 4096) + * Return: @size on success, 0 on invalid block size + */ +int sb_set_blocksize(struct super_block *sb, int size) +{ + if (size != 1024 && size != 2048 && size != 4096) + return 0; + + sb->s_blocksize = size; + sb->s_blocksize_bits = ffs(size) - 1; + + return size; +} + +/** + * d_make_root() - Create a root dentry for an inode + * @inode: Inode to create a dentry for + * Return: Allocated dentry, or NULL on failure (the inode is released on + * failure via iput()) + */ +struct dentry *d_make_root(struct inode *inode) +{ + struct dentry *de; + + if (!inode) + return NULL; + + de = kzalloc(sizeof(*de), GFP_KERNEL); + if (!de) { + iput(inode); + return NULL; + } + + de->d_inode = inode; + de->d_sb = inode->i_sb; + de->d_name.name = "/"; + de->d_name.len = 1; + + return de; +} + +/** + * iput() - Release a reference to an inode + * @inode: Inode to release + * + * Decrement the inode reference count. When the reference count reaches + * zero and the inode has no links, evict the inode via its super block + * operations and flush any dirty buffers. + */ +void iput(struct inode *inode) +{ + if (!inode) + return; + + if (atomic_dec_and_test(&inode->i_count)) { + if (inode->i_nlink == 0 && inode->i_sb && + inode->i_sb->s_op && inode->i_sb->s_op->evict_inode) { + inode->i_sb->s_op->evict_inode(inode); + bh_cache_sync(); + } + } +}