Commit 7d003cc2 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: convert btrfs_writepage_fixup_worker() to use a folio

This function heavily messes with pages, instead update it to use a
folio.
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 0d117068
...@@ -2708,49 +2708,51 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ...@@ -2708,49 +2708,51 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL;
struct extent_changeset *data_reserved = NULL; struct extent_changeset *data_reserved = NULL;
struct page *page = fixup->page; struct page *page = fixup->page;
struct folio *folio = page_folio(page);
struct btrfs_inode *inode = fixup->inode; struct btrfs_inode *inode = fixup->inode;
struct btrfs_fs_info *fs_info = inode->root->fs_info; struct btrfs_fs_info *fs_info = inode->root->fs_info;
u64 page_start = page_offset(page); u64 page_start = folio_pos(folio);
u64 page_end = page_offset(page) + PAGE_SIZE - 1; u64 page_end = folio_pos(folio) + folio_size(folio) - 1;
int ret = 0; int ret = 0;
bool free_delalloc_space = true; bool free_delalloc_space = true;
/* /*
* This is similar to page_mkwrite, we need to reserve the space before * This is similar to page_mkwrite, we need to reserve the space before
* we take the page lock. * we take the folio lock.
*/ */
ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start, ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
PAGE_SIZE); folio_size(folio));
again: again:
lock_page(page); folio_lock(folio);
/* /*
* Before we queued this fixup, we took a reference on the page. * Before we queued this fixup, we took a reference on the folio.
* page->mapping may go NULL, but it shouldn't be moved to a different * folio->mapping may go NULL, but it shouldn't be moved to a different
* address space. * address space.
*/ */
if (!page->mapping || !PageDirty(page) || !PageChecked(page)) { if (!folio->mapping || !folio_test_dirty(folio) ||
!folio_test_checked(folio)) {
/* /*
* Unfortunately this is a little tricky, either * Unfortunately this is a little tricky, either
* *
* 1) We got here and our page had already been dealt with and * 1) We got here and our folio had already been dealt with and
* we reserved our space, thus ret == 0, so we need to just * we reserved our space, thus ret == 0, so we need to just
* drop our space reservation and bail. This can happen the * drop our space reservation and bail. This can happen the
* first time we come into the fixup worker, or could happen * first time we come into the fixup worker, or could happen
* while waiting for the ordered extent. * while waiting for the ordered extent.
* 2) Our page was already dealt with, but we happened to get an * 2) Our folio was already dealt with, but we happened to get an
* ENOSPC above from the btrfs_delalloc_reserve_space. In * ENOSPC above from the btrfs_delalloc_reserve_space. In
* this case we obviously don't have anything to release, but * this case we obviously don't have anything to release, but
* because the page was already dealt with we don't want to * because the folio was already dealt with we don't want to
* mark the page with an error, so make sure we're resetting * mark the folio with an error, so make sure we're resetting
* ret to 0. This is why we have this check _before_ the ret * ret to 0. This is why we have this check _before_ the ret
* check, because we do not want to have a surprise ENOSPC * check, because we do not want to have a surprise ENOSPC
* when the page was already properly dealt with. * when the folio was already properly dealt with.
*/ */
if (!ret) { if (!ret) {
btrfs_delalloc_release_extents(inode, PAGE_SIZE); btrfs_delalloc_release_extents(inode, folio_size(folio));
btrfs_delalloc_release_space(inode, data_reserved, btrfs_delalloc_release_space(inode, data_reserved,
page_start, PAGE_SIZE, page_start, folio_size(folio),
true); true);
} }
ret = 0; ret = 0;
...@@ -2758,7 +2760,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ...@@ -2758,7 +2760,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
} }
/* /*
* We can't mess with the page state unless it is locked, so now that * We can't mess with the folio state unless it is locked, so now that
* it is locked bail if we failed to make our space reservation. * it is locked bail if we failed to make our space reservation.
*/ */
if (ret) if (ret)
...@@ -2767,14 +2769,14 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ...@@ -2767,14 +2769,14 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
lock_extent(&inode->io_tree, page_start, page_end, &cached_state); lock_extent(&inode->io_tree, page_start, page_end, &cached_state);
/* already ordered? We're done */ /* already ordered? We're done */
if (PageOrdered(page)) if (folio_test_ordered(folio))
goto out_reserved; goto out_reserved;
ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE); ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE);
if (ordered) { if (ordered) {
unlock_extent(&inode->io_tree, page_start, page_end, unlock_extent(&inode->io_tree, page_start, page_end,
&cached_state); &cached_state);
unlock_page(page); folio_unlock(folio);
btrfs_start_ordered_extent(ordered); btrfs_start_ordered_extent(ordered);
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
goto again; goto again;
...@@ -2792,7 +2794,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ...@@ -2792,7 +2794,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
* *
* The page was dirty when we started, nothing should have cleaned it. * The page was dirty when we started, nothing should have cleaned it.
*/ */
BUG_ON(!PageDirty(page)); BUG_ON(!folio_test_dirty(folio));
free_delalloc_space = false; free_delalloc_space = false;
out_reserved: out_reserved:
btrfs_delalloc_release_extents(inode, PAGE_SIZE); btrfs_delalloc_release_extents(inode, PAGE_SIZE);
...@@ -2806,14 +2808,14 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ...@@ -2806,14 +2808,14 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
* We hit ENOSPC or other errors. Update the mapping and page * We hit ENOSPC or other errors. Update the mapping and page
* to reflect the errors and clean the page. * to reflect the errors and clean the page.
*/ */
mapping_set_error(page->mapping, ret); mapping_set_error(folio->mapping, ret);
btrfs_mark_ordered_io_finished(inode, page_folio(page), btrfs_mark_ordered_io_finished(inode, folio, page_start,
page_start, PAGE_SIZE, !ret); folio_size(folio), !ret);
clear_page_dirty_for_io(page); folio_clear_dirty_for_io(folio);
} }
btrfs_folio_clear_checked(fs_info, page_folio(page), page_start, PAGE_SIZE); btrfs_folio_clear_checked(fs_info, folio, page_start, PAGE_SIZE);
unlock_page(page); folio_unlock(folio);
put_page(page); folio_put(folio);
kfree(fixup); kfree(fixup);
extent_changeset_free(data_reserved); extent_changeset_free(data_reserved);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment