]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
buffer: Add bh_submit()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 28 May 2026 17:31:15 +0000 (18:31 +0100)
committerChristian Brauner <brauner@kernel.org>
Thu, 4 Jun 2026 08:28:06 +0000 (10:28 +0200)
bh_submit() takes a bio_end_io allowing users to avoid the indirect
function call through bh->b_end_io, and eventually allowing us to remove
bh->b_end_io.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Link: https://patch.msgid.link/20260528173150.1093780-3-willy@infradead.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/buffer.c
include/linux/buffer_head.h

index d4e9a10d2a2655d83ee71ca176e2e9bd3fb90893..ea926963529e800ae372e718a97fd5aa47852d62 100644 (file)
@@ -1180,15 +1180,15 @@ static void buffer_set_crypto_ctx(struct bio *bio, const struct buffer_head *bh,
                        folio_pos(bh->b_folio) + bh_offset(bh), gfp_mask);
 }
 
-static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
-               enum rw_hint write_hint, struct writeback_control *wbc)
+static void __bh_submit(struct buffer_head *bh, blk_opf_t opf,
+               enum rw_hint write_hint, struct writeback_control *wbc,
+               bio_end_io_t end_bio)
 {
        const enum req_op op = opf & REQ_OP_MASK;
        struct bio *bio;
 
        BUG_ON(!buffer_locked(bh));
        BUG_ON(!buffer_mapped(bh));
-       BUG_ON(!bh->b_end_io);
        BUG_ON(buffer_delay(bh));
        BUG_ON(buffer_unwritten(bh));
 
@@ -1213,7 +1213,7 @@ static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
 
        bio_add_folio_nofail(bio, bh->b_folio, bh->b_size, bh_offset(bh));
 
-       bio->bi_end_io = end_bio_bh_io_sync;
+       bio->bi_end_io = end_bio;
        bio->bi_private = bh;
 
        /* Take care of bh's that straddle the end of the device */
@@ -1227,6 +1227,29 @@ static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
        blk_crypto_submit_bio(bio);
 }
 
+static void submit_bh_wbc(blk_opf_t opf, struct buffer_head *bh,
+                         enum rw_hint write_hint,
+                         struct writeback_control *wbc)
+{
+       BUG_ON(!bh->b_end_io);
+       __bh_submit(bh, opf, write_hint, wbc, end_bio_bh_io_sync);
+}
+
+/**
+ * bh_submit - Start I/O against a buffer head
+ * @bh: The buffer head to perform I/O on.
+ * @opf: Operation and flags for bio.
+ * @end_io: The routine to call when I/O has completed.
+ *
+ * If you need to do I/O on an individual bh (instead of allowing the
+ * page cache to do I/O on the folio that it is in), call this function.
+ */
+void bh_submit(struct buffer_head *bh, blk_opf_t opf, bio_end_io_t end_io)
+{
+       __bh_submit(bh, opf, WRITE_LIFE_NOT_SET, NULL, end_io);
+}
+EXPORT_SYMBOL(bh_submit);
+
 static struct buffer_head *__bread_slow(struct buffer_head *bh)
 {
        lock_buffer(bh);
index e4939e33b4b514a4f20bdb41315227902e1bc0c8..d59980e4adda2152bd5a64ab1c01656d25e0eac0 100644 (file)
@@ -240,6 +240,7 @@ int sync_dirty_buffer(struct buffer_head *bh);
 int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);
 void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);
 void submit_bh(blk_opf_t, struct buffer_head *);
+void bh_submit(struct buffer_head *, blk_opf_t, bio_end_io_t);
 void write_boundary_block(struct block_device *bdev,
                        sector_t bblock, unsigned blocksize);
 int bh_uptodate_or_lock(struct buffer_head *bh);