Fix dio_bio_alloc() to set BIO_PAGE_PINNED, not BIO_PAGE_REFFED, so that the bio code unpins the pinned pages rather than putting a ref on them. The issue was causing: WARNING: CPU: 6 PID: 2220 at mm/gup.c:76 try_get_folio This can be caused by creating a file on a loopback UDF filesystem, opening it O_DIRECT and making two writes to it from the same source buffer. Fixes: 1ccf164ec866 ("block: Use iov_iter_extract_pages() and page pinning in direct-io.c") Reported-by: kernel test robot <oliver.sang@xxxxxxxxx> Closes: https://lore.kernel.org/oe-lkp/202306120931.a9606b88-oliver.sang@xxxxxxxxx Signed-off-by: David Howells <dhowells@xxxxxxxxxx> cc: Christoph Hellwig <hch@xxxxxxxxxxxxx> cc: David Hildenbrand <david@xxxxxxxxxx> cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> cc: Jens Axboe <axboe@xxxxxxxxx> cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> cc: Jan Kara <jack@xxxxxxx> cc: Jeff Layton <jlayton@xxxxxxxxxx> cc: Jason Gunthorpe <jgg@xxxxxxxxxx> cc: Logan Gunthorpe <logang@xxxxxxxxxxxx> cc: Hillf Danton <hdanton@xxxxxxxx> cc: Christian Brauner <brauner@xxxxxxxxxx> cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> cc: linux-fsdevel@xxxxxxxxxxxxxxx cc: linux-block@xxxxxxxxxxxxxxx cc: linux-kernel@xxxxxxxxxxxxxxx cc: linux-mm@xxxxxxxxx --- fs/direct-io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 14049204cac8..04e810826ee8 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -415,7 +415,8 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio, else bio->bi_end_io = dio_bio_end_io; /* for now require references for all pages */ - bio_set_flag(bio, BIO_PAGE_REFFED); + if (dio->need_unpin) + bio_set_flag(bio, BIO_PAGE_PINNED); sdio->bio = bio; sdio->logical_offset_in_bio = sdio->cur_page_fs_offset; }