mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
btrfs: qgroup: fix a wrong length calculation in qgroup_free_reserved_data()
In that function, we round down the start position and round up the
ending position.
But during the calculation of @len, we use "round_up(start + len,
sectorsize)", which is the rounded up end position, not the rounded up
length.
Which results a much larger length, and later we are still using
"start + len", which is completely incorrect.
Fix it by declaring a local @aligned_start and @aligned_len and use them
instead.
Fixes: bc42bda223 ("btrfs: qgroup: Fix qgroup reserved space underflow by only freeing reserved ranges")
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
e0e6df7294
commit
9102b17951
|
|
@ -4339,12 +4339,13 @@ static int qgroup_free_reserved_data(struct btrfs_inode *inode,
|
|||
struct ulist_node *unode;
|
||||
struct ulist_iterator uiter;
|
||||
struct extent_changeset changeset;
|
||||
const u32 sectorsize = root->fs_info->sectorsize;
|
||||
const u64 aligned_start = round_down(start, sectorsize);
|
||||
const u64 aligned_len = round_up(start + len, sectorsize) - aligned_start;
|
||||
u64 freed = 0;
|
||||
int ret;
|
||||
|
||||
extent_changeset_init_bytes_only(&changeset);
|
||||
len = round_up(start + len, root->fs_info->sectorsize);
|
||||
start = round_down(start, root->fs_info->sectorsize);
|
||||
|
||||
ULIST_ITER_INIT(&uiter);
|
||||
while ((unode = ulist_next(&reserved->range_changed, &uiter))) {
|
||||
|
|
@ -4356,12 +4357,15 @@ static int qgroup_free_reserved_data(struct btrfs_inode *inode,
|
|||
|
||||
extent_changeset_release(&changeset);
|
||||
|
||||
/* Only free range in range [start, start + len) */
|
||||
if (range_start >= start + len ||
|
||||
range_start + range_len <= start)
|
||||
/*
|
||||
* Only free the range within
|
||||
* [aligned_start, aligned_start + aligned_len).
|
||||
*/
|
||||
if (range_start >= aligned_start + aligned_len ||
|
||||
range_start + range_len <= aligned_start)
|
||||
continue;
|
||||
free_start = max(range_start, start);
|
||||
free_len = min(start + len, range_start + range_len) -
|
||||
free_start = max(range_start, aligned_start);
|
||||
free_len = min(aligned_start + aligned_len, range_start + range_len) -
|
||||
free_start;
|
||||
/*
|
||||
* TODO: To also modify reserved->ranges_reserved to reflect
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user