@@ -2909,6 +2909,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;
@@ -2920,9 +2921,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);
/*
@@ -2965,19 +2973,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, 1);
btrfs_put_ordered_extent(ordered);
+
goto again;
}
@@ -3000,7 +3007,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) {
/*
Perform extent lock before pages while performing writepage_fixup_worker. Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> --- fs/btrfs/inode.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)