mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
ext4: convert move_extent_per_page() to use folios
[ Upstream commit 6dd8fe86fa ]
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.com
Signed-off-by: Vishal 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: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 1898efcdbed3 ("block: update the stable_writes flag in bdev_add")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b92a8f591c
commit
4c78612e5f
@@ -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 @@ again:
|
|||||||
* 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 @@ again:
|
|||||||
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 @@ again:
|
|||||||
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 @@ data_copy:
|
|||||||
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 @@ data_copy:
|
|||||||
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 @@ data_copy:
|
|||||||
*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 @@ repair_branches:
|
|||||||
*err = -EIO;
|
*err = -EIO;
|
||||||
}
|
}
|
||||||
replaced_count = 0;
|
replaced_count = 0;
|
||||||
goto unlock_pages;
|
goto unlock_folios;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user