]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
block: respect iov_iter::nofault flag in bio_iov_iter_bounce_write()
authorQu Wenruo <wqu@suse.com>
Tue, 16 Jun 2026 08:12:36 +0000 (17:42 +0930)
committerJens Axboe <axboe@kernel.dk>
Tue, 16 Jun 2026 20:48:35 +0000 (14:48 -0600)
For the incoming usage of IOMAP_DIO_BOUNCE in btrfs, btrfs has set
iov_iter::nofault to prevent deadlock when a page fault is needed to
read out the buffer.

However bio_iov_iter_bounce_write() doesn't respect iov_iter::nofault
flag, and just call a plain copy_from_iter() so it can still trigger
page fault and cause deadlock in btrfs.

Fix it by utilizing copy_folio_from_iter_atomic() if nofault flag is
set, otherwise use copy_folio_from_iter().

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/9c165a314022b61566eb247852eb773ca6c70889.1781597506.git.wqu@suse.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/bio.c

index 96f40d39b62badf747400868f2f2bf375e548fad..f2a5f4d0a9672b622be37a05d78497880c86cd52 100644 (file)
@@ -1335,7 +1335,11 @@ static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
                        break;
                bio_add_folio_nofail(bio, folio, this_len, 0);
 
-               copied = copy_from_iter(folio_address(folio), this_len, iter);
+               if (iter->nofault)
+                       copied = copy_folio_from_iter_atomic(folio, 0, this_len,
+                                                            iter);
+               else
+                       copied = copy_folio_from_iter(folio, 0, this_len, iter);
                if (copied < this_len) {
                        /*
                         * Need to revert the iov iter for all bytes we have