[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <175573713023.20753.17208085171701652235.stgit@frogsfrogsfrogs>
Date: Wed, 20 Aug 2025 18:11:00 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: tytso@....edu
Cc: John@...ves.net, bernd@...ernd.com, linux-fsdevel@...r.kernel.org,
linux-ext4@...r.kernel.org, miklos@...redi.hu, amir73il@...il.com,
joannelkoong@...il.com, neal@...pa.dev
Subject: [PATCH 12/20] cache: add a helper to grab a new refcount for a
cache_node
From: Darrick J. Wong <djwong@...nel.org>
Create a helper to bump the refcount of a cache node.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
lib/support/cache.h | 1 +
lib/support/cache.c | 57 +++++++++++++++++++++++++++++----------------------
2 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/lib/support/cache.h b/lib/support/cache.h
index b18b6d3325e9ad..e8f1c82ef7869c 100644
--- a/lib/support/cache.h
+++ b/lib/support/cache.h
@@ -141,5 +141,6 @@ int cache_node_get_priority(struct cache_node *);
int cache_node_purge(struct cache *, cache_key_t, struct cache_node *);
void cache_report(FILE *fp, const char *, struct cache *);
int cache_overflowed(struct cache *);
+struct cache_node *cache_node_grab(struct cache *cache, struct cache_node *node);
#endif /* __CACHE_H__ */
diff --git a/lib/support/cache.c b/lib/support/cache.c
index 606acd5453cf10..49568ffa6de2e4 100644
--- a/lib/support/cache.c
+++ b/lib/support/cache.c
@@ -362,6 +362,35 @@ __cache_node_purge(
return 0;
}
+/* Grab a new refcount to the cache node object. Caller must hold cn_mutex. */
+struct cache_node *cache_node_grab(struct cache *cache, struct cache_node *node)
+{
+ struct cache_mru *mru;
+
+ if (node->cn_count == 0 && cache->get) {
+ int err = cache->get(cache, node);
+ if (err)
+ return NULL;
+ }
+ if (node->cn_count == 0) {
+ ASSERT(node->cn_priority >= 0);
+ ASSERT(!list_empty(&node->cn_mru));
+ mru = &cache->c_mrus[node->cn_priority];
+ pthread_mutex_lock(&mru->cm_mutex);
+ mru->cm_count--;
+ list_del_init(&node->cn_mru);
+ pthread_mutex_unlock(&mru->cm_mutex);
+ if (node->cn_old_priority != -1) {
+ ASSERT(node->cn_priority ==
+ CACHE_DIRTY_PRIORITY);
+ node->cn_priority = node->cn_old_priority;
+ node->cn_old_priority = -1;
+ }
+ }
+ node->cn_count++;
+ return node;
+}
+
/*
* Lookup in the cache hash table. With any luck we'll get a cache
* hit, in which case this will all be over quickly and painlessly.
@@ -377,7 +406,6 @@ cache_node_get(
struct cache_node **nodep)
{
struct cache_hash *hash;
- struct cache_mru *mru;
struct cache_node *node = NULL, *n;
unsigned int hashidx;
int priority = 0;
@@ -411,31 +439,10 @@ cache_node_get(
* from its MRU list, and update stats.
*/
pthread_mutex_lock(&node->cn_mutex);
-
- if (node->cn_count == 0 && cache->get) {
- int err = cache->get(cache, node);
- if (err) {
- pthread_mutex_unlock(&node->cn_mutex);
- goto next_object;
- }
+ if (!cache_node_grab(cache, node)) {
+ pthread_mutex_unlock(&node->cn_mutex);
+ goto next_object;
}
- if (node->cn_count == 0) {
- ASSERT(node->cn_priority >= 0);
- ASSERT(!list_empty(&node->cn_mru));
- mru = &cache->c_mrus[node->cn_priority];
- pthread_mutex_lock(&mru->cm_mutex);
- mru->cm_count--;
- list_del_init(&node->cn_mru);
- pthread_mutex_unlock(&mru->cm_mutex);
- if (node->cn_old_priority != -1) {
- ASSERT(node->cn_priority ==
- CACHE_DIRTY_PRIORITY);
- node->cn_priority = node->cn_old_priority;
- node->cn_old_priority = -1;
- }
- }
- node->cn_count++;
-
pthread_mutex_unlock(&node->cn_mutex);
pthread_mutex_unlock(&hash->ch_mutex);
Powered by blists - more mailing lists