[PATCH 14/21] btrfs: writepage fixup lock rearrangement

Goldwyn Rodrigues
2023-03-02T22:25:40Z

Perform extent lock before pages while performing
writepage_fixup_worker.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/inode.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ed3553ff2c31..f879c65ee8cc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2722,6 +2722,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
u64 page_end;
int ret = 0;
bool free_delalloc_space = true;
+ bool flushed = false;

fixup = container_of(work, struct btrfs_writepage_fixup, work);
page = fixup->page;
@@ -2733,9 +2734,16 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
* This is similar to page_mkwrite, we need to reserve the space before
* we take the page lock.
*/
+reserve:
ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
PAGE_SIZE);
+ if (ret == -EDQUOT && !flushed) {
+ btrfs_qgroup_flush(inode->root);
+ flushed = true;
+ goto reserve;
+ }
again:
+ lock_extent(&inode->io_tree, page_start, page_end, NULL);
lock_page(page);

/*
@@ -2778,19 +2786,18 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
if (ret)
goto out_page;

- lock_extent(&inode->io_tree, page_start, page_end, &cached_state);
-
/* already ordered? We're done */
if (PageOrdered(page))
goto out_reserved;

ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE);
if (ordered) {
- unlock_extent(&inode->io_tree, page_start, page_end,
- &cached_state);
unlock_page(page);
+ unlock_extent(&inode->io_tree, page_start, page_end,
+ NULL);
btrfs_start_ordered_extent(ordered);
btrfs_put_ordered_extent(ordered);
+
goto again;
}

@@ -2813,7 +2820,6 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
if (free_delalloc_space)
btrfs_delalloc_release_space(inode, data_reserved, page_start,
PAGE_SIZE, true);
- unlock_extent(&inode->io_tree, page_start, page_end, &cached_state);
out_page:
if (ret) {
/*
--
2.39.2