diff options
author | Boris Burkov <boris@bur.io> | 2023-12-01 13:00:10 -0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2023-12-06 22:32:46 +0100 |
commit | 9e65bfca24cf1d77e4a5c7a170db5867377b3fe7 (patch) | |
tree | e8b84d6ae6fd7cbc7036f246ca1f4bfda1021cce /fs/btrfs/qgroup.h | |
parent | f63e1164b90b385cd832ff0fdfcfa76c3cc15436 (diff) | |
download | linux-stable-9e65bfca24cf1d77e4a5c7a170db5867377b3fe7.tar.gz linux-stable-9e65bfca24cf1d77e4a5c7a170db5867377b3fe7.tar.bz2 linux-stable-9e65bfca24cf1d77e4a5c7a170db5867377b3fe7.zip |
btrfs: fix qgroup_free_reserved_data int overflow
The reserved data counter and input parameter is a u64, but we
inadvertently accumulate it in an int. Overflowing that int results in
freeing the wrong amount of data and breaking reserve accounting.
Unfortunately, this overflow rot spreads from there, as the qgroup
release/free functions rely on returning an int to take advantage of
negative values for error codes.
Therefore, the full fix is to return the "released" or "freed" amount by
a u64 argument and to return 0 or negative error code via the return
value.
Most of the call sites simply ignore the return value, though some
of them handle the error and count the returned bytes. Change all of
them accordingly.
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/qgroup.h')
-rw-r--r-- | fs/btrfs/qgroup.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 855a4f978761..15b485506104 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -358,10 +358,10 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, /* New io_tree based accurate qgroup reserve API */ int btrfs_qgroup_reserve_data(struct btrfs_inode *inode, struct extent_changeset **reserved, u64 start, u64 len); -int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len); +int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len, u64 *released); int btrfs_qgroup_free_data(struct btrfs_inode *inode, struct extent_changeset *reserved, u64 start, - u64 len); + u64 len, u64 *freed); int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, enum btrfs_qgroup_rsv_type type, bool enforce); int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, |