Linux 9p file system development
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox