diff mbox series

[3/4] btrfs: inode: move the timing of TestClearPagePrivate() in btrfs_invalidatepage()

Message ID 20201217045737.48100-4-wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: inode: btrfs_invalidatepage() related refactor and fix for subpage | expand

Commit Message

Qu Wenruo Dec. 17, 2020, 4:57 a.m. UTC
For current sectorsize == PAGE_ZIE case, there will only be at most one
ordered extent for one page.

But for subpage case, one page can contain several ordered extents, thus
current TestClearPagePrivate2() call will only finish ordered IO for the
first ordered extent, the remaining ones will be skipped, and cause
never-end ordered io.

This patch will move the TestClearPagePrivate2 before the loop, and save
the result, so that we can finish all ordered extents.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/inode.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b4d36d138008..eb493fbb65f9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8178,6 +8178,7 @@  static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 	u64 start;
 	u64 end;
 	int inode_evicting = inode->vfs_inode.i_state & I_FREEING;
+	bool cleared_private2;
 	bool found_ordered = false;
 	bool completed_ordered = false;
 
@@ -8197,6 +8198,8 @@  static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 
 	if (!inode_evicting)
 		lock_extent_bits(tree, page_start, page_end, &cached_state);
+
+	cleared_private2 = TestClearPagePrivate2(page);
 again:
 	start = page_start;
 	ordered = btrfs_lookup_ordered_range(inode, start, page_end - start + 1);
@@ -8214,11 +8217,12 @@  static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 					 EXTENT_DELALLOC |
 					 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
 					 EXTENT_DEFRAG, 1, 0, &cached_state);
+
 		/*
 		 * whoever cleared the private bit is responsible
 		 * for the finish_ordered_io
 		 */
-		if (TestClearPagePrivate2(page)) {
+		if (cleared_private2) {
 			spin_lock_irq(&ordered_tree->lock);
 			set_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags);
 			ordered->truncated_len = min(ordered->truncated_len,
@@ -8233,6 +8237,7 @@  static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 				completed_ordered = true;
 			}
 		}
+
 		btrfs_put_ordered_extent(ordered);
 		if (!inode_evicting) {
 			cached_state = NULL;