diff mbox series

[14/21] btrfs: writepage fixup lock rearrangement

Message ID 0513454915b54ca4572e30c5d42915fa987ad245.1677793433.git.rgoldwyn@suse.com (mailing list archive)
State New, archived
Headers show
Series Lock extents before pages | expand

Commit Message

Goldwyn Rodrigues March 2, 2023, 10:24 p.m. UTC
From: Goldwyn Rodrigues <rgoldwyn@suse.com>

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 mbox series

Patch

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) {
 		/*