All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Howells" <dhowells@redhat.com>
Cc: v9fs@lists.linux.dev, "Chuck Lever" <cel@kernel.org>,
	"Jeff Layton" <jlayton@kernel.org>,
	"Anna Schumaker" <anna@kernel.org>
Subject: Re: [PATCH v16 08/15] netfs: Change netfs_writeback_single() to not look inside the iterator
Date: Sat, 07 Nov 2026 18:09:35 +0000	[thread overview]
Message-ID: <sashiko-outbox-203152@kernel.org> (raw)
In-Reply-To: <20261107160823.1465553-9-dhowells@redhat.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] netfs: netfs_write_collection() wakes waiter before
  netfs_wb_end()
- [Medium] netfs: set wreq->i_size to len in netfs_writeback_single()
--

commit 4b137787e59ae6eefb0ddaed87ce3b7cc4ab57b8
Author: David Howells <dhowells@redhat.com>

netfs: Change netfs_writeback_single() to not look inside the iterator

This commit changes netfs_writeback_single() to pass the data iterator
directly to the cache as a single monolithic write and wait synchronously
for the write to complete.

> diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
> index e041023811ed0..f084a6796667f 100644
> --- a/fs/netfs/write_issue.c
> +++ b/fs/netfs/write_issue.c
[ ... ]
> @@ -787,36 +665,42 @@ int netfs_writeback_single(struct address_space *mapping,
>  		goto couldnt_start;
>  	}
>  
> +	wreq->buffer.iter = *iter;
> +	wreq->len = len;
> +	wreq->submitted = wreq->len;

[Severity: Medium]
Should netfs_writeback_single() also set wreq->i_size = len here?

netfs_create_write_req() initializes wreq->i_size via a separate
i_size_read(inode) call in netfs_alloc_request().  In afs_dir_writepages(),
the caller only holds down_read(&dvnode->validate_lock) when reading
i_size to pass as len, while concurrent RPC completions in
afs_apply_status() can update inode->i_size under cb_lock without holding
validate_lock.

If wreq->i_size does not match len and len is not a multiple of
cache->bsize, cachefiles_issue_write() skips tail padding because
start + len == wreq->i_size is false:

fs/cachefiles/io.c:cachefiles_issue_write() {
	...
	/* We also need to end on the cache granularity boundary */
	if (start + len == wreq->i_size) {
		size_t part = len & (cache->bsize - 1);
		size_t need = cache->bsize - part;

		if (part && stream->submit_extendable_to >= need) {
			len += need;
			subreq->len += need;
			subreq->io_iter.count += need;
		}
	}
	...
}

cachefiles_issue_write() then strips the unaligned tail, causing
cachefiles_collect_write() to hit WARN_ON(len & (cache->bsize - 1)) and
invalidate the cache object.

