From 63f499c4b753cfdcf5ed958300fbadd7b7166db0 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 3 Feb 2012 13:40:00 -0500 Subject: [PATCH] cache: check for expiry on nfs41_attr_cache_lookup() added expiration field to struct attr_cache_entry. expiration timer is reset whenever attr_cache_update() is called with a 'change' attribute new function attr_cache_entry_expired() is used by nfs41_attr_cache_lookup() and name_cache_lookup()/entry_invis() to prevent the use of expired attributes Signed-off-by: Casey Bodley --- daemon/name_cache.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/daemon/name_cache.c b/daemon/name_cache.c index 2738cc4..e064739 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -95,6 +95,7 @@ struct attr_cache_entry { uint32_t time_modify_ns; uint32_t numlinks; uint32_t mode; + time_t expiration; unsigned ref_count : 26; unsigned type : 4; unsigned invalidated : 1; @@ -175,6 +176,13 @@ static __inline void attr_cache_entry_deref( attr_cache_entry_free(cache, entry); } +static __inline int attr_cache_entry_expired( + IN const struct attr_cache_entry *entry) +{ + return entry->invalidated || + (!entry->delegated && time(NULL) > entry->expiration); +} + /* attr_cache */ static int attr_cache_init( IN struct attr_cache *cache, @@ -285,6 +293,7 @@ static void attr_cache_update( entry->change = info->change; /* revalidate whenever we get a change attribute */ entry->invalidated = 0; + entry->expiration = time(NULL) + NAME_CACHE_EXPIRATION; } if (info->attrmask.arr[0] & FATTR4_WORD0_SIZE) entry->size = info->size; @@ -610,8 +619,8 @@ static int entry_invis( dprintf(NCLVL2, "name_entry_negative('%s')\n", entry->component); return 1; } - /* attribute entry invalidated? */ - if (entry->attributes->invalidated) { + /* attribute entry expired? */ + if (attr_cache_entry_expired(entry->attributes)) { dprintf(NCLVL2, "attr_entry_expired(%llu)\n", entry->attributes->fileid); return 1; @@ -848,7 +857,7 @@ int nfs41_attr_cache_lookup( } entry = attr_cache_search(&cache->attributes, fileid); - if (entry == NULL) { + if (entry == NULL || attr_cache_entry_expired(entry)) { status = ERROR_FILE_NOT_FOUND; goto out_unlock; }