@@ -210,6 +210,7 @@ extern int cache_check(struct cache_detail *detail,
struct cache_head *h, struct cache_req *rqstp);
extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
+extern void cache_delete_entry(struct cache_detail *cd, struct cache_head *h);
#define NEVER (0x7FFFFFFF)
extern void __init cache_initialize(void);
extern int cache_register_net(struct cache_detail *cd, struct net *net);
@@ -458,6 +458,36 @@ static int cache_clean(void)
return rv;
}
+void cache_delete_entry(struct cache_detail *detail, struct cache_head *h)
+{
+ struct cache_detail *tmp;
+
+ if (!detail || !h)
+ return;
+
+ spin_lock(&cache_list_lock);
+ list_for_each_entry(tmp, &cache_list, others) {
+ if (tmp == detail)
+ goto found;
+ }
+ spin_unlock(&cache_list_lock);
+ printk(KERN_WARNING "%s: Deleted cache detail %p\n", __func__, detail);
+ return ;
+
+found:
+ write_lock(&detail->hash_lock);
+
+ list_del_init(&h->cache_list);
+ detail->entries--;
+ set_bit(CACHE_CLEANED, &h->flags);
+
+ write_unlock(&detail->hash_lock);
+ spin_unlock(&cache_list_lock);
+
+ cache_put(h, detail);
+}
+EXPORT_SYMBOL_GPL(cache_delete_entry);
+
/*
* We want to regularly clean the cache, so we need to schedule some work ...
*/
A new helper cache_delete_entry() for delete cache_head from cache_detail directly. It will be used by pin_kill, so make sure the cache_detail is valid before deleting is needed. Because pin_kill is not many times, so the influence of performance is accepted. Signed-off-by: Kinglong Mee <kinglongmee@gmail.com> --- include/linux/sunrpc/cache.h | 1 + net/sunrpc/cache.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+)