linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Max Kellermann <max.kellermann@ionos.com>, dhowells@redhat.com
Cc: willy@infradead.org, linux-cachefs@redhat.com,
	 linux-fsdevel@vger.kernel.org, ceph-devel@vger.kernel.org,
	 linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	xiubli@redhat.com, Ilya Dryomov <idryomov@gmail.com>
Subject: Re: [PATCH] fs/netfs/fscache_io: remove the obsolete "using_pgpriv2" flag
Date: Mon, 29 Jul 2024 08:56:34 -0400	[thread overview]
Message-ID: <d03ba5c264de1d3601853d91810108d9897661fb.camel@kernel.org> (raw)
In-Reply-To: <20240729091532.855688-1-max.kellermann@ionos.com>

On Mon, 2024-07-29 at 11:15 +0200, Max Kellermann wrote:
> This fixes a crash bug caused by commit ae678317b95e ("netfs: Remove
> deprecated use of PG_private_2 as a second writeback flag") by
> removing a leftover folio_end_private_2() call after all calls to
> folio_start_private_2() had been removed by the commit.
> 
> By calling folio_end_private_2() without folio_start_private_2(), the
> folio refcounter breaks and causes trouble like RCU stalls and general
> protection faults.
> 
> Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
> Fixes: ae678317b95e ("netfs: Remove deprecated use of PG_private_2 as a second writeback flag")
> Link: https://lore.kernel.org/ceph-devel/CAKPOu+_DA8XiMAA2ApMj7Pyshve_YWknw8Hdt1=zCy9Y87R1qw@mail.gmail.com/
> Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
> ---
>  fs/ceph/addr.c          |  2 +-
>  fs/netfs/fscache_io.c   | 29 +----------------------------
>  include/linux/fscache.h | 30 ++++--------------------------
>  3 files changed, 6 insertions(+), 55 deletions(-)
> 
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 8c16bc5250ef..485cbd1730d1 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -512,7 +512,7 @@ static void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, b
>  	struct fscache_cookie *cookie = ceph_fscache_cookie(ci);
>  
>  	fscache_write_to_cache(cookie, inode->i_mapping, off, len, i_size_read(inode),
> -			       ceph_fscache_write_terminated, inode, true, caching);
> +			       ceph_fscache_write_terminated, inode, caching);
>  }
>  #else
>  static inline void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, bool caching)
> diff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c
> index 38637e5c9b57..0d8f3f646598 100644
> --- a/fs/netfs/fscache_io.c
> +++ b/fs/netfs/fscache_io.c
> @@ -166,30 +166,10 @@ struct fscache_write_request {
>  	loff_t			start;
>  	size_t			len;
>  	bool			set_bits;
> -	bool			using_pgpriv2;
>  	netfs_io_terminated_t	term_func;
>  	void			*term_func_priv;
>  };
>  
> -void __fscache_clear_page_bits(struct address_space *mapping,
> -			       loff_t start, size_t len)
> -{
> -	pgoff_t first = start / PAGE_SIZE;
> -	pgoff_t last = (start + len - 1) / PAGE_SIZE;
> -	struct page *page;
> -
> -	if (len) {
> -		XA_STATE(xas, &mapping->i_pages, first);
> -
> -		rcu_read_lock();
> -		xas_for_each(&xas, page, last) {
> -			folio_end_private_2(page_folio(page));
> -		}
> -		rcu_read_unlock();
> -	}
> -}
> -EXPORT_SYMBOL(__fscache_clear_page_bits);
> -
>  /*
>   * Deal with the completion of writing the data to the cache.
>   */
> @@ -198,10 +178,6 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error,
>  {
>  	struct fscache_write_request *wreq = priv;
>  
> -	if (wreq->using_pgpriv2)
> -		fscache_clear_page_bits(wreq->mapping, wreq->start, wreq->len,
> -					wreq->set_bits);
> -
>  	if (wreq->term_func)
>  		wreq->term_func(wreq->term_func_priv, transferred_or_error,
>  				was_async);
> @@ -214,7 +190,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
>  			      loff_t start, size_t len, loff_t i_size,
>  			      netfs_io_terminated_t term_func,
>  			      void *term_func_priv,
> -			      bool using_pgpriv2, bool cond)
> +			      bool cond)
>  {
>  	struct fscache_write_request *wreq;
>  	struct netfs_cache_resources *cres;
> @@ -232,7 +208,6 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
>  	wreq->mapping		= mapping;
>  	wreq->start		= start;
>  	wreq->len		= len;
> -	wreq->using_pgpriv2	= using_pgpriv2;
>  	wreq->set_bits		= cond;
>  	wreq->term_func		= term_func;
>  	wreq->term_func_priv	= term_func_priv;
> @@ -260,8 +235,6 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
>  abandon_free:
>  	kfree(wreq);
>  abandon:
> -	if (using_pgpriv2)
> -		fscache_clear_page_bits(mapping, start, len, cond);
>  	if (term_func)
>  		term_func(term_func_priv, ret, false);
>  }
> diff --git a/include/linux/fscache.h b/include/linux/fscache.h
> index 9de27643607f..f8c52bddaa15 100644
> --- a/include/linux/fscache.h
> +++ b/include/linux/fscache.h
> @@ -177,8 +177,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
>  			      loff_t start, size_t len, loff_t i_size,
>  			      netfs_io_terminated_t term_func,
>  			      void *term_func_priv,
> -			      bool using_pgpriv2, bool cond);
> -extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);
> +			      bool cond);
>  
>  /**
>   * fscache_acquire_volume - Register a volume as desiring caching services
> @@ -573,24 +572,6 @@ int fscache_write(struct netfs_cache_resources *cres,
>  	return ops->write(cres, start_pos, iter, term_func, term_func_priv);
>  }
>  
> -/**
> - * fscache_clear_page_bits - Clear the PG_fscache bits from a set of pages
> - * @mapping: The netfs inode to use as the source
> - * @start: The start position in @mapping
> - * @len: The amount of data to unlock
> - * @caching: If PG_fscache has been set
> - *
> - * Clear the PG_fscache flag from a sequence of pages and wake up anyone who's
> - * waiting.
> - */
> -static inline void fscache_clear_page_bits(struct address_space *mapping,
> -					   loff_t start, size_t len,
> -					   bool caching)
> -{
> -	if (caching)
> -		__fscache_clear_page_bits(mapping, start, len);
> -}
> -
>  /**
>   * fscache_write_to_cache - Save a write to the cache and clear PG_fscache
>   * @cookie: The cookie representing the cache object
> @@ -600,7 +581,6 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
>   * @i_size: The new size of the inode
>   * @term_func: The function to call upon completion
>   * @term_func_priv: The private data for @term_func
> - * @using_pgpriv2: If we're using PG_private_2 to mark in-progress write
>   * @caching: If we actually want to do the caching
>   *
>   * Helper function for a netfs to write dirty data from an inode into the cache
> @@ -612,21 +592,19 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
>   * marked with PG_fscache.
>   *
>   * If given, @term_func will be called upon completion and supplied with
> - * @term_func_priv.  Note that if @using_pgpriv2 is set, the PG_private_2 flags
> - * will have been cleared by this point, so the netfs must retain its own pin
> - * on the mapping.
> + * @term_func_priv.
>   */
>  static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
>  					  struct address_space *mapping,
>  					  loff_t start, size_t len, loff_t i_size,
>  					  netfs_io_terminated_t term_func,
>  					  void *term_func_priv,
> -					  bool using_pgpriv2, bool caching)
> +					  bool caching)
>  {
>  	if (caching)
>  		__fscache_write_to_cache(cookie, mapping, start, len, i_size,
>  					 term_func, term_func_priv,
> -					 using_pgpriv2, caching);
> +					 caching);
>  	else if (term_func)
>  		term_func(term_func_priv, -ENOBUFS, false);
>  


