linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v4 01/30] btrfs: pass bytenr directly to __process_pages_contig()
Date: Mon, 31 May 2021 16:50:37 +0800	[thread overview]
Message-ID: <20210531085106.259490-2-wqu@suse.com> (raw)
In-Reply-To: <20210531085106.259490-1-wqu@suse.com>

As a preparation for incoming subpage support, we need bytenr passed to
__process_pages_contig() directly, not the current page index.

So change the parameter and all callers to pass bytenr in.

With the modification, here we need to replace the old @index_ret with
@processed_end for __process_pages_contig(), but this brings a small
problem.

Normally we follow the inclusive return value, meaning @processed_end
should be the last byte we processed.

If parameter @start is 0, and we failed to lock any page, then we would
return @processed_end as -1, causing more problems for
__unlock_for_delalloc().

So here for @processed_end, we use two different return value patterns.
If we have locked any page, @processed_end will be the last byte of
locked page.
Or it will be @start otherwise.

This change will impact lock_delalloc_pages(), so it needs to check
@processed_end to only unlock the range if we have locked any.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/extent_io.c | 57 ++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 20 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 6f023f800bd6..95d61e03f33f 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1810,8 +1810,8 @@ bool btrfs_find_delalloc_range(struct extent_io_tree *tree, u64 *start,
 
 static int __process_pages_contig(struct address_space *mapping,
 				  struct page *locked_page,
-				  pgoff_t start_index, pgoff_t end_index,
-				  unsigned long page_ops, pgoff_t *index_ret);
+				  u64 start, u64 end, unsigned long page_ops,
+				  u64 *processed_end);
 
 static noinline void __unlock_for_delalloc(struct inode *inode,
 					   struct page *locked_page,
@@ -1824,7 +1824,7 @@ static noinline void __unlock_for_delalloc(struct inode *inode,
 	if (index == locked_page->index && end_index == index)
 		return;
 
-	__process_pages_contig(inode->i_mapping, locked_page, index, end_index,
+	__process_pages_contig(inode->i_mapping, locked_page, start, end,
 			       PAGE_UNLOCK, NULL);
 }
 
@@ -1834,19 +1834,19 @@ static noinline int lock_delalloc_pages(struct inode *inode,
 					u64 delalloc_end)
 {
 	unsigned long index = delalloc_start >> PAGE_SHIFT;
-	unsigned long index_ret = index;
 	unsigned long end_index = delalloc_end >> PAGE_SHIFT;
+	u64 processed_end = delalloc_start;
 	int ret;
 
 	ASSERT(locked_page);
 	if (index == locked_page->index && index == end_index)
 		return 0;
 
-	ret = __process_pages_contig(inode->i_mapping, locked_page, index,
-				     end_index, PAGE_LOCK, &index_ret);
-	if (ret == -EAGAIN)
+	ret = __process_pages_contig(inode->i_mapping, locked_page, delalloc_start,
+				     delalloc_end, PAGE_LOCK, &processed_end);
+	if (ret == -EAGAIN && processed_end > delalloc_start)
 		__unlock_for_delalloc(inode, locked_page, delalloc_start,
-				      (u64)index_ret << PAGE_SHIFT);
+				      processed_end);
 	return ret;
 }
 
@@ -1941,12 +1941,14 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode,
 
 static int __process_pages_contig(struct address_space *mapping,
 				  struct page *locked_page,
-				  pgoff_t start_index, pgoff_t end_index,
-				  unsigned long page_ops, pgoff_t *index_ret)
+				  u64 start, u64 end, unsigned long page_ops,
+				  u64 *processed_end)
 {
+	pgoff_t start_index = start >> PAGE_SHIFT;
+	pgoff_t end_index = end >> PAGE_SHIFT;
+	pgoff_t index = start_index;
 	unsigned long nr_pages = end_index - start_index + 1;
 	unsigned long pages_processed = 0;
-	pgoff_t index = start_index;
 	struct page *pages[16];
 	unsigned ret;
 	int err = 0;
@@ -1954,17 +1956,19 @@ static int __process_pages_contig(struct address_space *mapping,
 
 	if (page_ops & PAGE_LOCK) {
 		ASSERT(page_ops == PAGE_LOCK);
-		ASSERT(index_ret && *index_ret == start_index);
+		ASSERT(processed_end && *processed_end == start);
 	}
 
 	if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0)
 		mapping_set_error(mapping, -EIO);
 
 	while (nr_pages > 0) {
-		ret = find_get_pages_contig(mapping, index,
+		int found_pages;
+
+		found_pages = find_get_pages_contig(mapping, index,
 				     min_t(unsigned long,
 				     nr_pages, ARRAY_SIZE(pages)), pages);
-		if (ret == 0) {
+		if (found_pages == 0) {
 			/*
 			 * Only if we're going to lock these pages,
 			 * can we find nothing at @index.
@@ -2007,13 +2011,27 @@ static int __process_pages_contig(struct address_space *mapping,
 			put_page(pages[i]);
 			pages_processed++;
 		}
-		nr_pages -= ret;
-		index += ret;
+		nr_pages -= found_pages;
+		index += found_pages;
 		cond_resched();
 	}
 out:
-	if (err && index_ret)
-		*index_ret = start_index + pages_processed - 1;
+	if (err && processed_end) {
+		/*
+		 * Update @processed_end. I know this is awful since it has
+		 * two different return value patterns (inclusive vs exclusive).
+		 *
+		 * But the exclusive pattern is necessary if @start is 0, or we
+		 * underflow and check against processed_end won't work as
+		 * expected.
+		 */
+		if (pages_processed)
+			*processed_end = min(end,
+			((u64)(start_index + pages_processed) << PAGE_SHIFT) - 1);
+		else
+			*processed_end = start;
+
+	}
 	return err;
 }
 
@@ -2024,8 +2042,7 @@ void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
 	clear_extent_bit(&inode->io_tree, start, end, clear_bits, 1, 0, NULL);
 
 	__process_pages_contig(inode->vfs_inode.i_mapping, locked_page,
-			       start >> PAGE_SHIFT, end >> PAGE_SHIFT,
-			       page_ops, NULL);
+			       start, end, page_ops, NULL);
 }
 
 /*
-- 
2.31.1


  reply	other threads:[~2021-05-31  8:51 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-31  8:50 [PATCH v4 00/30] btrfs: add data write support for subpage Qu Wenruo
2021-05-31  8:50 ` Qu Wenruo [this message]
2021-05-31  8:50 ` [PATCH v4 02/30] btrfs: refactor the page status update into process_one_page() Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 03/30] btrfs: provide btrfs_page_clamp_*() helpers Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 04/30] btrfs: only require sector size alignment for end_bio_extent_writepage() Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 05/30] btrfs: make btrfs_dirty_pages() to be subpage compatible Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 06/30] btrfs: make __process_pages_contig() to handle subpage dirty/error/writeback status Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 07/30] btrfs: make end_bio_extent_writepage() to be subpage compatible Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 08/30] btrfs: make process_one_page() to handle subpage locking Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 09/30] btrfs: introduce helpers for subpage ordered status Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 10/30] btrfs: make page Ordered bit to be subpage compatible Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 11/30] btrfs: update locked page dirty/writeback/error bits in __process_pages_contig Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 12/30] btrfs: prevent extent_clear_unlock_delalloc() to unlock page not locked by __process_pages_contig() Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 13/30] btrfs: make btrfs_set_range_writeback() subpage compatible Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 14/30] btrfs: make __extent_writepage_io() only submit dirty range for subpage Qu Wenruo
2021-06-04 14:58   ` Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 15/30] btrfs: make btrfs_truncate_block() to be subpage compatible Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 16/30] btrfs: make btrfs_page_mkwrite() " Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 17/30] btrfs: reflink: make copy_inline_to_page() " Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 18/30] btrfs: fix the filemap_range_has_page() call in btrfs_punch_hole_lock_range() Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 19/30] btrfs: don't clear page extent mapped if we're not invalidating the full page Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 20/30] btrfs: extract relocation page read and dirty part into its own function Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 21/30] btrfs: make relocate_one_page() to handle subpage case Qu Wenruo
2021-05-31  8:50 ` [PATCH v4 22/30] btrfs: fix wild subpage writeback which does not have ordered extent Qu Wenruo
2021-06-02 16:25   ` David Sterba
2021-05-31  8:50 ` [PATCH v4 23/30] btrfs: disable inline extent creation for subpage Qu Wenruo
2021-05-31  8:51 ` [PATCH v4 24/30] btrfs: allow submit_extent_page() to do bio split " Qu Wenruo
2021-05-31  8:51 ` [PATCH v4 25/30] btrfs: reject raid5/6 fs " Qu Wenruo
2021-05-31  8:51 ` [PATCH v4 26/30] btrfs: fix a crash caused by race between prepare_pages() and btrfs_releasepage() Qu Wenruo
2021-05-31  8:51 ` [PATCH v4 27/30] btrfs: fix a use-after-free bug in writeback subpage helper Qu Wenruo
2021-06-02 16:48   ` David Sterba
2021-05-31  8:51 ` [PATCH v4 28/30] btrfs: fix a subpage false alert for relocating partial preallocated data extents Qu Wenruo
2021-05-31  8:51 ` [PATCH v4 29/30] btrfs: fix a subpage relocation data corruption Qu Wenruo
2021-05-31 10:26   ` Qu Wenruo
2021-06-01  1:07     ` Qu Wenruo
2021-06-02 17:10       ` David Sterba
2021-05-31  8:51 ` [PATCH v4 30/30] btrfs: allow read-write for 4K sectorsize on 64K page size systems Qu Wenruo
2021-06-02 17:37   ` David Sterba
2021-05-31  9:47 ` [PATCH v4 00/30] btrfs: add data write support for subpage Neal Gompa
2021-05-31  9:50   ` Qu Wenruo
2021-05-31 12:17     ` Neal Gompa
2021-05-31 13:08       ` Qu Wenruo
2021-05-31 14:09 ` David Sterba
2021-06-01  0:21   ` Qu Wenruo
2021-06-02  2:22 ` riteshh
2021-06-02  2:24   ` Qu Wenruo
2021-06-02  2:27     ` riteshh
2021-06-02 17:39   ` David Sterba
2021-06-02 17:57 ` David Sterba
2021-06-03  6:20   ` Qu Wenruo
2021-06-08  8:23 ` Anand Jain
2021-06-08  9:02   ` Qu Wenruo
2021-06-08  9:45     ` Anand Jain
2021-06-08  9:50       ` Qu Wenruo
2021-06-08 11:11         ` Anand Jain
2021-06-17 20:40           ` David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210531085106.259490-2-wqu@suse.com \
    --to=wqu@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).