Commit 6dd8fe86 authored by Vishal Moola (Oracle)'s avatar Vishal Moola (Oracle) Committed by Andrew Morton

ext4: convert move_extent_per_page() to use folios

Patch series "Removing the try_to_release_page() wrapper", v3.

This patchset replaces the remaining calls of try_to_release_page() with
the folio equivalent: filemap_release_folio().  This allows us to remove
the wrapper.


This patch (of 4):

Convert move_extent_per_page() to use folios.  This change removes 5 calls
to compound_head() and is in preparation for the removal of the
try_to_release_page() wrapper.

Link: https://lkml.kernel.org/r/20221118073055.55694-1-vishal.moola@gmail.com
Link: https://lkml.kernel.org/r/20221118073055.55694-2-vishal.moola@gmail.comSigned-off-by: default avatarVishal Moola (Oracle) <vishal.moola@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Naoya Horiguchi <naoya.horiguchi@nec.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent a4bafffb
...@@ -253,6 +253,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -253,6 +253,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
{ {
struct inode *orig_inode = file_inode(o_filp); struct inode *orig_inode = file_inode(o_filp);
struct page *pagep[2] = {NULL, NULL}; struct page *pagep[2] = {NULL, NULL};
struct folio *folio[2] = {NULL, NULL};
handle_t *handle; handle_t *handle;
ext4_lblk_t orig_blk_offset, donor_blk_offset; ext4_lblk_t orig_blk_offset, donor_blk_offset;
unsigned long blocksize = orig_inode->i_sb->s_blocksize; unsigned long blocksize = orig_inode->i_sb->s_blocksize;
...@@ -313,6 +314,13 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -313,6 +314,13 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
* hold page's lock, if it is still the case data copy is not * hold page's lock, if it is still the case data copy is not
* necessary, just swap data blocks between orig and donor. * necessary, just swap data blocks between orig and donor.
*/ */
folio[0] = page_folio(pagep[0]);
folio[1] = page_folio(pagep[1]);
VM_BUG_ON_FOLIO(folio_test_large(folio[0]), folio[0]);
VM_BUG_ON_FOLIO(folio_test_large(folio[1]), folio[1]);
VM_BUG_ON_FOLIO(folio_nr_pages(folio[0]) != folio_nr_pages(folio[1]), folio[1]);
if (unwritten) { if (unwritten) {
ext4_double_down_write_data_sem(orig_inode, donor_inode); ext4_double_down_write_data_sem(orig_inode, donor_inode);
/* If any of extents in range became initialized we have to /* If any of extents in range became initialized we have to
...@@ -331,10 +339,10 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -331,10 +339,10 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
ext4_double_up_write_data_sem(orig_inode, donor_inode); ext4_double_up_write_data_sem(orig_inode, donor_inode);
goto data_copy; goto data_copy;
} }
if ((page_has_private(pagep[0]) && if ((folio_has_private(folio[0]) &&
!try_to_release_page(pagep[0], 0)) || !filemap_release_folio(folio[0], 0)) ||
(page_has_private(pagep[1]) && (folio_has_private(folio[1]) &&
!try_to_release_page(pagep[1], 0))) { !filemap_release_folio(folio[1], 0))) {
*err = -EBUSY; *err = -EBUSY;
goto drop_data_sem; goto drop_data_sem;
} }
...@@ -344,19 +352,21 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -344,19 +352,21 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
block_len_in_page, 1, err); block_len_in_page, 1, err);
drop_data_sem: drop_data_sem:
ext4_double_up_write_data_sem(orig_inode, donor_inode); ext4_double_up_write_data_sem(orig_inode, donor_inode);
goto unlock_pages; goto unlock_folios;
} }
data_copy: data_copy:
*err = mext_page_mkuptodate(pagep[0], from, from + replaced_size); *err = mext_page_mkuptodate(&folio[0]->page, from, from + replaced_size);
if (*err) if (*err)
goto unlock_pages; goto unlock_folios;
/* At this point all buffers in range are uptodate, old mapping layout /* At this point all buffers in range are uptodate, old mapping layout
* is no longer required, try to drop it now. */ * is no longer required, try to drop it now. */
if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) || if ((folio_has_private(folio[0]) &&
(page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) { !filemap_release_folio(folio[0], 0)) ||
(folio_has_private(folio[1]) &&
!filemap_release_folio(folio[1], 0))) {
*err = -EBUSY; *err = -EBUSY;
goto unlock_pages; goto unlock_folios;
} }
ext4_double_down_write_data_sem(orig_inode, donor_inode); ext4_double_down_write_data_sem(orig_inode, donor_inode);
replaced_count = ext4_swap_extents(handle, orig_inode, donor_inode, replaced_count = ext4_swap_extents(handle, orig_inode, donor_inode,
...@@ -369,13 +379,13 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -369,13 +379,13 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
replaced_size = replaced_size =
block_len_in_page << orig_inode->i_blkbits; block_len_in_page << orig_inode->i_blkbits;
} else } else
goto unlock_pages; goto unlock_folios;
} }
/* Perform all necessary steps similar write_begin()/write_end() /* Perform all necessary steps similar write_begin()/write_end()
* but keeping in mind that i_size will not change */ * but keeping in mind that i_size will not change */
if (!page_has_buffers(pagep[0])) if (!folio_buffers(folio[0]))
create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0); create_empty_buffers(&folio[0]->page, 1 << orig_inode->i_blkbits, 0);
bh = page_buffers(pagep[0]); bh = folio_buffers(folio[0]);
for (i = 0; i < data_offset_in_page; i++) for (i = 0; i < data_offset_in_page; i++)
bh = bh->b_this_page; bh = bh->b_this_page;
for (i = 0; i < block_len_in_page; i++) { for (i = 0; i < block_len_in_page; i++) {
...@@ -385,7 +395,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -385,7 +395,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
bh = bh->b_this_page; bh = bh->b_this_page;
} }
if (!*err) if (!*err)
*err = block_commit_write(pagep[0], from, from + replaced_size); *err = block_commit_write(&folio[0]->page, from, from + replaced_size);
if (unlikely(*err < 0)) if (unlikely(*err < 0))
goto repair_branches; goto repair_branches;
...@@ -395,11 +405,11 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -395,11 +405,11 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
*err = ext4_jbd2_inode_add_write(handle, orig_inode, *err = ext4_jbd2_inode_add_write(handle, orig_inode,
(loff_t)orig_page_offset << PAGE_SHIFT, replaced_size); (loff_t)orig_page_offset << PAGE_SHIFT, replaced_size);
unlock_pages: unlock_folios:
unlock_page(pagep[0]); folio_unlock(folio[0]);
put_page(pagep[0]); folio_put(folio[0]);
unlock_page(pagep[1]); folio_unlock(folio[1]);
put_page(pagep[1]); folio_put(folio[1]);
stop_journal: stop_journal:
ext4_journal_stop(handle); ext4_journal_stop(handle);
if (*err == -ENOSPC && if (*err == -ENOSPC &&
...@@ -430,7 +440,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -430,7 +440,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
*err = -EIO; *err = -EIO;
} }
replaced_count = 0; replaced_count = 0;
goto unlock_pages; goto unlock_folios;
} }
/** /**
......
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