summaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/name-cache.c108
1 files changed, 15 insertions, 93 deletions
diff --git a/libdiskfs/name-cache.c b/libdiskfs/name-cache.c
index a4270fe9..2cf1ed8b 100644
--- a/libdiskfs/name-cache.c
+++ b/libdiskfs/name-cache.c
@@ -19,9 +19,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
-
#include "priv.h"
#include <string.h>
+#include <cacheq.h>
/* Maximum number of names to cache at once */
#define MAXCACHE 256
@@ -32,6 +32,8 @@
/* Cache entry */
struct lookup_cache
{
+ struct cacheq_hdr hdr;
+
/* Used to indentify nodes to the fs dependent code. 0 for NODE_CACHE_ID
means a `negative' entry -- recording that there's definitely no node with
this name. */
@@ -43,20 +45,10 @@ struct lookup_cache
/* Strlen of NAME. If this is zero, it's an unused entry. */
size_t name_len;
-
- /* Next and prev entries in the cache, linked in LRU order. */
- struct lookup_cache *next, *prev;
};
/* The contents of the cache in no particular order */
-static struct lookup_cache lookup_cache[MAXCACHE];
-
-/* The least, and most, recently used entries in the cache. These point to
- either end of a linked list composed of all the elements of LOOKUP_CACHE.
- This list will always be the same length -- if an element is `removed',
- its entry is simply marked inactive, and moved to the LRU end of the list
- so it will be reused first. */
-static struct lookup_cache *lru_cache = 0, *mru_cache = 0;
+static struct cacheq lookup_cache = { sizeof (struct lookup_cache) };
static spin_lock_t cache_lock = SPIN_LOCK_INITIALIZER;
@@ -69,52 +61,6 @@ static struct
long fetch_errors;
} statistics;
-/* Move C to the most-recently-used end of the cache. CACHE_LOCK must be
- held. */
-static void
-make_mru (struct lookup_cache *c)
-{
- if (c != mru_cache)
- {
- /* First remove it. We known C->prev isn't 0 because C wasn't
- previously == MRU_CACHE. */
- c->prev->next = c->next;
- if (c->next)
- c->next->prev = c->prev;
- else
- lru_cache = c->prev;
-
- /* Now make it MRU_CACHE. */
- c->next = mru_cache;
- c->prev = 0;
- mru_cache->prev = c;
- mru_cache = c;
- }
-}
-
-/* Move C to the least-recently-used end of the cache. CACHE_LOCK must be
- held. */
-static void
-make_lru (struct lookup_cache *c)
-{
- if (c != lru_cache)
- {
- /* First remove it. We known C->next isn't 0 because C wasn't
- previously == LRU_CACHE. */
- c->next->prev = c->prev;
- if (c->prev)
- c->prev->next = c->next;
- else
- mru_cache = c->next;
-
- /* Now make it LRU_CACHE. */
- c->prev = lru_cache;
- c->next = 0;
- lru_cache->next = c;
- lru_cache = c;
- }
-}
-
/* If there's an entry for NAME, of length NAME_LEN, in directory DIR in the
cache, return it's entry, otherwise 0. CACHE_LOCK must be held. */
static struct lookup_cache *
@@ -124,7 +70,7 @@ find_cache (struct node *dir, const char *name, size_t name_len)
/* Search the list. All unused entries are contiguous at the end of the
list, so we can stop searching when we see the first one. */
- for (c = mru_cache; c && c->name_len; c = c->next)
+ for (c = lookup_cache.mru; c && c->name_len; c = c->hdr.next)
if (c->name_len == name_len
&& c->dir_cache_id == dir->cache_id
&& c->name[0] == name[0] && strcmp (c->name, name) == 0)
@@ -133,31 +79,6 @@ find_cache (struct node *dir, const char *name, size_t name_len)
return 0;
}
-/* Put all the elements of the LOOKUP_CACHE array in a doubly linked list
- pointed to at either end by LRU_CACHE and MRU_CACHE, and initialize each
- entry. */
-static void
-init_lookup_cache ()
-{
- int i;
-
- lru_cache = mru_cache = &lookup_cache[0];
-
- lru_cache->name_len = 0;
- lru_cache->next = 0;
-
- for (i = 1; i < MAXCACHE; i++)
- {
- struct lookup_cache *c = &lookup_cache[i];
- c->name_len = 0;
- c->next = mru_cache;
- mru_cache->prev = c;
- mru_cache = c;
- }
-
- mru_cache->prev = 0;
-}
-
/* Node NP has just been found in DIR with NAME. If NP is null, that
means that this name has been confirmed as absent in the directory. */
void
@@ -178,14 +99,14 @@ diskfs_enter_lookup_cache (struct node *dir, struct node *np, char *name)
spin_lock (&cache_lock);
- if (lru_cache == 0)
+ if (lookup_cache.length == 0)
/* There should always be an lru_cache; this being zero means that the
cache hasn't been initialized yet. Do so. */
- init_lookup_cache ();
+ cacheq_set_length (&lookup_cache, MAXCACHE);
/* See if there's an old entry for NAME in DIR. If not, replace the least
recently used entry. */
- c = find_cache (dir, name, name_len) ?: lru_cache;
+ c = find_cache (dir, name, name_len) ?: lookup_cache.lru;
/* Fill C with the new entry. */
c->dir_cache_id = dir->cache_id;
@@ -194,7 +115,7 @@ diskfs_enter_lookup_cache (struct node *dir, struct node *np, char *name)
c->name_len = name_len;
/* Now C becomes the MRU entry! */
- make_mru (c);
+ cacheq_make_mru (&lookup_cache, c);
spin_unlock (&cache_lock);
}
@@ -207,17 +128,18 @@ diskfs_purge_lookup_cache (struct node *dp, struct node *np)
struct lookup_cache *c, *next;
spin_lock (&cache_lock);
- for (c = mru_cache; c; c = next)
+ for (c = lookup_cache.mru; c; c = next)
{
- /* Save C->next, since we may delete C from this position in the list. */
- next = c->next;
+ /* Save C->hdr.next, since we may move C from this position. */
+ next = c->hdr.next;
if (c->name_len
&& c->dir_cache_id == dp->cache_id
&& c->node_cache_id == np->cache_id)
{
c->name_len = 0;
- make_lru (c); /* Use C as the next free entry. */
+ cacheq_make_lru (&lookup_cache, c); /* Use C as the next free
+ entry. */
}
}
spin_unlock (&cache_lock);
@@ -239,7 +161,7 @@ diskfs_check_lookup_cache (struct node *dir, char *name)
{
int id = c->node_cache_id;
- make_mru (c); /* Record C as recently used. */
+ cacheq_make_mru (&lookup_cache, c); /* Record C as recently used. */
statistics.pos_hits++;
spin_unlock (&cache_lock);