]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iomap: release pages on atomic dio size mismatch
authorFengnan Chang <changfengnan@bytedance.com>
Fri, 12 Jun 2026 04:40:41 +0000 (12:40 +0800)
committerChristian Brauner <brauner@kernel.org>
Wed, 1 Jul 2026 13:26:24 +0000 (15:26 +0200)
If bio_iov_iter_get_pages() or the bounce helper succeeds but builds a
short bio, the REQ_ATOMIC size check rejects it before submission.  The
old error path only dropped the bio reference, leaving any pages already
attached to the bio unreleased.

Release or unbounce the pages before falling through to out_put_bio on
this error path.

This bug was reported by sashiko:
https://sashiko.dev/#/patchset/20260608073134.95964-1-changfengnan%40bytedance.com

Fixes: 9e0933c21c12 ("fs: iomap: Atomic write support")
Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
Link: https://patch.msgid.link/20260612044041.10677-1-changfengnan@bytedance.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/iomap/direct-io.c

index b485e3b191dafacaf916055931aefc6f4215c0bd..e2cd5f92babedbb642ed4b08bb9b5bd426f93a20 100644 (file)
@@ -369,7 +369,7 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter,
         */
        if ((op & REQ_ATOMIC) && WARN_ON_ONCE(ret != iomap_length(iter))) {
                ret = -EINVAL;
-               goto out_put_bio;
+               goto out_bio_release_pages;
        }
 
        if (iter->iomap.flags & IOMAP_F_INTEGRITY) {
@@ -393,6 +393,11 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter,
        iomap_dio_submit_bio(iter, dio, bio, pos);
        return ret;
 
+out_bio_release_pages:
+       if (dio->flags & IOMAP_DIO_BOUNCE)
+               bio_iov_iter_unbounce(bio, true, false);
+       else
+               bio_release_pages(bio, false);
 out_put_bio:
        bio_put(bio);
        return ret;