[PATCH] ext4: do not report inline conversion allocation failures as fs errors
From: Hengyu Liang
Date: Thu Oct 29 2026 - 22:57:57 EST
When truncate grows an inline-data file beyond its inline capacity,
ext4_setattr() first calls ext4_convert_inline_data(). If the conversion
fails, it jumps to err_out and passes the error to ext4_std_error().
Allocating the first block can fail with -ENOSPC or -EDQUOT on a healthy
filesystem. Reporting these as filesystem errors records an error in the
superblock and, with errors=remount-ro, aborts the journal and rejects
subsequent writes with -EROFS.
For example, create a filesystem with inline_data,quota and mount it with
usrquota,errors=remount-ro. Create a small inline file owned by a user with
a 1 MiB block quota, then let that user fill the quota in a second file.
Growing the inline file with ftruncate() returns EDQUOT, after which even
root can no longer create a file.
Return conversion errors directly, as other callers of
ext4_convert_inline_data() do. The conversion helper handles its own
cleanup, and lower layers report metadata and journal errors.
Fixes: ed9356a30e59 ("ext4: convert inline data to extents when truncate exceeds inline size")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Hengyu Liang <hengyul@xxxxxxxxxx>
---
Tested on x86-64 KVM with KASAN, comparing ext4/dev at 8c4f6e337634
with this patch (28 allocation-pressure cases per kernel):
- ENOSPC and EDQUOT with 1K/4K blocks, default/nodelalloc/data=journal,
buffered_iomap and bigalloc, using remount-ro and continue policies.
- Failed conversion preserves inline data; 16 repeated failures on the
patched kernel do not increase quota usage. Removing the allocation
limit permits a successful retry.
- Remount readback and e2fsck -fn pass for all 28 images per kernel.
- A device-mapper block-bitmap read failure still returns EIO, records a
filesystem error and rejects subsequent writes with EROFS.
fs/ext4/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 6ede3644a738..02011f65ab32 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -7123,7 +7123,7 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
attr->ia_size > EXT4_I(inode)->i_inline_size) {
error = ext4_convert_inline_data(inode);
if (error)
- goto err_out;
+ return error;
}
if (shrink) {
--
2.53.0