* [PATCH v2 1/2] mpage: terminate read-ahead on read error
@ 2025-08-29 2:36 Chi Zhiling
2025-08-29 2:36 ` [PATCH v2 2/2] mpage: convert do_mpage_readpage() to return void type Chi Zhiling
0 siblings, 1 reply; 2+ messages in thread
From: Chi Zhiling @ 2025-08-29 2:36 UTC (permalink / raw)
To: linux-fsdevel, linux-mm, linux-kernel
Cc: Alexander Viro, Christian Brauner, Jan Kara, Matthew Wilcox,
Andrew Morton, Namjae Jeon, Sungjong Seo, Yuezhang Mo,
Chi Zhiling
From: Chi Zhiling <chizhiling@kylinos.cn>
For exFAT filesystems with 4MB read_ahead_size, removing the storage device
during read operations can delay EIO error reporting by several minutes.
This occurs because the read-ahead implementation in mpage doesn't handle
errors.
Another reason for the delay is that the filesystem requires metadata to
issue file read request. When the storage device is removed, the metadata
buffers are invalidated, causing mpage to repeatedly attempt to fetch
metadata during each get_block call.
The original purpose of this patch is terminate read ahead when we fail
to get metadata, to make the patch more generic, implement it by checking
folio status, instead of checking the return of get_block().
So, if a folio is synchronously unlocked and non-uptodate, should we
quit the read ahead?
I think it depends on whether the error is permanent or temporary, and
whether further read ahead might succeed.
A device being unplugged is one reason for returning such a folio, but
we could return it for many other reasons (e.g., metadata errors).
I think most errors won't be restored in a short time, so we should quit
read ahead when they occur.
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
---
diff from v1:
No functional changes. Improved code style as suggested
[v1]: https://lore.kernel.org/all/20250812072225.181798-1-chizhiling@163.com/T/#u
Just submit the final version, it doesn't matter to me if it doesn't merge :)
fs/mpage.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/mpage.c b/fs/mpage.c
index c5fd821fd30e..e4c11831f234 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -369,6 +369,12 @@ void mpage_readahead(struct readahead_control *rac, get_block_t get_block)
args.folio = folio;
args.nr_pages = readahead_count(rac);
args.bio = do_mpage_readpage(&args);
+ /*
+ * If read ahead failed synchronously, it may cause by removed
+ * device, or some filesystem metadata error.
+ */
+ if (!folio_test_locked(folio) && !folio_test_uptodate(folio))
+ break;
}
if (args.bio)
mpage_bio_submit_read(args.bio);
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH v2 2/2] mpage: convert do_mpage_readpage() to return void type
2025-08-29 2:36 [PATCH v2 1/2] mpage: terminate read-ahead on read error Chi Zhiling
@ 2025-08-29 2:36 ` Chi Zhiling
0 siblings, 0 replies; 2+ messages in thread
From: Chi Zhiling @ 2025-08-29 2:36 UTC (permalink / raw)
To: linux-fsdevel, linux-mm, linux-kernel
Cc: Alexander Viro, Christian Brauner, Jan Kara, Matthew Wilcox,
Andrew Morton, Namjae Jeon, Sungjong Seo, Yuezhang Mo,
Chi Zhiling
From: Chi Zhiling <chizhiling@kylinos.cn>
The return value of do_mpage_readpage() is arg->bio, which is already set
in the arg structure. Returning it again is redundant.
This patch changes the return type to void since the caller doesn't care
about the return value.
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
---
fs/mpage.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/mpage.c b/fs/mpage.c
index e4c11831f234..7dae5afc2b9e 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -148,7 +148,7 @@ struct mpage_readpage_args {
* represent the validity of its disk mapping and to decide when to do the next
* get_block() call.
*/
-static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
+static void do_mpage_readpage(struct mpage_readpage_args *args)
{
struct folio *folio = args->folio;
struct inode *inode = folio->mapping->host;
@@ -305,7 +305,7 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
else
args->last_block_in_bio = first_block + blocks_per_folio - 1;
out:
- return args->bio;
+ return;
confused:
if (args->bio)
@@ -368,7 +368,7 @@ void mpage_readahead(struct readahead_control *rac, get_block_t get_block)
prefetchw(&folio->flags);
args.folio = folio;
args.nr_pages = readahead_count(rac);
- args.bio = do_mpage_readpage(&args);
+ do_mpage_readpage(&args);
/*
* If read ahead failed synchronously, it may cause by removed
* device, or some filesystem metadata error.
@@ -392,7 +392,7 @@ int mpage_read_folio(struct folio *folio, get_block_t get_block)
.get_block = get_block,
};
- args.bio = do_mpage_readpage(&args);
+ do_mpage_readpage(&args);
if (args.bio)
mpage_bio_submit_read(args.bio);
return 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-08-29 2:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-29 2:36 [PATCH v2 1/2] mpage: terminate read-ahead on read error Chi Zhiling
2025-08-29 2:36 ` [PATCH v2 2/2] mpage: convert do_mpage_readpage() to return void type Chi Zhiling
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).