summaryrefslogtreecommitdiff
path: root/fs/buffer.c
diff options
context:
space:
mode:
authorMatthew Wilcox (Oracle) <willy@infradead.org>2026-05-28 18:31:23 +0100
committerChristian Brauner <brauner@kernel.org>2026-06-04 10:28:07 +0200
commit5059fb945ca895af80506c7a90d46b7308d6f6c5 (patch)
tree3474b55cd68c9e1d665f1e5bea0fda214ae078a4 /fs/buffer.c
parent44d325ebba175e73711a4bd90f30e1bc192242d9 (diff)
downloadlinux-next-5059fb945ca895af80506c7a90d46b7308d6f6c5.tar.gz
linux-next-5059fb945ca895af80506c7a90d46b7308d6f6c5.zip
buffer: Convert block_read_full_folio to bh_submit()
Avoid an extra indirect function call by using bh_submit() instead of submit_bh(). Since mark_buffer_async_read() would collapse to a single function call, inline it into block_read_full_folio() along with its extensive comment. Convert end_buffer_async_read_io() to bh_end_async_read(). Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Link: https://patch.msgid.link/20260528173150.1093780-11-willy@infradead.org Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index d96320c18acb..b668a73d48ec 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -402,11 +402,13 @@ static void decrypt_bh(struct work_struct *work)
}
/*
- * I/O completion handler for block_read_full_folio() - pages
+ * I/O completion handler for block_read_full_folio() - folios
* which come unlocked at the end of I/O.
*/
-static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate)
+static void bh_end_async_read(struct bio *bio)
{
+ struct buffer_head *bh;
+ bool uptodate = bio_endio_bh(bio, &bh);
struct inode *inode = bh->b_folio->mapping->host;
bool decrypt = fscrypt_inode_uses_fs_layer_crypto(inode);
struct fsverity_info *vi = NULL;
@@ -431,7 +433,7 @@ static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate)
}
return;
}
- uptodate = 0;
+ uptodate = false;
}
end_buffer_async_read(bh, uptodate);
}
@@ -494,33 +496,6 @@ void bh_end_async_write(struct bio *bio)
}
EXPORT_SYMBOL(bh_end_async_write);
-/*
- * If a page's buffers are under async readin (end_buffer_async_read
- * completion) then there is a possibility that another thread of
- * control could lock one of the buffers after it has completed
- * but while some of the other buffers have not completed. This
- * locked buffer would confuse end_buffer_async_read() into not unlocking
- * the page. So the absence of BH_Async_Read tells end_buffer_async_read()
- * that this buffer is not under async I/O.
- *
- * The page comes unlocked when it has no locked buffer_async buffers
- * left.
- *
- * PageLocked prevents anyone starting new async I/O reads any of
- * the buffers.
- *
- * PageWriteback is used to prevent simultaneous writeout of the same
- * page.
- *
- * PageLocked prevents anyone from starting writeback of a page which is
- * under read I/O (PageWriteback is only ever set against a locked page).
- */
-static void mark_buffer_async_read(struct buffer_head *bh)
-{
- bh->b_end_io = end_buffer_async_read_io;
- set_buffer_async_read(bh);
-}
-
void mark_buffer_async_write(struct buffer_head *bh)
{
bh->b_end_io = end_buffer_async_write;
@@ -2497,9 +2472,33 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
continue;
}
- mark_buffer_async_read(bh);
+ /*
+ * If a folio's buffers are under async readin
+ * (end_buffer_async_read completion) then there is a
+ * possibility that another thread of control could lock
+ * one of the buffers after it has completed but while
+ * some of the other buffers have not completed. This
+ * locked buffer would confuse end_buffer_async_read()
+ * into not unlocking the folio. So the absence of
+ * BH_Async_Read tells end_buffer_async_read() that this
+ * buffer is not under async I/O.
+ *
+ * The folio comes unlocked when it has no locked
+ * buffer_async buffers left.
+ *
+ * The folio lock prevents anyone starting new async
+ * I/O reads into any of the buffers.
+ *
+ * The writeback flag is used to prevent simultaneous
+ * writeout of the same folio.
+ *
+ * The folio lock prevents anyone from starting writeback
+ * of a folio which is under read I/O (the writeback
+ * flag is only ever set on a locked folio).
+ */
+ set_buffer_async_read(bh);
if (prev)
- submit_bh(REQ_OP_READ, prev);
+ bh_submit(prev, REQ_OP_READ, bh_end_async_read);
prev = bh;
} while (iblock++, (bh = bh->b_this_page) != head);
@@ -2513,7 +2512,7 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block)
* in this folio.
*/
if (prev)
- submit_bh(REQ_OP_READ, prev);
+ bh_submit(prev, REQ_OP_READ, bh_end_async_read);
else
folio_end_read(folio, !page_error);