From: "Pankaj Raghav (Samsung)" <pankaj.raghav@linux.dev>
To: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Cc: Christian Brauner <brauner@kernel.org>,
linux-fsdevel@vger.kernel.org,
"Darrick J . Wong" <djwong@kernel.org>,
Carlos Maiolino <cem@kernel.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Jan Kara <jack@suse.cz>, Matthew Wilcox <willy@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Ritesh Harjani <ritesh.list@gmail.com>,
Zhang Yi <yi.zhang@huawei.com>, Christoph Hellwig <hch@lst.de>,
Dave Chinner <dchinner@redhat.com>,
Daniel Gomez <da.gomez@kernel.org>, Theodore Tso <tytso@mit.edu>,
linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Dave Chinner <dgc@kernel.org>
Subject: Re: [RFC PATCH v3 04/11] iomap: Add initial support for buffered RWF_WRITETHROUGH
Date: Mon, 17 Aug 2026 15:20:12 +0200 [thread overview]
Message-ID: <aoMCtTAZFN_DlZjw@quentin> (raw)
In-Reply-To: <c108df815e3330e76f2d6adfde791a6e20a498b9.1785908600.git.ojaswin@linux.ibm.com>
I have added some minor comments. I haven't checked Sashiko's review, so
ignore them if it is a repeat.
> +
> + if (!wt_ctx->nr_bvecs)
> + goto exit;
> +
> + for (i = 0; i < wt_ctx->nr_bvecs; i++)
> + len += wt_ctx->bvec[i].bv_len;
> +
> + bio = bio_alloc(iomap->bdev, wt_ctx->nr_bvecs, opf, GFP_NOFS);
> + bio->bi_iter.bi_sector = iomap_sector(iomap, wt_ctx->bio_pos);
> + bio->bi_end_io = iomap_writethrough_bio_end_io;
> + bio->bi_private = wt_ctx;
> +
> + for (i = 0; i < wt_ctx->nr_bvecs; i++)
> + __bio_add_page(bio, wt_ctx->bvec[i].bv_page,
> + wt_ctx->bvec[i].bv_len,
> + wt_ctx->bvec[i].bv_offset);
bio_add_folio_nofail()?
> +
> + if (!error && wt_ops->writethrough_submit)
> + error = wt_ops->writethrough_submit(wt_ctx->inode, iomap,
> + wt_ctx->bio_pos, len);
> +
> +
> + atomic_inc(&wt_ctx->ref);
> +
> + /*
> + * In case of error we still need the I/O completion to run so we can
> + * release references and end writeback on the folios.
> + */
> + if (error) {
> + bio->bi_status = errno_to_blk_status(error);
> + bio_endio(bio);
> + return error;
> + }
> +
> + submit_bio(bio);
> + wt_ctx->nr_bvecs = 0;
> +
> +exit:
> + return 0;
<snip>
> +
> + if (!wt_ctx->nr_bvecs) {
> + wt_ctx->bio_pos = round_down(pos, bs);
> + submit_start_pos = pos;
> + }
> +
> + bvec_set_folio(&wt_ctx->bvec[wt_ctx->nr_bvecs], folio,
> + len_aligned, off_aligned);
> + wt_ctx->nr_bvecs++;
> +
> +put_folio:
> + __iomap_put_folio(iter, wt_ops->write_ops, written, folio);
> +
> + if (old_size < pos)
> + pagecache_isize_extended(iter->inode, old_size, pos);
Some new code has been added upstream to include VERITY. Probably the
same thing needs to be done here?
if (pos + written > old_size &&
!(iter->iomap.flags & IOMAP_F_FSVERITY)) {
i_size_write(iter->inode, pos + written);
iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
}
__iomap_put_folio(iter, write_ops, written, folio);
if (old_size < pos && !(iter->iomap.flags & IOMAP_F_FSVERITY))
pagecache_isize_extended(iter->inode, old_size, pos);
> +
> + cond_resched();
> + if (unlikely(written == 0)) {
> + iomap_write_failed(iter->inode, pos, bytes);
> + iov_iter_revert(i, copied);
> +
> + if (chunk > PAGE_SIZE)
> + chunk /= 2;
> + if (copied) {
> + bytes = copied;
> + goto retry;
> + }
> + } else {
> + total_written += written;
> + pending += written;
> + iomap_iter_advance(iter, written);
> + }
> +
> + /*
> + * If we fail to submit the bio, we immediately call the
> + * IO completion handler that records the error. We
> + * shall not retry anymore cause this could lead to
> + * infinite loops in case of non-transient errors.
> + */
> + if (wt_ctx->nr_bvecs == wt_ctx->max_bvecs) {
> + status = iomap_writethrough_try_submit(wt_ctx,
> + &iter->iomap, wt_ops, &pending);
> + if (status)
> + goto submit_failed;
> + }
> +
> + } while (iov_iter_count(i) && iomap_length(iter));
> +
> + if (wt_ctx->nr_bvecs) {
> + status = iomap_writethrough_try_submit(wt_ctx,
> + &iter->iomap, wt_ops, &pending);
> + if (status)
> + goto submit_failed;
> + }
> +
> + /*
> + * In case of an error, we only consider the bytes we were actually able
> + * to submit IO for as valid data and revert the iters accordingly
> + */
> + if (status) {
> + /*
> + * we still need to run the endio completion for cleanup work
> + * hence call the below helper to take care of it, if we haven't
> + * already done so. We can ignore the return value here.
> + */
> + iomap_writethrough_submit_bio(wt_ctx, &iter->iomap, wt_ops, status);
Do we even need to call iomap_writethrough_submit_bio() here?
In all the failure scenario we reach submit_failed directly right? In
the cases where we fail before copy_folio_from_iter_atomic(), we will
not have anything to do anyway, therefore, making the above call a no
op? Am I missing something?
> +
> +submit_failed:
> + iomap_write_failed(iter->inode, submit_start_pos, pending);
> + iomap_iter_revert(iter, pending);
> + iov_iter_revert(i, pending);
> + }
> +
> + return status;
> +}
> +
> static int iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i,
> const struct iomap_write_ops *write_ops)
> {
> @@ -1345,6 +1700,88 @@ int iomap_fsverity_write(struct file *file, loff_t pos, size_t length,
> }
> EXPORT_SYMBOL_GPL(iomap_fsverity_write);
>
> +ssize_t iomap_file_writethrough_write(struct kiocb *iocb, struct iov_iter *i,
> + const struct iomap_writethrough_ops *wt_ops,
> + void *private)
> +{
> + struct inode *inode = iocb->ki_filp->f_mapping->host;
> + struct iomap_iter iter = {
> + .inode = inode,
> + .pos = iocb->ki_pos,
> + .len = iov_iter_count(i),
> + .flags = IOMAP_WRITE | IOMAP_WRITETHROUGH,
> + .private = private,
> + };
> + struct iomap_writethrough_ctx *wt_ctx;
> + unsigned int max_bvecs;
> + ssize_t ret;
> + struct blk_plug plug;
> + size_t min_folio_bytes = PAGE_SIZE
> + << mapping_min_folio_order(inode->i_mapping);
mapping_min_folio_nrbytes can be used here.
> +
> + /*
> + * For now we don't support any other flag with WRITETHROUGH
> + */
> __folio_cancel_dirty(folio);
> }
> bool folio_clear_dirty_for_io(struct folio *folio);
> +bool folio_clear_dirty_for_writethrough(struct folio *folio);
> bool clear_page_dirty_for_io(struct page *page);
> void folio_invalidate(struct folio *folio, size_t offset, size_t length);
> bool noop_dirty_folio(struct address_space *mapping, struct folio *folio);
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index bd87262f2e34..9c8d91b926a7 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -451,10 +451,13 @@ typedef int __bitwise __kernel_rwf_t;
> /* prevent pipe and socket writes from raising SIGPIPE */
> #define RWF_NOSIGNAL ((__force __kernel_rwf_t)0x00000100)
>
> +/* buffered IO that is asynchronously written through to disk after write */
Isn't it synchronously written?
> +#define RWF_WRITETHROUGH ((__force __kernel_rwf_t)0x00000200)
> +
> /* mask of flags supported by the kernel */
> #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\
> RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC |\
> - RWF_DONTCACHE | RWF_NOSIGNAL)
> + RWF_DONTCACHE | RWF_NOSIGNAL | RWF_WRITETHROUGH)
>
--
Pankaj
next prev parent reply other threads:[~2026-08-17 13:20 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 6:28 [RFC PATCH v3 00/11] Add buffered write-through support to iomap & xfs Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 01/11] fs: Add counter to track inflight writes that need stable pages Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 02/11] mm: Refactor folio_clear_dirty_for_io() Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 03/11] iomap: Add helper to revert iomap iter Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 04/11] iomap: Add initial support for buffered RWF_WRITETHROUGH Ojaswin Mujoo
2026-08-17 13:20 ` Pankaj Raghav (Samsung) [this message]
2026-08-05 6:28 ` [RFC PATCH v3 05/11] xfs: Add RWF_WRITETHROUGH support to xfs Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 06/11] iomap: Add aio support to RWF_WRITETHROUGH Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 07/11] iomap: Add DSYNC " Ojaswin Mujoo
2026-08-17 13:26 ` Pankaj Raghav (Samsung)
2026-08-05 6:28 ` [RFC PATCH v3 08/11] fs: Introduce RWF_NOSERIAL flag to indicate parallel reads/writes Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 09/11] xfs: Implement RWF_NOSERIAL to parallelize RWF_WRITETHROUGH writes Ojaswin Mujoo
2026-08-17 13:33 ` Pankaj Raghav (Samsung)
2026-08-05 6:28 ` [RFC PATCH v3 10/11] iomap: Avoid folio dirtying in case of RWF_WRITETHROUGH Ojaswin Mujoo
2026-08-05 6:28 ` [RFC PATCH v3 11/11] iomap: Handle deadlock due to repeating folios in RWF_WRITETHROUGH Ojaswin Mujoo
2026-08-05 6:35 ` [RFC PATCH v3 00/11] Add buffered write-through support to iomap & xfs Ojaswin Mujoo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aoMCtTAZFN_DlZjw@quentin \
--to=pankaj.raghav@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=da.gomez@kernel.org \
--cc=dchinner@redhat.com \
--cc=dgc@kernel.org \
--cc=djwong@kernel.org \
--cc=hch@lst.de \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-xfs@vger.kernel.org \
--cc=ojaswin@linux.ibm.com \
--cc=ritesh.list@gmail.com \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
--cc=yi.zhang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox