Linux XFS filesystem development
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Eric Sandeen <sandeen@redhat.com>
Cc: linux-xfs@vger.kernel.org, aalbersh@kernel.org
Subject: Re: [PATCH 2/3] libxfs: Return -ENOMEM on actual cache node allocation failures
Date: Fri, 25 Sep 2026 15:58:47 -0700	[thread overview]
Message-ID: <20260925225847.GC2705364@frogsfrogsfrogs> (raw)
In-Reply-To: <20260925194535.397036-3-sandeen@redhat.com>

On Fri, Sep 25, 2026 at 02:41:44PM -0500, Eric Sandeen wrote:
> Today, if we get an underlying ENOMEM from an actual cache node
> allocation attempt, it's indistinguishable from "current cache size
> is filled" and we'll keep doubling cache size to no avail until the
> size itself overflows.
> 
> This patch differentiates "no node returned" between the "cache full;
> grow it" case and the "underlying allocation actually got ENOMEM" case
> so that the caller can do the right thing, and return true ENOMEM
> up the stack for callers to handle.
> 
> Finally, actually check this returned error at the cache_node_get
> callsite (in __cache_lookup).
> 
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>  libxfs/cache.c | 22 ++++++++++++++++------
>  libxfs/rdwr.c  |  9 ++++-----
>  2 files changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/libxfs/cache.c b/libxfs/cache.c
> index a6dabf92..60bfcdc5 100644
> --- a/libxfs/cache.c
> +++ b/libxfs/cache.c
> @@ -285,7 +285,8 @@ cache_shake(
>   * Allocate a new hash node (updating atomic counter in the process),
>   * unless doing so will push us over the maximum cache size.
>   * Return 1 with nodep set on success.
> - * Return 0 and NULL nodep otherwise (cache full, or alloc failure)
> + * Return 0 and NULL nodep if the cache is full (caller should shake/expand).
> + * Return -ENOMEM and NULL nodep if the underlying allocation failed.
>   */
>  static int
>  cache_node_allocate(
> @@ -315,7 +316,7 @@ cache_node_allocate(
>  		cache->c_count--;
>  		pthread_mutex_unlock(&cache->c_mutex);
>  		*nodep = NULL;
> -		return 0;
> +		return -ENOMEM;
>  	}
>  	pthread_mutex_init(&node->cn_mutex, NULL);
>  	list_head_init(&node->cn_mru);
> @@ -373,8 +374,8 @@ __cache_node_purge(
>   * hit, in which case this will all be over quickly and painlessly.
>   * Otherwise, we allocate a new node, taking care not to expand the
>   * cache beyond the requested maximum size (shrink it if it would).
> - * Returns zero if hit in cache, one if a new node was allocated.  A node
> - * is always returned.
> + * Returns zero if hit in cache, one if a new node was allocated.  Returns
> + * -ENOMEM if allocation fails after cache shaking is exhausted.
>   */
>  int
>  cache_node_get(
> @@ -391,6 +392,7 @@ cache_node_get(
>  	unsigned int		hashidx;
>  	int			priority = 0;
>  	int			purged = 0;
> +	int			error = 0;
>  
>  	hashidx = cache->hash(key, cache->c_hashsize, cache->c_hashshift);
>  	hash = cache->c_hash + hashidx;
> @@ -464,8 +466,8 @@ next_object:
>  		/*
>  		 * not found, allocate a new entry
>  		 */
> -		cache_node_allocate(cache, key, &node);
> -		if (node)
> +		error = cache_node_allocate(cache, key, &node);
> +		if (error > 0)

I think you could keep the node nullness check, though in the end it
doesn't make much difference.  It's not like you can return
Result<struct cache_node> or anything. :)

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D


>  			break;
>  
>  		priority = cache_shake(cache, priority, false);
> @@ -475,6 +477,14 @@ next_object:
>  		 * If we exceed CACHE_MAX_PRIORITY all slots are full; grow it.
>  		 */
>  		if (priority > CACHE_MAX_PRIORITY) {
> +			/*
> +			 * We've shaken every priority level.  If the last
> +			 * attempt failed with a real ENOMEM rather than a
> +			 * full cache, neither shaking nor growing can help;
> +			 * return the error to the caller.
> +			 */
> +			if (error < 0)
> +				return error;
>  			priority = 0;
>  			cache_expand(cache);
>  		}
> diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
> index 90f2d566..d8ba832e 100644
> --- a/libxfs/rdwr.c
> +++ b/libxfs/rdwr.c
> @@ -411,17 +411,16 @@ __cache_lookup(
>  	struct cache_node	*cn = NULL;
>  	struct cache		*bcache = key->buftarg->bcache;
>  	struct xfs_buf		*bp;
> +	int			ret;
>  
>  	*bpp = NULL;
>  
> -	cache_node_get(bcache, key, &cn);
> -	if (!cn)
> -		return -ENOMEM;
> +	ret = cache_node_get(bcache, key, &cn);
> +	if (ret < 0)
> +		return ret;
>  	bp = container_of(cn, struct xfs_buf, b_node);
>  
>  	if (use_xfs_buf_lock) {
> -		int		ret;
> -
>  		ret = pthread_mutex_trylock(&bp->b_lock);
>  		if (ret) {
>  			ASSERT(ret == EAGAIN);
> -- 
> 2.55.0
> 
> 

  reply	other threads:[~2026-09-25 22:58 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-25 19:41 [PATCH 0/3 V3] libxfs: better cache allocation error handling Eric Sandeen
2026-09-25 19:41 ` [PATCH 1/3] libxfs: change cache_node_allocate function signature Eric Sandeen
2026-09-25 22:56   ` Darrick J. Wong
2026-09-25 19:41 ` [PATCH 2/3] libxfs: Return -ENOMEM on actual cache node allocation failures Eric Sandeen
2026-09-25 22:58   ` Darrick J. Wong [this message]
2026-09-28 15:07     ` Eric Sandeen
2026-09-25 19:41 ` [PATCH 3/3] libxfs: do not allow cache growth to overflow Eric Sandeen
2026-09-25 22:59   ` Darrick J. Wong
2026-09-28  8:16 ` [PATCH 0/3 V3] libxfs: better cache allocation error handling Christoph Hellwig
2026-09-28 15:05   ` Eric Sandeen

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=20260925225847.GC2705364@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=aalbersh@kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@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