diff options
author | Qu Wenruo <wqu@suse.com> | 2022-02-18 03:13:00 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2022-03-02 16:51:39 +0100 |
commit | c992fa1fd52380d0c4ced7b07479e877311ae645 (patch) | |
tree | a34136260ad76cd18d72aec61bb1e5df29dab215 /crypto/asymmetric_keys/tpm.asn1 | |
parent | btrfs: reduce extent threshold for autodefrag (diff) | |
download | linux-c992fa1fd52380d0c4ced7b07479e877311ae645.tar.xz linux-c992fa1fd52380d0c4ced7b07479e877311ae645.zip |
btrfs: subpage: fix a wrong check on subpage->writers
[BUG]
When looping btrfs/074 with 64K page size and 4K sectorsize, there is a
low chance (1/50~1/100) to crash with the following ASSERT() triggered
in btrfs_subpage_start_writer():
ret = atomic_add_return(nbits, &subpage->writers);
ASSERT(ret == nbits); <<< This one <<<
[CAUSE]
With more debugging output on the parameters of
btrfs_subpage_start_writer(), it shows a very concerning error:
ret=29 nbits=13 start=393216 len=53248
For @nbits it's correct, but @ret which is the returned value from
atomic_add_return(), it's not only larger than nbits, but also larger
than max sectors per page value (for 64K page size and 4K sector size,
it's 16).
This indicates that some call sites are not properly decreasing the value.
And that's exactly the case, in btrfs_page_unlock_writer(), due to the
fact that we can have page locked either by lock_page() or
process_one_page(), we have to check if the subpage has any writer.
If no writers, it's locked by lock_page() and we only need to unlock it.
But unfortunately the check for the writers are completely opposite:
if (atomic_read(&subpage->writers))
/* No writers, locked by plain lock_page() */
return unlock_page(page);
We directly unlock the page if it has writers, which is the completely
opposite what we want.
Thankfully the affected call site is only limited to
extent_write_locked_range(), so it's mostly affecting compressed write.
[FIX]
Just fix the wrong check condition to fix the bug.
Fixes: e55a0de18572 ("btrfs: rework page locking in __extent_writepage()")
CC: stable@vger.kernel.org # 5.16
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'crypto/asymmetric_keys/tpm.asn1')
0 files changed, 0 insertions, 0 deletions