From 6c555e028bd34c54bb619fb77c8453e2ea45da65 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 25 Aug 2011 10:52:19 -0400 Subject: [PATCH] namecache: prefer to evict child entries over parents renamed name_cache_entry_refresh() to name_cache_entry_updated(). this function resets the entry's expiration timer. new function name_cache_entry_accessed() deals with moving the entry to the end of exp_entries to prevent eviction name_cache_entry_accessed() now does the same for its parents as well. cache consistency of the parents is maintained because their expiration timers are unchanged. by 'refreshing' the parents of each name cache entry inserted, the eviction policy will always prefer child nodes (which are far less costly to evict) Signed-off-by: Casey Bodley --- daemon/name_cache.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/daemon/name_cache.c b/daemon/name_cache.c index f2aa193..75f31c9 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -455,17 +455,31 @@ static int name_cache_entry_create( return status; } -static void name_cache_entry_refresh( +static void name_cache_entry_accessed( + IN struct nfs41_name_cache *cache, + IN struct name_cache_entry *entry) +{ + /* move the entry to the front of cache->exp_entries, then do + * the same for its parents, which are more costly to evict */ + while (entry) { + /* if entry is delegated, it won't be in the list */ + if (!list_empty(&entry->exp_entry)) { + list_remove(&entry->exp_entry); + list_add_head(&cache->exp_entries, &entry->exp_entry); + } + if (entry == entry->parent) + break; + entry = entry->parent; + } +} + +static void name_cache_entry_updated( IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry) { /* update the expiration timer */ entry->expiration = time(NULL) + cache->expiration; - /* move the entry to the front of cache->exp_entries */ - if (!list_empty(&entry->exp_entry)) { - list_remove(&entry->exp_entry); - list_add_head(&cache->exp_entries, &entry->exp_entry); - } + name_cache_entry_accessed(cache, entry); } static int name_cache_entry_update( @@ -506,7 +520,7 @@ static int name_cache_entry_update( attr_cache_entry_deref(&cache->attributes, entry->attributes); entry->attributes = NULL; } - name_cache_entry_refresh(cache, entry); + name_cache_entry_updated(cache, entry); return status; } @@ -521,7 +535,7 @@ static int name_cache_entry_changed( if (cinfo->after == entry->attributes->change || (cinfo->atomic && cinfo->before == entry->attributes->change)) { entry->attributes->change = cinfo->after; - name_cache_entry_refresh(cache, entry); + name_cache_entry_updated(cache, entry); dprintf(NCLVL1, "name_cache_entry_changed('%s') has not changed. " "updated change=%llu\n", entry->component, entry->attributes->change); @@ -978,7 +992,7 @@ int nfs41_name_cache_delegreturn( if (status == NO_ERROR) { /* put the name cache entry back on the exp_entries list */ list_add_head(&cache->exp_entries, &target->exp_entry); - name_cache_entry_refresh(cache, target); + name_cache_entry_updated(cache, target); attributes = target->attributes; } else {