linux-stable/fs/btrfs
Ethan Lien 0355387ea5 btrfs: fix qgroup reserve overflow the qgroup limit
commit b642b52d0b upstream.

We use extent_changeset->bytes_changed in qgroup_reserve_data() to record
how many bytes we set for EXTENT_QGROUP_RESERVED state. Currently the
bytes_changed is set as "unsigned int", and it will overflow if we try to
fallocate a range larger than 4GiB. The result is we reserve less bytes
and eventually break the qgroup limit.

Unlike regular buffered/direct write, which we use one changeset for
each ordered extent, which can never be larger than 256M.  For
fallocate, we use one changeset for the whole range, thus it no longer
respects the 256M per extent limit, and caused the problem.

The following example test script reproduces the problem:

  $ cat qgroup-overflow.sh
  #!/bin/bash

  DEV=/dev/sdj
  MNT=/mnt/sdj

  mkfs.btrfs -f $DEV
  mount $DEV $MNT

  # Set qgroup limit to 2GiB.
  btrfs quota enable $MNT
  btrfs qgroup limit 2G $MNT

  # Try to fallocate a 3GiB file. This should fail.
  echo
  echo "Try to fallocate a 3GiB file..."
  fallocate -l 3G $MNT/3G.file

  # Try to fallocate a 5GiB file.
  echo
  echo "Try to fallocate a 5GiB file..."
  fallocate -l 5G $MNT/5G.file

  # See we break the qgroup limit.
  echo
  sync
  btrfs qgroup show -r $MNT

  umount $MNT

When running the test:

  $ ./qgroup-overflow.sh
  (...)

  Try to fallocate a 3GiB file...
  fallocate: fallocate failed: Disk quota exceeded

  Try to fallocate a 5GiB file...

  qgroupid         rfer         excl     max_rfer
  --------         ----         ----     --------
  0/5           5.00GiB      5.00GiB      2.00GiB

Since we have no control of how bytes_changed is used, it's better to
set it to u64.