(cc'ing the cephfs maintainers too)

Nice work! I'd prefer this patch over the first one. It looks like the
Fixes: commit went into v6.10. Did it go into earlier kernels too?

If so, what might be best is to take both of your patches. Have the
simple one first that just flips the flag, and mark that one for
stable. Then we can add the second patch on top to remove all of this
stuff for mainline.

Either way, you can add this to both patches:

Reviewed-by: Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2024-07-29 12:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-29  9:15 [PATCH] fs/netfs/fscache_io: remove the obsolete "using_pgpriv2" flag Max Kellermann
2024-07-29 12:56 ` Jeff Layton [this message]
2024-07-29 13:04   ` Max Kellermann
2024-07-29 15:35   ` Max Kellermann
2024-07-29 15:51     ` Jeff Layton
2024-07-30 16:01 ` [PATCH] netfs, ceph: Revert "netfs: Remove deprecated use of PG_private_2 as a second writeback flag" David Howells
2024-07-30 16:28   ` Max Kellermann
2024-07-30 20:00     ` Max Kellermann
2024-07-31  8:16     ` Max Kellermann
2024-07-31 10:41     ` David Howells
2024-07-31 11:37       ` Max Kellermann
2024-08-04 13:57         ` [PATCH] netfs: Set NETFS_RREQ_WRITE_TO_CACHE when caching is possible Hristo Venev
2024-08-04 23:22           ` Trond Myklebust
2024-08-05 15:34             ` Hristo Venev
2024-08-07 20:17       ` [RFC][PATCH] netfs: Fix handling of USE_PGPRIV2 and WRITE_TO_CACHE flags David Howells
2024-08-08 11:46       ` [PATCH v2] " David Howells
2024-08-08 21:31       ` [PATCH v3] " David Howells

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=d03ba5c264de1d3601853d91810108d9897661fb.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=dhowells@redhat.com \
    --cc=idryomov@gmail.com \
    --cc=linux-cachefs@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=max.kellermann@ionos.com \
    --cc=stable@vger.kernel.org \
    --cc=willy@infradead.org \
    --cc=xiubli@redhat.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).