diff options
author | Flavio Cruz <flaviocruz@gmail.com> | 2016-02-14 18:37:54 -0500 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-02-15 01:13:07 +0100 |
commit | 63ac03bc069b81559b04596d6b337880c3351700 (patch) | |
tree | 2e8e91a888d3d42d95c9041ebe917fae028504f8 /nfs | |
parent | 254a4d43674a0d5fe8f8475e3b625924691048d3 (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.c | 86 | ||||
-rw-r--r-- | nfs/nfs.c | 11 | ||||
-rw-r--r-- | nfs/nfs.h | 5 |
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); @@ -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 @@ -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 */ |