linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Yue Zhao <findns94@gmail.com>
To: stable@vger.kernel.org
Cc: linux-ext4@vger.kernel.org, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz,
	yi.zhang@huawei.com, tangyeechou@gmail.com,
	Yue Zhao <findns94@gmail.com>
Subject: [PATCH 1/1][For stable 5.4] mm: migrate: buffer_migrate_page_norefs() fallback migrate not uptodate pages
Date: Thu,  4 May 2023 00:34:26 +0800	[thread overview]
Message-ID: <20230503163426.5538-2-findns94@gmail.com> (raw)
In-Reply-To: <20230503163426.5538-1-findns94@gmail.com>

Recently we notice that ext4 filesystem occasionally fail to read
metadata from disk and report error message, but the disk and block
layer looks fine. After analyse, we lockon commit 88dbcbb3a484
("blkdev: avoid migration stalls for blkdev pages"). It provide a
migration method for the bdev, we could move page that has buffers
without extra users now, but it will lock the buffers on the page, which
breaks a lot of current filesystem's fragile metadata read operations,
like ll_rw_block() for common usage and ext4_read_bh_lock() for ext4,
these helpers just trylock the buffer and skip submit IO if it lock
failed, many callers just wait_on_buffer() and conclude IO error if the
buffer is not uptodate after buffer unlocked.

This issue could be easily reproduced by add some delay just after
buffer_migrate_lock_buffers() in __buffer_migrate_page() and do
fsstress on ext4 filesystem.

  EXT4-fs error (device pmem1): __ext4_find_entry:1658: inode #73193:
  comm fsstress: reading directory lblock 0
  EXT4-fs error (device pmem1): __ext4_find_entry:1658: inode #75334:
  comm fsstress: reading directory lblock 0

Something like ll_rw_block() should be used carefully and seems could
only be safely used for the readahead case. So the best way is to fix
the read operations in filesystem in the long run, but now let us avoid
this issue first. This patch avoid this issue by fallback to migrate
pages that are not uptodate like fallback_migrate_page(), those pages
that has buffers may probably do read operation soon.

Fixes: 88dbcbb3a484 ("blkdev: avoid migration stalls for blkdev pages")

Signed-off-by: Yue Zhao <findns94@gmail.com>
---
 mm/migrate.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/mm/migrate.c b/mm/migrate.c
index 034b0662fd3b..1e908e997147 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -751,6 +751,39 @@ static int __buffer_migrate_page(struct address_space *mapping,
 		return -EAGAIN;
 
 	head = page_buffers(page);
+
+	/*
+	 * If the mapped buffers on the page are not uptodate and has refcount,
+	 * some others may propably try to lock the buffer and submit read IO
+	 * through ll_rw_block(), but it will not submit IO once it failed to
+	 * lock the buffer, so try to fallback to migrate_page() to prevent
+	 * false positive EIO.
+	 */
+	if (check_refs) {
+		bool uptodate = true;
+		bool invalidate = false;
+
+		bh = head;
+		do {
+			if (buffer_mapped(bh) && !buffer_uptodate(bh)) {
+				uptodate = false;
+				if (atomic_read(&bh->b_count)) {
+					invalidate = true;
+					break;
+				}
+			}
+			bh = bh->b_this_page;
+		} while (bh != head);
+
+		if (!uptodate) {
+			if (invalidate)
+				invalidate_bh_lrus();
+			if (try_to_release_page(page, GFP_KERNEL))
+				return migrate_page(mapping, newpage, page, mode);
+			return -EAGAIN;
+		}
+	}
+
 	if (!buffer_migrate_lock_buffers(head, mode))
 		return -EAGAIN;
 
-- 
2.17.1


  reply	other threads:[~2023-05-03 16:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-03 16:34 [PATCH 0/1][For stable 5.4] mm: migrate: buffer_migrate_page_norefs() fallback migrate not uptodate pages Yue Zhao
2023-05-03 16:34 ` Yue Zhao [this message]
2023-05-06  0:58 ` Greg KH

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=20230503163426.5538-2-findns94@gmail.com \
    --to=findns94@gmail.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=akpm@linux-foundation.org \
    --cc=jack@suse.cz \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=stable@vger.kernel.org \
    --cc=tangyeechou@gmail.com \
    --cc=tytso@mit.edu \
    --cc=yi.zhang@huawei.com \
    /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).