summaryrefslogtreecommitdiff
path: root/nfs
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2016-02-14 18:37:54 -0500
committerJustus Winter <justus@gnupg.org>2016-02-15 01:13:07 +0100
commit63ac03bc069b81559b04596d6b337880c3351700 (patch)
tree2e8e91a888d3d42d95c9041ebe917fae028504f8 /nfs
parent254a4d43674a0d5fe8f8475e3b625924691048d3 (diff)
nfs: Use libihash for the node cache.
* nfs/cache.c: Remove old node cache and use libihash. Use a pointer to the node handle as the key and the node itself as the value. Use netfs_make_node_alloc to allow libihash to set 'slot'. * nfs/nfs.c: Pass in a struct handle instead. * nfs/nfs.h: Add a hurd_ihash_locp_t field and remove hnext and hprevp.
Diffstat (limited to 'nfs')
-rw-r--r--nfs/cache.c86
-rw-r--r--nfs/nfs.c11
-rw-r--r--nfs/nfs.h5
3 files changed, 44 insertions, 58 deletions
diff --git a/nfs/cache.c b/nfs/cache.c
index 506b90ff..4719ae36 100644
--- a/nfs/cache.c
+++ b/nfs/cache.c
@@ -24,49 +24,46 @@
#include <stdio.h>
#include <netinet/in.h>
-/* Hash table containing all the nodes currently active. XXX Was 512,
- however, a prime is much nicer for the hash function. 509 is nice
- as not only is it prime, it also keeps the array within a page or
- two. */
-#define CACHESIZE 509
-static struct node *nodehash [CACHESIZE];
-
-/* Compute and return a hash key for NFS file handle DATA of LEN
- bytes. */
-static inline int
-hash (int *data, size_t len)
+/* Compute and return a hash key for NFS file handle. */
+static hurd_ihash_key_t
+ihash_hash (const void *data)
{
- unsigned int h = 0;
- char *cp = (char *)data;
- int i;
-
- for (i = 0; i < len; i++)
- h += cp[i];
-
- return h % CACHESIZE;
+ const struct fhandle *handle = (struct fhandle *) data;
+ return (hurd_ihash_key_t) hurd_ihash_hash32 (handle->data, handle->size, 0);
+}
+
+/* Compare two handles which are used as keys. */
+static int
+ihash_compare (const void *key1, const void *key2)
+{
+ const struct fhandle *handle1 = (struct fhandle *) key1;
+ const struct fhandle *handle2 = (struct fhandle *) key2;
+
+ return handle1->size == handle2->size &&
+ memcmp (handle1->data, handle2->data, handle1->size) == 0;
}
-/* Lookup the file handle P (length LEN) in the hash table. If it is
+/* Hash table containing all the nodes currently active. */
+static struct hurd_ihash nodehash =
+ HURD_IHASH_INITIALIZER_GKI (sizeof (struct node)
+ + offsetof (struct netnode, slot), NULL, NULL,
+ ihash_hash, ihash_compare);
+
+/* Lookup the file handle HANDLE in the hash table. If it is
not present, initialize a new node structure and insert it into the
hash table. Whichever course, a new reference is generated and the
node is returned in *NPP; the lock on the node, (*NPP)->LOCK, is
held. */
void
-lookup_fhandle (void *p, size_t len, struct node **npp)
+lookup_fhandle (struct fhandle *handle, struct node **npp)
{
struct node *np;
struct netnode *nn;
- int h;
-
- h = hash (p, len);
pthread_spin_lock (&netfs_node_refcnt_lock);
- for (np = nodehash[h]; np; np = np->nn->hnext)
+ np = hurd_ihash_find (&nodehash, (hurd_ihash_key_t) handle);
+ if (np)
{
- if (np->nn->handle.size != len
- || memcmp (np->nn->handle.data, p, len) != 0)
- continue;
-
np->references++;
pthread_spin_unlock (&netfs_node_refcnt_lock);
pthread_mutex_lock (&np->lock);
@@ -75,23 +72,19 @@ lookup_fhandle (void *p, size_t len, struct node **npp)
}
/* Could not find it */
- nn = malloc (sizeof (struct netnode));
- assert (nn);
+ np = netfs_make_node_alloc (sizeof (struct netnode));
+ assert (np);
+ nn = netfs_node_netnode (np);
- nn->handle.size = len;
- memcpy (nn->handle.data, p, len);
+ nn->handle.size = handle->size;
+ memcpy (nn->handle.data, handle->data, handle->size);
nn->stat_updated = 0;
nn->dtrans = NOT_POSSIBLE;
nn->dead_dir = 0;
nn->dead_name = 0;
- np = netfs_make_node (nn);
+ hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &nn->handle, np);
pthread_mutex_lock (&np->lock);
- nn->hnext = nodehash[h];
- if (nn->hnext)
- nn->hnext->nn->hprevp = &nn->hnext;
- nn->hprevp = &nodehash[h];
- nodehash[h] = np;
pthread_spin_unlock (&netfs_node_refcnt_lock);
@@ -162,9 +155,7 @@ netfs_node_norefs (struct node *np)
}
else
{
- *np->nn->hprevp = np->nn->hnext;
- if (np->nn->hnext)
- np->nn->hnext->nn->hprevp = np->nn->hprevp;
+ hurd_ihash_locp_remove (&nodehash, np->nn->slot);
if (np->nn->dtrans == SYMLINK)
free (np->nn->transarg.name);
free (np->nn);
@@ -178,7 +169,6 @@ netfs_node_norefs (struct node *np)
int *
recache_handle (int *p, struct node *np)
{
- int h;
size_t len;
if (protocol_version == 2)
@@ -191,20 +181,14 @@ recache_handle (int *p, struct node *np)
/* Unlink it */
pthread_spin_lock (&netfs_node_refcnt_lock);
- *np->nn->hprevp = np->nn->hnext;
- if (np->nn->hnext)
- np->nn->hnext->nn->hprevp = np->nn->hprevp;
+ hurd_ihash_locp_remove (&nodehash, np->nn->slot);
/* Change the name */
np->nn->handle.size = len;
memcpy (np->nn->handle.data, p, len);
/* Reinsert it */
- h = hash (p, len);
- np->nn->hnext = nodehash[h];
- if (np->nn->hnext)
- np->nn->hnext->nn->hprevp = &np->nn->hnext;
- np->nn->hprevp = &nodehash[h];
+ hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &np->nn->handle, np);
pthread_spin_unlock (&netfs_node_refcnt_lock);
return p + len / sizeof (int);
diff --git a/nfs/nfs.c b/nfs/nfs.c
index 4916df65..77281566 100644
--- a/nfs/nfs.c
+++ b/nfs/nfs.c
@@ -383,18 +383,19 @@ xdr_decode_64bit (int *p, long long *n)
int *
xdr_decode_fhandle (int *p, struct node **npp)
{
- size_t len;
+ struct fhandle handle;
if (protocol_version == 2)
- len = NFS2_FHSIZE;
+ handle.size = NFS2_FHSIZE;
else
{
- len = ntohl (*p);
+ handle.size = ntohl (*p);
p++;
}
+ memcpy (&handle.data, p, handle.size);
/* Enter into cache. */
- lookup_fhandle (p, len, npp);
- return p + len / sizeof (int);
+ lookup_fhandle (&handle, npp);
+ return p + handle.size / sizeof (int);
}
/* Decode *P into a stat structure; return the address of the
diff --git a/nfs/nfs.h b/nfs/nfs.h
index 18dec001..8424acb2 100644
--- a/nfs/nfs.h
+++ b/nfs/nfs.h
@@ -24,6 +24,7 @@
#include <pthread.h>
#include <sys/mman.h>
#include "nfs-spec.h"
+#include <hurd/ihash.h>
#include <hurd/netfs.h>
/* A file handle */
@@ -39,9 +40,9 @@ struct fhandle
node. */
struct netnode
{
+ hurd_ihash_locp_t slot;
struct fhandle handle;
time_t stat_updated;
- struct node *hnext, **hprevp;
/* These two fields handle translators set internally but
unknown to the server. */
@@ -192,7 +193,7 @@ void *timeout_service_thread (void *);
void *rpc_receive_thread (void *);
/* cache.c */
-void lookup_fhandle (void *, size_t, struct node **);
+void lookup_fhandle (struct fhandle *, struct node **);
int *recache_handle (int *, struct node *);
/* name-cache.c */