bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] nfs: Use libihash for the node cache.


From: Flavio Cruz
Subject: [PATCH] nfs: Use libihash for the node cache.
Date: Sun, 14 Feb 2016 18:37:54 -0500
User-agent: Mutt/1.5.24 (2015-08-30)

* 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.
---
 nfs/cache.c | 86 +++++++++++++++++++++++++------------------------------------
 nfs/nfs.c   | 11 ++++----
 nfs/nfs.h   |  5 ++--
 3 files changed, 44 insertions(+), 58 deletions(-)

diff --git a/nfs/cache.c b/nfs/cache.c
index 506b90f..4719ae3 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 4916df6..7728156 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 18dec00..8424acb 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 */
-- 
2.6.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]