>  	__set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
>  	trace_netfs_write(wreq, netfs_write_trace_writeback_single);
>  	netfs_stat(&netfs_n_wh_writepages);
>  
> -	if (__test_and_set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags))
> -		wreq->netfs_ops->begin_writeback(wreq);
> +	for (int s = 0; s < NR_IO_STREAMS; s++) {
> +		struct netfs_io_subrequest *subreq;
> +		struct netfs_io_stream *stream = &wreq->io_streams[s];
> +
> +		if (!stream->avail)
> +			continue;
>  
> -	for (fq = (struct folio_queue *)iter->folioq; fq; fq = fq->next) {
> -		for (int slot = 0; slot < folioq_count(fq); slot++) {
> -			struct folio *folio = folioq_folio(fq, slot);
> -			size_t part = umin(folioq_folio_size(fq, slot), size);
> +		netfs_prepare_write(wreq, stream, 0);
> +		/* Allocation not allowed to fail in writeback. */
>  
> -			_debug("wbiter %lx %llx", folio->index, atomic64_read(&wreq->issued_to));
> +		subreq = stream->construct;
> +		subreq->len = wreq->len;
> +		stream->submit_len = subreq->len;
> +		stream->submit_extendable_to = iov_iter_count(iter) - len;
>  
> -			ret = netfs_write_folio_single(wreq, folio);
> -			if (ret < 0)
> -				goto stop;
> -			size -= part;
> -			if (size <= 0)
> -				goto stop;
> -		}
> +		netfs_issue_write(wreq, stream);
>  	}
>  
> -stop:
> -	for (int s = 0; s < NR_IO_STREAMS; s++)
> -		netfs_issue_write(wreq, &wreq->io_streams[s]);
>  	netfs_all_subreqs_queued(wreq);
> -
>  	netfs_wake_collector(wreq);
>  
> +	/* TODO: Might want to be async here if WB_SYNC_NONE, but then need to
> +	 * wait before modifying.
> +	 */
> +	ret = netfs_wait_for_write(wreq);
> +	if (ret > 0)
> +		ret = 0;

[Severity: Medium]
Can netfs_writeback_single() return to its caller before the collector
worker releases NETFS_ICTX_WB_LOCK?

Because NETFS_RREQ_OFFLOAD_COLLECTION is set, netfs_wait_for_write() sleeps
until the collector worker clears NETFS_RREQ_IN_PROGRESS, which happens in
netfs_write_collection() before netfs_wb_end() is called:

CPU0                              kworker
netfs_writeback_single()
  netfs_wb_begin(ictx, ...)
  ...
  netfs_wait_for_write(wreq)
                                  netfs_write_collection()
                                    netfs_wake_rreq_flag(...,
                                      NETFS_RREQ_IN_PROGRESS, ...)
  /* returns to caller */
  /* next writeback on inode */
  netfs_wb_begin(ictx, true)
    /* sees NETFS_ICTX_WB_LOCK */ <-- false lock conflict
                                    netfs_wb_end(ictx)

An immediate subsequent WB_SYNC_NONE writeback on the same inode can see
NETFS_ICTX_WB_LOCK still held, re-mark the inode dirty via
netfs_single_mark_inode_dirty(), and abort the writeback pass.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261107160823.1465553-1-dhowells@redhat.com?part=8

  reply	other threads:[~2026-11-07 18:09 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 16:08 [PATCH v16 00/15] netfs, iov_iter: Use a chain of bio_vec arrays instead of folio_queue David Howells
2026-11-07 16:08 ` [PATCH v16 01/15] Add a function to kmap one page of a multipage bio_vec David Howells
2026-11-07 16:15   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 02/15] iov_iter: Add a segmented queue of bio_vec[] David Howells
2026-11-07 16:31   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 03/15] netfs: Add some tools for managing bvecq chains David Howells
2026-11-07 16:46   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 04/15] iov_iter: Add an API document for the bvecq structure David Howells
2026-11-07 16:47   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 05/15] iov_iter: Add a bvecq kunit test David Howells
2026-11-07 17:01   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 06/15] afs: Fix an inconsistency in the symlink code David Howells
2026-11-07 17:09   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 07/15] netfs: Explicitly pass tail padding to netfs_writeback_single() David Howells
2026-11-07 17:46   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 08/15] netfs: Change netfs_writeback_single() to not look inside the iterator David Howells
2026-11-07 18:09   ` sashiko-bot [this message]
2026-11-07 16:08 ` [PATCH v16 09/15] afs: Use a bvecq to hold dir content rather than folioq David Howells
2026-11-07 18:34   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 10/15] cifs: Use a bvecq for buffering instead of a folioq David Howells
2026-11-07 18:51   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 11/15] smbdirect: Support ITER_BVECQ in smbdirect_map_sges_from_iter() David Howells
2026-11-07 18:57   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 12/15] netfs: Switch folioq to bvecq David Howells
2026-11-07 19:25   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 13/15] smbdirect: Remove support for ITER_FOLIOQ from smbdirect_map_sges_from_iter() David Howells
2026-11-07 19:29   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 14/15] iov_iter: Remove ITER_FOLIOQ David Howells
2026-11-07 19:31   ` sashiko-bot
2026-11-07 16:08 ` [PATCH v16 15/15] netfs: Remove folio_queue David Howells
2026-11-07 19:35   ` sashiko-bot

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=sashiko-outbox-203152@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anna@kernel.org \
    --cc=cel@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=jlayton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=v9fs@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.