Re: [PATCH v4 02/10] btrfs: defrag: extract the page preparation code into one helper
From: David Sterba <hidden>
Date: 2021-07-01 16:52:01
On Thu, Jun 10, 2021 at 01:09:09PM +0800, Qu Wenruo wrote:
quoted hunk ↗ jump to hunk
In cluster_pages_for_defrag(), we have complex code block inside one for() loop. The code block is to prepare one page for defrag, this will ensure: - The page is locked and set up properly - No ordered extent exists in the page range - The page is uptodate - The writeback has finished This behavior is pretty common and will be reused by later defrag rework. So extract the code into its own helper, defrag_prepare_one_page(), for later usage, and cleanup the code by a little. Since we're here, also make the page check to be subpage compatible, which means we will also check page::private, not only page->mapping. Signed-off-by: Qu Wenruo <redacted> --- fs/btrfs/ioctl.c | 151 +++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 65 deletions(-)diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 05af6f5ff3ff..a06ceb8fdf28 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c@@ -1143,6 +1143,89 @@ static int should_defrag_range(struct inode *inode, u64 start, u32 thresh, return ret; } +/* + * Prepare one page to be defragged. + * + * This will ensure: + * - Returned page is locked and has been set up properly + * - No ordered extent exists in the page + * - The page is uptodate + * - The writeback has finished + */ +static struct page *defrag_prepare_one_page(struct btrfs_inode *inode, + unsigned long index) +{ + struct address_space *mapping = inode->vfs_inode.i_mapping; + gfp_t mask = btrfs_alloc_write_mask(mapping); + u64 page_start = index << PAGE_SHIFT;
page index must be either pgoff_t or u64