[PATCH] fs/ntfs3: restore the file size when fallocate() fails on a sparse file
From: Hengyu Liang
Date: Sat Oct 10 2026 - 00:52:50 EST
For a sparse file, ntfs_fallocate() first extends the file with
ntfs_set_size() and then allocates the clusters of the range.
However, when this allocation fails, the function returns without
putting the size back. As of now, a fallocate() that fails with ENOSPC
still leaves the file at the requested size, with a part of the range
allocated.
The issue can be reproduced on a volume mounted with the sparse option:
truncate -s 16M img
mkntfs -F -q img
mount -t ntfs3 -o loop,sparse img /mnt
dd if=/dev/zero of=/mnt/hole bs=512k count=1
dd if=/dev/zero of=/mnt/fill bs=4k
sync
rm /mnt/hole
sync
fallocate -l 1M /mnt/f
ls -l /mnt/f
df -k /mnt
The fallocate command fails with "No space left on device". Before this
patch, /mnt/f is then 1048576 bytes long and the available space has
dropped from 912K to 400K. After this patch, /mnt/f is empty and the
available space is still 912K.
This patch will set the size back when the allocation fails, with the
call that FALLOC_FL_KEEP_SIZE already uses.
Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Signed-off-by: Hengyu Liang <hengyul@xxxxxxxxxx>
---
fs/ntfs3/file.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 95dfe6878860..98fb4116031b 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -673,8 +673,12 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
err = attr_data_get_block(ni, vcn, cend - vcn,
&lcn, &clen, &new,
true, NULL, false);
- if (err)
+ if (err) {
+ /* Do not leave the file extended. */
+ if (new_size > i_size)
+ ntfs_set_size(inode, i_size);
goto out;
+ }
}
}
--
2.53.0