From patchwork Wed Dec 31 22:29:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1161 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=1767220330; bh=237M7JClVSt5Yp0UfL4WPptafdQ3W1W1KyifOATRU8w=; 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=Evn8+UthLkJ4OG27ehIiPIiGalOjTMBRU8QYmBZaDvdJVdVzwgHxYeKHJgBlHP5NG 7OF+JOOZJz0p7ZBCzSyhHVo92QGxSin46PBFT87PXA4kRgavBZmtEVO7qo0pfGRnnD v0nCHpCc8RF/Bx/iZxXoa/zQWprlJqFwZRgsQexgBPYWUG5ohDeww1AHDqUK4EWIxq XZdwCetqhvOTXcmkxrNPns8llJHqlmB3BKmHjNbBxBrmwW6vbMHkc+oBiLL5vHxDKT ksPrs5Mf9mj61IOvqME4RzwRWeIQj/k2oim9+Cf2fHCDanbIAPE4gesYvu+N08VZ9I 4YA0VTX3QMLzA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id CFE5268F65 for ; Wed, 31 Dec 2025 15:32:10 -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 wrWEk60D35DR for ; Wed, 31 Dec 2025 15:32:10 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220329; bh=237M7JClVSt5Yp0UfL4WPptafdQ3W1W1KyifOATRU8w=; 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=F3eT24AzqveBVTdLVdWF3Y5xIlEv+s7x5m2mLPzaNP45Jznp2ebTAcejYtb6my3aJ HJfzdTREVj9dUVzPPwtKFCAWB17JldMTdE5UAJmyHj9eCnBsr6jmoCzbNkRUI0nbXk i3lWZgphV6Cj8xzZNVwAx1/CiE4g275tEyaXaAoKAlFQ1KwKiU/exvG2O5LyozqEwH J83003IMRWupr3gTioBXcCoqnr/Wk8TKTd3nKYoJlnRDp9MV5UyNCasbQBBtLAChZO 0v6UDEDHG6J12mNIt+qsZaBLZqq7/yPLgPN3gzdbJ96ES/VriovwsN6BIHedTQIsIU 73cav1w++79QA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id BC1B868FCB for ; Wed, 31 Dec 2025 15:32:09 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220327; bh=l2Dt9p39ZGfGmiHEIeIGEum3fkmUL3pUP/64W5cPmWY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BPUUPfrxOHwSibzwNPaitJK0C41UB1rXFWRj3xE+7hbcxcs/hYsO2ocPAHt3sM/ui OGUAGTNO447v7SLNtH1Y8h1spnxA8ccAa0YL8bbHnxUmASPixg7fHO+BjZG7KEIuqW P+tzW4KW+R9XJMaAUDiBZAgWcNCJczJtBGLNXa6HB/3upKIaInqqPznyoStg/2tW7O 8/UQmevQgKgbpTtdR347I3fVC+p2D3Qnx+aDBnowFQOA/rNcNWlD9tTjRGF3TJlHbz HWji+ifrSlM0Q7nv+3tc8TpdsYy2orUNWtqVpl98pBOaoecQxsUOpPB4qP1LOdi4E/ WiL5UBY0fGoKA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 69E2168F65; Wed, 31 Dec 2025 15:32:07 -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 90fbUfyNaoFF; Wed, 31 Dec 2025 15:32:07 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220327; bh=ZDnBl4+o5jS0XwI12hSHzEm40ilVf32srQdyqelCCok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XV3VYgfIUgZLQY0uxXStZqF52mwv9zn7I92SDKwAYk6dTxYX6+mHhc6xs7qptBjr6 cnRd3Ct4AJAWioLu6HEc2wT4JEGurbsfYJfDXLcUrc4ivCQtgGjO+7pwfthDup8esh Kl7Kkqu1M4HKft50JOQ3fY1GyHcfdtRlR3QlBIAs2mGpbURR3kQC0dcYg4omqmC5sK lPLhN/kyT7CX3Mp8XsA8gDoC3lzYCBOp0yxgXkq6kyeBBIG+gswcOW2cAvrTDK6fYR VOe2+LwLE3go3ReU1kyQyBn7QRuFZuDjetTxRaHVv39SKJFSKNmF5WOfTzQ2tO6R7J H7oYqvjsWnN+Q== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id BD82268F61; Wed, 31 Dec 2025 15:32:06 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Wed, 31 Dec 2025 15:29:56 -0700 Message-ID: <20251231223008.3251711-24-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251231223008.3251711-1-sjg@u-boot.org> References: <20251231223008.3251711-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 72I3UHKLU3Y3CDWC6XY3I6XCFC2Q5OM7 X-Message-ID-Hash: 72I3UHKLU3Y3CDWC6XY3I6XCFC2Q5OM7 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: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 23/26] ext4l: Update symlink to replace existing files 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 ext4l_ln() function returned -EEXIST when creating a symlink where a file already exists. This differs from the old ext4 implementation which deletes any existing file before creating the symlink (like ln -sf behaviour). Update ext4l_ln() to match this behaviour by calling __ext4_unlink() to remove any existing non-directory file before creating the symlink. Directories cannot be replaced with symlinks and return -EISDIR. This allows test_symlink3 to pass. Co-developed-by: Claude Signed-off-by: Simon Glass --- fs/ext4l/interface.c | 18 +++++++++++++++--- include/ext4l.h | 5 ++++- test/fs/ext4l.c | 4 ++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/ext4l/interface.c b/fs/ext4l/interface.c index c9dd25dd7b4..acd9ba5511e 100644 --- a/fs/ext4l/interface.c +++ b/fs/ext4l/interface.c @@ -1268,9 +1268,21 @@ int ext4l_ln(const char *filename, const char *linkname) return ret; if (dentry->d_inode) { - /* File already exists */ - ret = -EEXIST; - goto out; + /* File already exists - delete it first (like ln -sf) */ + if (S_ISDIR(dentry->d_inode->i_mode)) { + /* Cannot replace a directory with a symlink */ + ret = -EISDIR; + goto out; + } + + ret = __ext4_unlink(dir_dentry->d_inode, &dentry->d_name, + dentry->d_inode, dentry); + if (ret) + goto out; + + /* Release inode to free data blocks */ + iput(dentry->d_inode); + dentry->d_inode = NULL; } /* Create the symlink - filename is what the link points to */ diff --git a/include/ext4l.h b/include/ext4l.h index d0e420c8da2..882a27dad42 100644 --- a/include/ext4l.h +++ b/include/ext4l.h @@ -114,9 +114,12 @@ int ext4l_mkdir(const char *dirname); /** * ext4l_ln() - Create a symbolic link * + * Creates the symlink, replacing any existing file (like ln -sf). + * Refuses to replace a directory. + * * @filename: Path of symlink to create * @target: Target path the symlink points to - * Return: 0 on success, -EEXIST if file already exists, + * Return: 0 on success, -EISDIR if target is a directory, * -ENOTDIR if parent is not a directory, -EROFS if read-only, * negative on other errors */ diff --git a/test/fs/ext4l.c b/test/fs/ext4l.c index 1d46a752f32..c1d10dcc816 100644 --- a/test/fs/ext4l.c +++ b/test/fs/ext4l.c @@ -576,8 +576,8 @@ static int fs_test_ext4l_ln_norun(struct unit_test_state *uts) ut_asserteq(12, actread); ut_asserteq_str("hello world\n", buf); - /* Verify creating duplicate returns -EEXIST */ - ut_asserteq(-EEXIST, ext4l_ln(target, link_name)); + /* Verify creating duplicate succeeds (like ln -sf) */ + ut_assertok(ext4l_ln(target, link_name)); /* Verify creating symlink in non-existent parent returns -ENOENT */ ut_asserteq(-ENOENT, ext4l_ln(target, "/nonexistent/link"));