readahead_folio() returns the next folio from the readahead control (rac) but it also drops the refcount on the folio that had been held by the rac. As such, there is only one refcount remaining on the folio (which is held by the page cache) after this returns. This is problematic because this opens a race where if the folio does not have an iomap_folio_state struct attached to it and the folio gets read in by the filesystem's IO helper, folio_end_read() may have already been called on the folio (which will unlock the folio) which allows the page cache to evict the folio (dropping the refcount and leading to the folio being freed) by the time iomap_read_end() runs. Switch to __readahead_folio(), which returns the folio with a reference held for the caller, and add explicit folio_put() calls when done with the folio. Fixes: d43558ae6729 ("iomap: track pending read bytes more optimally") Signed-off-by: Joanne Koong --- fs/iomap/buffered-io.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index fd9a2cf95620..96fab015371b 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -588,10 +588,11 @@ static int iomap_readahead_iter(struct iomap_iter *iter, if (ctx->cur_folio && offset_in_folio(ctx->cur_folio, iter->pos) == 0) { iomap_read_end(ctx->cur_folio, *cur_bytes_submitted); + folio_put(ctx->cur_folio); ctx->cur_folio = NULL; } if (!ctx->cur_folio) { - ctx->cur_folio = readahead_folio(ctx->rac); + ctx->cur_folio = __readahead_folio(ctx->rac); if (WARN_ON_ONCE(!ctx->cur_folio)) return -EINVAL; *cur_bytes_submitted = 0; @@ -639,8 +640,10 @@ void iomap_readahead(const struct iomap_ops *ops, if (ctx->ops->submit_read) ctx->ops->submit_read(ctx); - if (ctx->cur_folio) + if (ctx->cur_folio) { iomap_read_end(ctx->cur_folio, cur_bytes_submitted); + folio_put(ctx->cur_folio); + } } EXPORT_SYMBOL_GPL(iomap_readahead); -- 2.47.3