From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Wei Gao <wegao@suse.com>, Jan Kara <jack@suse.cz>,
Sasha Levin <sashal@kernel.org>,
jack@suse.com, linux-ext4@vger.kernel.org
Subject: [PATCH AUTOSEL 6.1 14/16] ext2: Handle fiemap on empty files to prevent EINVAL
Date: Sun, 3 Aug 2025 17:21:24 -0400 [thread overview]
Message-ID: <20250803212127.3548367-14-sashal@kernel.org> (raw)
In-Reply-To: <20250803212127.3548367-1-sashal@kernel.org>
From: Wei Gao <wegao@suse.com>
[ Upstream commit a099b09a3342a0b28ea330e405501b5b4d0424b4 ]
Previously, ext2_fiemap would unconditionally apply "len = min_t(u64, len,
i_size_read(inode));", When inode->i_size was 0 (for an empty file), this
would reduce the requested len to 0. Passing len = 0 to iomap_fiemap could
then result in an -EINVAL error, even for valid queries on empty files.
Link: https://github.com/linux-test-project/ltp/issues/1246
Signed-off-by: Wei Gao <wegao@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20250613152402.3432135-1-wegao@suse.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Based on my analysis of the commit and its context:
**Backport Status: YES**
This commit should be backported to stable kernel trees. Here's the
extensive analysis:
**1. Bug Fix Analysis:**
The commit fixes a user-visible bug where `fiemap` operations on empty
files (i_size = 0) could fail with -EINVAL. Looking at the code change
in fs/ext2/inode.c:
- **Before the fix**: `len = min_t(u64, len, i_size_read(inode));` would
set len to 0 for empty files
- **After the fix**: The code adds a special check:
```c
if (i_size == 0)
i_size = 1;
len = min_t(u64, len, i_size);
```
This ensures that even for empty files, we pass a non-zero length to
`iomap_fiemap()`.
**2. Root Cause:**
From examining fs/ioctl.c:175-176, I found that `fiemap_prep()`
explicitly returns -EINVAL when len is 0:
```c
if (*len == 0)
return -EINVAL;
```
This means `iomap_fiemap()` would fail when passed a zero length, which
is exactly what was happening for empty ext2 files.
**3. Impact Assessment:**
- **User-visible impact**: Applications using fiemap on empty ext2 files
would receive unexpected EINVAL errors
- **Test failure**: The commit references an LTP (Linux Test Project)
issue (#1246), indicating this breaks existing tests
- **Functional impact**: fiemap is a commonly used interface for
discovering file extent mappings, and it should work on empty files
(they simply have no extents)
**4. Fix Quality:**
- **Minimal and contained**: The fix adds only 10 lines of code with a
clear comment explaining the rationale
- **Safe approach**: Setting i_size to 1 for the length calculation is
safe because:
- It only affects the length passed to iomap_fiemap
- The comment explains this is specifically to avoid EINVAL from
iomap_fiemap
- The actual file size remains unchanged
- **No architectural changes**: This is a simple boundary condition fix
**5. Regression Risk:**
- **Low risk**: The change only affects the fiemap path for empty files
- **Well-tested path**: fiemap is a read-only operation
- **Clear boundary**: Only affects files where i_size == 0
**6. Stable Tree Criteria:**
This fix meets all the stable tree criteria:
- Fixes a real bug that users/tests hit
- Small, self-contained change
- No new features or architectural changes
- Clear fix for a specific problem
- Low risk of introducing regressions
**7. Similar Patterns:**
The comment in the fix mentions that "ext2_get_blocks() iterates
unmapped space block by block which is slow" - this suggests the min_t()
optimization is important for performance on large sparse files, but
shouldn't break functionality for empty files.
The fix properly balances maintaining the performance optimization while
ensuring correctness for the edge case of empty files.
fs/ext2/inode.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 5a32fcd55183..430ccd983491 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -860,9 +860,19 @@ int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
int ret;
+ loff_t i_size;
inode_lock(inode);
- len = min_t(u64, len, i_size_read(inode));
+ i_size = i_size_read(inode);
+ /*
+ * iomap_fiemap() returns EINVAL for 0 length. Make sure we don't trim
+ * length to 0 but still trim the range as much as possible since
+ * ext2_get_blocks() iterates unmapped space block by block which is
+ * slow.
+ */
+ if (i_size == 0)
+ i_size = 1;
+ len = min_t(u64, len, i_size);
ret = iomap_fiemap(inode, fieinfo, start, len, &ext2_iomap_ops);
inode_unlock(inode);
--
2.39.5
next prev parent reply other threads:[~2025-08-03 21:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-03 21:21 [PATCH AUTOSEL 6.1 01/16] hfs: fix slab-out-of-bounds in hfs_bnode_read() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 02/16] hfsplus: fix slab-out-of-bounds in hfsplus_bnode_read() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 03/16] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 04/16] hfsplus: don't use BUG_ON() in hfsplus_create_attributes_file() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 05/16] arm64: Handle KCOV __init vs inline mismatches Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 06/16] smb/server: avoid deadlock when linking with ReplaceIfExists Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 07/16] udf: Verify partition map count Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 08/16] drbd: add missing kref_get in handle_write_conflicts Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 09/16] hfs: fix not erasing deleted b-tree node issue Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 10/16] better lockdep annotations for simple_recursive_removal() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 11/16] ata: libata-sata: Disallow changing LPM state if not supported Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 12/16] fs/ntfs3: Add sanity check for file name Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 13/16] fs/ntfs3: correctly create symlink for relative path Sasha Levin
2025-08-03 21:21 ` Sasha Levin [this message]
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 15/16] fix locking in efi_secret_unlink() Sasha Levin
2025-08-03 21:21 ` [PATCH AUTOSEL 6.1 16/16] securityfs: don't pin dentries twice, once is enough Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250803212127.3548367-14-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=jack@suse.com \
--cc=jack@suse.cz \
--cc=linux-ext4@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=wegao@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox