linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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;
as well as URLs for NNTP newsgroup(s).