]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iomap: free the bio before completing the dio
authorChristoph Hellwig <hch@lst.de>
Mon, 26 Jan 2026 05:53:42 +0000 (06:53 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 28 Jan 2026 12:16:40 +0000 (05:16 -0700)
There are good arguments for processing the user completions ASAP vs.
freeing resources ASAP, but freeing the bio first here removes potential
use after free hazards when checking flags, and will simplify the
upcoming bounce buffer support.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/iomap/direct-io.c

index c1d5db85c8c78200415d1002b7ec596a18958be3..d4d52775ce256f16c96818d54e92ce615003dbcf 100644 (file)
@@ -214,7 +214,15 @@ static void iomap_dio_done(struct iomap_dio *dio)
 static void __iomap_dio_bio_end_io(struct bio *bio, bool inline_completion)
 {
        struct iomap_dio *dio = bio->bi_private;
-       bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
+
+       if (dio->flags & IOMAP_DIO_DIRTY) {
+               bio_check_pages_dirty(bio);
+       } else {
+               bio_release_pages(bio, false);
+               bio_put(bio);
+       }
+
+       /* Do not touch bio below, we just gave up our reference. */
 
        if (atomic_dec_and_test(&dio->ref)) {
                /*
@@ -225,13 +233,6 @@ static void __iomap_dio_bio_end_io(struct bio *bio, bool inline_completion)
                        dio->flags &= ~IOMAP_DIO_COMP_WORK;
                iomap_dio_done(dio);
        }
-
-       if (should_dirty) {
-               bio_check_pages_dirty(bio);
-       } else {
-               bio_release_pages(bio, false);
-               bio_put(bio);
-       }
 }
 
 void iomap_dio_bio_end_io(struct bio *bio)