summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2026-01-26 08:53:42 +0300
committerJens Axboe <axboe@kernel.dk>2026-01-28 15:16:40 +0300
commit45cec0de6c8973660da279e44b24d37af49daeb6 (patch)
tree638092462715d2b2b1f940e103d16f137d3dcf4b
parente2fcff5bb4c48bf602082e5a1428ff7328f7558f (diff)
downloadlinux-45cec0de6c8973660da279e44b24d37af49daeb6.tar.xz
iomap: free the bio before completing the dio
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>
-rw-r--r--fs/iomap/direct-io.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index c1d5db85c8c7..d4d52775ce25 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -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)