CC: stable@vger.kernel.org # 4.14+
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Ethan Lien <ethanlien@synology.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-20 09:08:30 +02:00
..
tests Btrfs: fix selftests failure due to uninitialized i_mode in test inodes 2020-12-29 13:47:07 +01:00
acl.c
async-thread.c btrfs: fix memory ordering between normal and ordered work functions 2021-11-26 11:40:40 +01:00
async-thread.h Btrfs: fix crash during unmount due to race with delayed inode workers 2020-04-24 08:00:48 +02:00
backref.c btrfs: remove BUG_ON(!eie) in find_parent_nodes 2022-01-27 09:00:56 +01:00
backref.h
btrfs_inode.h
check-integrity.c btrfs: fix possible NULL-pointer dereference in integrity checks 2020-02-28 16:36:05 +01:00
check-integrity.h
compression.c btrfs: mark compressed range uptodate only if all bio succeed 2021-08-08 08:53:29 +02:00
compression.h btrfs: correctly validate compression type 2019-09-19 09:08:03 +02:00
ctree.c btrfs: fix race when picking most recent mod log operation for an old root 2021-05-22 10:57:20 +02:00
ctree.h Btrfs: fix unexpected failure of nocow buffered writes after snapshotting when low on space 2020-10-14 09:51:11 +02:00
dedupe.h
delayed-inode.c btrfs: abort transaction if we fail to update the delayed inode 2021-07-20 16:17:32 +02:00
delayed-inode.h
delayed-ref.c Btrfs: fix race between adding and putting tree mod seq elements and nodes 2020-02-14 16:32:19 -05:00
delayed-ref.h
dev-replace.c btrfs: Ensure replaced device doesn't have pending chunk allocation 2019-07-10 09:54:41 +02:00
dev-replace.h
dir-item.c
disk-io.c btrfs: check-integrity: fix a warning on write caching disabled disk 2021-12-08 08:46:54 +01:00
disk-io.h
export.c btrfs: export helpers for subvolume name/id resolution 2020-08-26 10:29:54 +02:00
export.h btrfs: export helpers for subvolume name/id resolution 2020-08-26 10:29:54 +02:00
extent-tree.c btrfs: unlock newly allocated extent buffer after error 2022-03-16 12:57:09 +01:00
extent_io.c Btrfs: fix missing error return if writeback for extent buffer never started 2020-11-18 18:27:54 +01:00
extent_io.h btrfs: fix qgroup reserve overflow the qgroup limit 2022-04-20 09:08:30 +02:00
extent_map.c Btrfs: fix race between using extent maps and merging them 2020-02-28 16:35:53 +01:00
extent_map.h
file-item.c btrfs: fix error handling in btrfs_del_csums 2021-06-10 12:43:51 +02:00
file.c btrfs: always wait on ordered extents at fsync time 2021-10-27 09:51:39 +02:00
free-space-cache.c btrfs: clarify error returns values in __load_free_space_cache 2021-03-03 18:22:43 +01:00
free-space-cache.h
free-space-tree.c
free-space-tree.h
hash.c
hash.h
inode-item.c
inode-map.c Btrfs: fix inode cache waiters hanging on path allocation failure 2020-01-27 14:46:46 +01:00
inode-map.h
inode.c Revert "btrfs: compression: don't try to compress if we don't have enough pages" 2021-09-22 11:45:16 +02:00
ioctl.c btrfs: fix metadata extent leak after failure to create subvolume 2021-05-22 10:57:15 +02:00
Kconfig btrfs: disable build on platforms having page size 256K 2021-07-20 16:17:32 +02:00
locking.c
locking.h
lzo.c
Makefile
math.h
ordered-data.c Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered extents 2020-02-28 16:36:14 +01:00
ordered-data.h
orphan.c
print-tree.c btrfs: require only sector size alignment for parent eb bytenr 2020-09-23 10:46:30 +02:00
print-tree.h
props.c btrfs: correctly validate compression type 2019-09-19 09:08:03 +02:00
props.h
qgroup.c btrfs: fix transaction leak and crash after RO remount caused by qgroup rescan 2021-01-23 15:48:42 +01:00
qgroup.h
raid56.c btrfs: fix raid6 qstripe kmap 2021-03-11 13:51:04 +01:00
raid56.h
rcu-string.h
reada.c btrfs: fix use-after-free on readahead extent after failure to create it 2020-11-05 11:07:00 +01:00
relocation.c btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s 2021-05-22 10:57:17 +02:00
root-tree.c btrfs: Don't panic when we can't find a root key 2019-05-31 06:47:20 -07:00
scrub.c btrfs: don't prematurely free work in scrub_missing_raid56_worker() 2019-12-31 12:37:53 +01:00
send.c btrfs: send: in case of IO error log it 2022-02-23 11:57:33 +01:00
send.h
struct-funcs.c
super.c btrfs: fix transaction leak and crash after RO remount caused by qgroup rescan 2021-01-23 15:48:42 +01:00
sysfs.c btrfs: sysfs: use NOFS for device creation 2020-08-26 10:29:54 +02:00
sysfs.h
transaction.c btrfs: clear defrag status of a root if starting transaction fails 2021-07-20 16:17:28 +02:00
transaction.h
tree-checker.c
tree-checker.h
tree-defrag.c
tree-log.c btrfs: fix lost error handling when replaying directory deletes 2021-11-26 11:40:22 +01:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c btrfs: handle ENOENT in btrfs_uuid_tree_iterate 2019-12-31 12:36:44 +01:00
volumes.c btrfs: tree-checker: Enhance chunk checker to validate chunk profile 2020-12-02 08:34:40 +01:00
volumes.h btrfs: Remove btrfs_bio::flags member 2019-12-17 20:39:16 +01:00
xattr.c
xattr.h
zlib.c
zstd.c