mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 07:23:14 +00:00
btrfs: handle page locking in btrfs_page_end_writer_lock with no writers
There are several call sites of extent_clear_unlock_delalloc() which get @locked_page = NULL. So that extent_clear_unlock_delalloc() will try to call process_one_page() to unlock every page even the first page is not locked by btrfs_page_start_writer_lock(). This will trigger an ASSERT() in btrfs_subpage_end_and_test_writer() as previously we require every page passed to btrfs_subpage_end_and_test_writer() to be locked by btrfs_page_start_writer_lock(). But compression path doesn't go that way. Thankfully it's not hard to distinguish page locked by lock_page() and btrfs_page_start_writer_lock(). So do the check in btrfs_subpage_end_and_test_writer() so now it can handle both cases well. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
e55a0de185
commit
164674a76b
@ -292,6 +292,16 @@ bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info,
|
||||
|
||||
btrfs_subpage_assert(fs_info, page, start, len);
|
||||
|
||||
/*
|
||||
* We have call sites passing @lock_page into
|
||||
* extent_clear_unlock_delalloc() for compression path.
|
||||
*
|
||||
* This @locked_page is locked by plain lock_page(), thus its
|
||||
* subpage::writers is 0. Handle them in a special way.
|
||||
*/
|
||||
if (atomic_read(&subpage->writers) == 0)
|
||||
return true;
|
||||
|
||||
ASSERT(atomic_read(&subpage->writers) >= nbits);
|
||||
return atomic_sub_and_test(nbits, &subpage->writers);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user