2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-23 04:34:11 +08:00

sunrpc: clean up cache entry add/remove from hashtable

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Trond Myklebust 2020-01-06 13:40:35 -05:00 committed by J. Bruce Fields
parent 1d82163714
commit 809fe3c533

View File

@ -77,6 +77,22 @@ static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail,
return NULL; return NULL;
} }
static void sunrpc_begin_cache_remove_entry(struct cache_head *ch,
struct cache_detail *cd)
{
/* Must be called under cd->hash_lock */
hlist_del_init_rcu(&ch->cache_list);
set_bit(CACHE_CLEANED, &ch->flags);
cd->entries --;
}
static void sunrpc_end_cache_remove_entry(struct cache_head *ch,
struct cache_detail *cd)
{
cache_fresh_unlocked(ch, cd);
cache_put(ch, cd);
}
static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail, static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
struct cache_head *key, struct cache_head *key,
int hash) int hash)
@ -100,8 +116,7 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
hlist_for_each_entry_rcu(tmp, head, cache_list) { hlist_for_each_entry_rcu(tmp, head, cache_list) {
if (detail->match(tmp, key)) { if (detail->match(tmp, key)) {
if (cache_is_expired(detail, tmp)) { if (cache_is_expired(detail, tmp)) {
hlist_del_init_rcu(&tmp->cache_list); sunrpc_begin_cache_remove_entry(tmp, detail);
detail->entries --;
freeme = tmp; freeme = tmp;
break; break;
} }
@ -117,10 +132,8 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
cache_get(new); cache_get(new);
spin_unlock(&detail->hash_lock); spin_unlock(&detail->hash_lock);
if (freeme) { if (freeme)
cache_fresh_unlocked(freeme, detail); sunrpc_end_cache_remove_entry(freeme, detail);
cache_put(freeme, detail);
}
return new; return new;
} }
@ -454,8 +467,7 @@ static int cache_clean(void)
if (!cache_is_expired(current_detail, ch)) if (!cache_is_expired(current_detail, ch))
continue; continue;
hlist_del_init_rcu(&ch->cache_list); sunrpc_begin_cache_remove_entry(ch, current_detail);
current_detail->entries--;
rv = 1; rv = 1;
break; break;
} }
@ -465,11 +477,8 @@ static int cache_clean(void)
if (!ch) if (!ch)
current_index ++; current_index ++;
spin_unlock(&cache_list_lock); spin_unlock(&cache_list_lock);
if (ch) { if (ch)
set_bit(CACHE_CLEANED, &ch->flags); sunrpc_end_cache_remove_entry(ch, d);
cache_fresh_unlocked(ch, d);
cache_put(ch, d);
}
} else } else
spin_unlock(&cache_list_lock); spin_unlock(&cache_list_lock);
@ -525,13 +534,9 @@ void cache_purge(struct cache_detail *detail)
for (i = 0; i < detail->hash_size; i++) { for (i = 0; i < detail->hash_size; i++) {
head = &detail->hash_table[i]; head = &detail->hash_table[i];
hlist_for_each_entry_safe(ch, tmp, head, cache_list) { hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
hlist_del_init_rcu(&ch->cache_list); sunrpc_begin_cache_remove_entry(ch, detail);
detail->entries--;
set_bit(CACHE_CLEANED, &ch->flags);
spin_unlock(&detail->hash_lock); spin_unlock(&detail->hash_lock);
cache_fresh_unlocked(ch, detail); sunrpc_end_cache_remove_entry(ch, detail);
cache_put(ch, detail);
spin_lock(&detail->hash_lock); spin_lock(&detail->hash_lock);
} }
} }
@ -1886,12 +1891,9 @@ void sunrpc_cache_unhash(struct cache_detail *cd, struct cache_head *h)
{ {
spin_lock(&cd->hash_lock); spin_lock(&cd->hash_lock);
if (!hlist_unhashed(&h->cache_list)){ if (!hlist_unhashed(&h->cache_list)){
hlist_del_init_rcu(&h->cache_list); sunrpc_begin_cache_remove_entry(h, cd);
cd->entries--;
set_bit(CACHE_CLEANED, &h->flags);
spin_unlock(&cd->hash_lock); spin_unlock(&cd->hash_lock);
cache_fresh_unlocked(h, cd); sunrpc_end_cache_remove_entry(h, cd);
cache_put(h, cd);
} else } else
spin_unlock(&cd->hash_lock); spin_unlock(&cd->hash_lock);
} }