1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/fs
Filipe Manana da2dccd745 btrfs: fix hole expansion when writing at an offset beyond EOF
At btrfs_write_check() if our file's i_size is not sector size aligned and
we have a write that starts at an offset larger than the i_size that falls
within the same page of the i_size, then we end up not zeroing the file
range [i_size, write_offset).

The code is this:

    start_pos = round_down(pos, fs_info->sectorsize);
    oldsize = i_size_read(inode);
    if (start_pos > oldsize) {
        /* Expand hole size to cover write data, preventing empty gap */
        loff_t end_pos = round_up(pos + count, fs_info->sectorsize);

        ret = btrfs_cont_expand(BTRFS_I(inode), oldsize, end_pos);
        if (ret)
            return ret;
    }

So if our file's i_size is 90269 bytes and a write at offset 90365 bytes
comes in, we get 'start_pos' set to 90112 bytes, which is less than the
i_size and therefore we don't zero out the range [90269, 90365) by
calling btrfs_cont_expand().

This is an old bug introduced in commit 9036c10208 ("Btrfs: update hole
handling v2"), from 2008, and the buggy code got moved around over the
years.

Fix this by discarding 'start_pos' and comparing against the write offset
('pos') without any alignment.

This bug was recently exposed by test case generic/363 which tests this
scenario by polluting ranges beyond EOF with an mmap write and than verify
that after a file increases we get zeroes for the range which is supposed
to be a hole and not what we wrote with the previous mmaped write.

We're only seeing this exposed now because generic/363 used to run only
on xfs until last Sunday's fstests update.

The test was failing like this:

   $ ./check generic/363
   FSTYP         -- btrfs
   PLATFORM      -- Linux/x86_64 debian0 6.13.0-rc7-btrfs-next-185+ #17 SMP PREEMPT_DYNAMIC Mon Feb  3 12:28:46 WET 2025
   MKFS_OPTIONS  -- /dev/sdc
   MOUNT_OPTIONS -- /dev/sdc /home/fdmanana/btrfs-tests/scratch_1

   generic/363 0s ... [failed, exit status 1]- output mismatch (see /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad)
       --- tests/generic/363.out	2025-02-05 15:31:14.013646509 +0000
       +++ /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad	2025-02-05 17:25:33.112630781 +0000
       @@ -1 +1,46 @@
        QA output created by 363
       +READ BAD DATA: offset = 0xdcad, size = 0xd921, fname = /home/fdmanana/btrfs-tests/dev/junk
       +OFFSET      GOOD    BAD     RANGE
       +0x1609d     0x0000  0x3104  0x0
       +operation# (mod 256) for the bad data may be 4
       +0x1609e     0x0000  0x0472  0x1
       +operation# (mod 256) for the bad data may be 4
       ...
       (Run 'diff -u /home/fdmanana/git/hub/xfstests/tests/generic/363.out /home/fdmanana/git/hub/xfstests/results//generic/363.out.bad'  to see the entire diff)
   Ran: generic/363
   Failures: generic/363
   Failed 1 of 1 tests

Fixes: 9036c10208 ("Btrfs: update hole handling v2")
CC: stable@vger.kernel.org
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2025-02-11 23:09:03 +01:00
..
9p netfs: Work around recursion by abandoning retry if nothing read 2024-12-20 22:07:57 +01:00
adfs Merge patch series "adfs, affs, befs, hfs, hfsplus: convert to new mount api" 2024-10-08 14:41:53 +02:00
affs Merge patch series "adfs, affs, befs, hfs, hfsplus: convert to new mount api" 2024-10-08 14:41:53 +02:00
afs afs: Fix merge preference rule failure condition 2025-01-09 17:21:41 +01:00
autofs autofs: fix thinko in validate_dev_ioctl() 2024-10-28 13:16:56 +01:00
bcachefs - The series "resource: A couple of cleanups" from Andy Shevchenko 2024-11-25 16:09:48 -08:00
befs befs: convert befs to use the new mount api 2024-09-18 11:44:43 +02:00
bfs fs: Convert aops->write_begin to take a folio 2024-08-07 11:33:21 +02:00
btrfs btrfs: fix hole expansion when writing at an offset beyond EOF 2025-02-11 23:09:03 +01:00
cachefiles cachefiles: Parse the "secctx" immediately 2024-12-20 22:07:56 +01:00
ceph ceph: allocate sparse_ext map only for sparse reads 2024-12-16 23:25:44 +01:00
coda coda: use param->file for FSCONFIG_SET_FD 2024-08-19 13:45:03 +02:00
configfs configfs: improve item creation performance 2024-11-14 07:45:20 +01:00
cramfs vfs-6.11.module.description 2024-07-15 11:14:59 -07:00
crypto Random number generator updates for Linux 6.13-rc1. 2024-11-19 10:43:44 -08:00
debugfs fs: debugfs: fix open proxy for unsafe files 2025-01-10 09:41:53 +01:00
devpts
dlm dlm: fix dlm_recover_members refcount on error 2024-11-18 10:05:57 -06:00
ecryptfs vfs-6.13.ecryptfs.mount.api 2024-11-26 13:39:02 -08:00
efivarfs First batch of EFI fixes for v6.13 2024-12-15 15:33:41 -08:00
efs efs: fix the efs new mount api implementation 2024-10-15 15:58:36 +02:00
erofs erofs: use buffered I/O for file-backed mounts by default 2024-12-16 21:02:07 +08:00
exfat exfat: fix the infinite loop in __exfat_free_cluster() 2024-12-31 17:51:21 +09:00
exportfs fs: prepare for "explicit connectable" file handles 2024-11-15 11:34:57 +01:00
ext2 vfs-6.12.file 2024-09-16 09:14:02 +02:00
ext4 A lot of miscellaneous ext4 bug fixes and cleanups this cycle, most 2024-11-18 16:32:58 -08:00
f2fs f2fs-for-6.13-rc1 2024-11-26 12:50:58 -08:00
fat fat: fix uninitialized variable 2024-10-17 00:28:06 -07:00
freevxfs freevxfs: Replace one-element array with flexible array member 2024-11-06 10:42:06 +01:00
fuse fuse fixes for 6.13-rc7 2025-01-07 15:43:07 +01:00
gfs2 gfs2 changes 2024-11-26 12:34:50 -08:00
hfs hfs: Sanity check the root record 2024-12-02 15:32:19 +01:00
hfsplus vfs-6.13.misc 2024-11-18 09:35:30 -08:00
hostfs hostfs: Fix the NULL vs IS_ERR() bug for __filemap_get_folio() 2024-11-15 20:55:32 +01:00
hpfs hpfs: convert hpfs to use the new mount api 2024-10-08 14:41:53 +02:00
hugetlbfs mm: use aligned address in clear_gigantic_page() 2024-12-18 19:04:42 -08:00
iomap iomap: avoid avoid truncating 64-bit offset to 32 bits 2025-01-09 16:09:20 +01:00
isofs isofs: avoid memory leak in iocharset 2024-11-06 20:24:41 +01:00
jbd2 jbd2: flush filesystem device before updating tail sequence 2024-12-04 12:00:05 +01:00
jffs2 jffs2: Fix rtime decompressor 2024-12-05 12:31:40 +01:00
jfs A few more patches to add sanity checks in jfs 2024-11-21 09:59:59 -08:00
kernfs
lockd NFSD 6.13 Release Notes 2024-11-26 12:59:30 -08:00
minix buffer: Convert __block_write_begin() to take a folio 2024-08-07 11:33:36 +02:00
netfs netfs: Fix read-retry for fs with no ->prepare_read() 2025-01-09 17:20:04 +01:00
nfs vfs-6.13-rc7.fixes 2025-01-06 10:26:39 -08:00
nfs_common nfs_common: must not hold RCU while calling nfsd_file_put_local 2024-11-18 20:23:12 -05:00
nfsd nfsd-6.13 fixes: 2024-12-23 12:16:15 -08:00
nilfs2 nilfs2: fix buffer head leaks in calls to truncate_inode_pages() 2024-12-18 19:04:45 -08:00
nls move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
notify fs: relax assertions on failure to encode file handles 2024-12-19 15:18:27 +01:00
ntfs3 fs/ntfs3: Accumulated refactoring changes 2024-11-01 11:19:53 +03:00
ocfs2 ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv 2024-12-30 17:59:09 -08:00
omfs fs: Convert aops->write_begin to take a folio 2024-08-07 11:33:21 +02:00
openpromfs openpromfs: add missing MODULE_DESCRIPTION() macro 2024-06-20 09:46:01 +02:00
orangefs move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
overlayfs ovl: support encoding fid from inode with no alias 2025-01-06 15:43:55 +01:00
proc fs/proc/task_mmu: fix pagemap flags with PMD THP entries on 32bit 2024-12-30 17:59:08 -08:00
pstore Get rid of 'remove_new' relic from platform driver struct 2024-12-01 15:12:43 -08:00
qnx4 qnx4: add MODULE_DESCRIPTION() 2024-05-28 11:52:53 +02:00
qnx6 fs/qnx6: Fix building with GCC 15 2024-12-03 10:40:36 +01:00
quota quota: flush quota_release_work upon quota writeback 2024-11-26 22:54:00 +01:00
ramfs
romfs romfs: fix romfs_read_folio() 2024-08-21 22:32:58 +02:00
smb DFS (smb3 global namespace) client fix 2025-01-11 10:49:50 -08:00
squashfs Squashfs: fix variable overflow in squashfs_readpage_block 2024-10-30 20:14:12 -07:00
sysfs sysfs: bin_attribute: add const read/write callback variants 2024-11-05 14:00:28 +01:00
sysv buffer: Convert __block_write_begin() to take a folio 2024-08-07 11:33:36 +02:00
tests execve: Move KUnit tests to tests/ subdirectory 2024-07-22 18:25:47 -07:00
tracefs tracing: Fix tracefs mount options 2024-11-01 08:38:14 -04:00
ubifs This pull request contains updates for JFFS2, UBI and UBIFS: 2024-11-30 10:32:47 -08:00
udf udf: Verify inode link counts before performing rename 2024-11-26 22:54:24 +01:00
ufs ufs: ufs_sb_private_info: remove unused s_{2,3}apb fields 2024-11-12 19:02:12 -05:00
unicode Revert "unicode: Don't special case ignorable code points" 2024-12-11 14:11:23 -08:00
vboxsf fs: Convert aops->write_end to take a folio 2024-08-07 11:32:02 +02:00
verity fsverity: expose verified fsverity built-in signatures to LSMs 2024-08-20 14:03:18 -04:00
xfs xfs: lock dquot buffer before detaching dquot from b_li_list 2025-01-10 10:12:48 +01:00
zonefs zonefs fixes for 6.12-rc2 2024-10-02 12:02:15 -07:00
aio.c A rather large update for timekeeping and timers: 2024-11-19 16:35:06 -08:00
anon_inodes.c
attr.c fs: handle delegated timestamps in setattr_copy_mgtime 2024-10-10 10:20:51 +02:00
backing-file.c fs/backing_file: fix wrong argument in callback 2024-11-26 18:13:29 +01:00
bad_inode.c
binfmt_elf.c Revert "fs: don't block i_writecount during exec" 2024-11-27 12:51:30 +01:00
binfmt_elf_fdpic.c Revert "fs: don't block i_writecount during exec" 2024-11-27 12:51:30 +01:00
binfmt_flat.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
binfmt_misc.c Revert "fs: don't block i_writecount during exec" 2024-11-27 12:51:30 +01:00
binfmt_script.c fs: binfmt: add missing MODULE_DESCRIPTION() macros 2024-05-28 12:06:51 +02:00
bpf_fs_kfuncs.c bpf: Add kfunc bpf_get_dentry_xattr() to read xattr from dentry 2024-08-07 11:26:54 -07:00
buffer.c - The series "zram: optimal post-processing target selection" from 2024-11-23 09:58:07 -08:00
char_dev.c fs: Reorganize kerneldoc parameter names 2024-10-22 11:16:57 +02:00
compat_binfmt_elf.c binfmt_elf: Wire up AT_HWCAP3 at AT_HWCAP4 2024-10-17 18:38:49 +01:00
coredump.c coredump: add cond_resched() to dump_user_range 2024-10-22 11:16:58 +02:00
d_path.c
dax.c fsdax: dax_unshare_iter needs to copy entire blocks 2024-10-07 13:51:47 +02:00
dcache.c - The series "zram: optimal post-processing target selection" from 2024-11-23 09:58:07 -08:00
direct-io.c fs/direct-io: Remove linux/prefetch.h include 2024-08-19 13:45:02 +02:00
drop_caches.c sysctl: treewide: constify the ctl_table argument of proc_handlers 2024-07-24 20:59:29 +02:00
eventfd.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
eventpoll.c Networking changes for 6.13. 2024-11-21 08:28:08 -08:00
exec.c Revert "fs: don't block i_writecount during exec" 2024-11-27 12:51:30 +01:00
fcntl.c fs: require inode_owner_or_capable for F_SET_RW_HINT 2024-11-25 15:16:49 +01:00
fhandle.c vfs-6.13.exportfs 2024-11-26 13:26:15 -08:00
file.c fs: fix missing declaration of init_files 2024-12-17 13:38:46 +01:00
file_table.c Merge branch 'work.fdtable' into vfs.file 2024-10-30 09:58:02 +01:00
filesystems.c
fs-writeback.c Merge patch series "two little writeback cleanups v2" 2024-11-13 14:08:34 +01:00
fs_context.c
fs_parser.c vfs-6.13.ovl 2024-11-18 10:45:06 -08:00
fs_pin.c
fs_struct.c
fs_types.c
fsopen.c fdget(), more trivial conversions 2024-11-03 01:28:06 -05:00
init.c
inode.c - The series "zram: optimal post-processing target selection" from 2024-11-23 09:58:07 -08:00
internal.h sanitize struct filename and lookup flags handling in statx 2024-11-18 14:54:10 -08:00
ioctl.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
Kconfig reiserfs: The last commit 2024-10-21 16:29:38 +02:00
Kconfig.binfmt exec: Add KUnit test for bprm_stack_limits() 2024-06-19 13:13:55 -07:00
kernel_read_file.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
libfs.c sanitize struct filename and lookup flags handling in statx 2024-11-18 14:54:10 -08:00
locks.c fdget(), more trivial conversions 2024-11-03 01:28:06 -05:00
Makefile reiserfs: The last commit 2024-10-21 16:29:38 +02:00
mbcache.c
mnt_idmapping.c fuse update for 6.12 2024-09-24 15:29:42 -07:00
mount.h fs: kill MNT_ONRB 2025-01-09 16:58:50 +01:00
mpage.c fs/writeback: convert wbc_account_cgroup_owner to take a folio 2024-10-28 13:26:54 +01:00
namei.c sanitize xattr and io_uring interactions with it, 2024-11-18 12:44:25 -08:00
namespace.c vfs-6.14-rc7.mount.fixes 2025-01-09 17:03:21 +01:00
nsfs.c [tree-wide] finally take no_llseek out 2024-09-27 08:18:43 -07:00
open.c \n 2024-11-21 09:55:45 -08:00
pidfs.c pidfd: add ioctl to retrieve pid info 2024-10-24 13:54:51 +02:00
pipe.c [tree-wide] finally take no_llseek out 2024-09-27 08:18:43 -07:00
pnode.c
pnode.h
posix_acl.c acl: Annotate struct posix_acl with __counted_by() 2024-10-22 11:16:59 +02:00
proc_namespace.c fs: rename show_mnt_opts -> show_vfsmnt_opts 2024-06-28 14:36:43 +02:00
read_write.c the bulk of struct fd memory safety stuff 2024-11-18 12:24:06 -08:00
readdir.c introduce "fd_pos" class, convert fdget_pos() users to it. 2024-11-03 01:28:06 -05:00
remap_range.c convert vfs_dedupe_file_range(). 2024-11-03 01:28:07 -05:00
select.c do_pollfd(): convert to CLASS(fd) 2024-11-03 01:28:07 -05:00
seq_file.c fs: Reorganize kerneldoc parameter names 2024-10-22 11:16:57 +02:00
signalfd.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
splice.c fdget(), more trivial conversions 2024-11-03 01:28:06 -05:00
stack.c
stat.c sanitize struct filename and lookup flags handling in statx 2024-11-18 14:54:10 -08:00
statfs.c fdget_raw() users: switch to CLASS(fd_raw) 2024-11-03 01:28:06 -05:00
super.c fs/super.c: introduce get_tree_bdev_flags() 2024-10-21 14:30:26 +02:00
sync.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
sysctls.c
timerfd.c A rather large update for timekeeping and timers: 2024-11-19 16:35:06 -08:00
userfaultfd.c fork: do not invoke uffd on fork if error occurs 2024-10-28 21:40:38 -07:00
utimes.c fdget(), more trivial conversions 2024-11-03 01:28:06 -05:00
xattr.c xattr: remove redundant check on variable err 2024-11-06 13:00:01 -05:00