summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
Diffstat (limited to 'debian')
-rw-r--r--debian/patches/flavio0001-nfs-Use-libihash-for-the-node-cache.patch232
-rw-r--r--debian/patches/flavio0002-libdiskfs-fix-and-improve-locking-in-nrefs-nput.patch68
-rw-r--r--debian/patches/series2
3 files changed, 302 insertions, 0 deletions
diff --git a/debian/patches/flavio0001-nfs-Use-libihash-for-the-node-cache.patch b/debian/patches/flavio0001-nfs-Use-libihash-for-the-node-cache.patch
new file mode 100644
index 00000000..bfeef9c3
--- /dev/null
+++ b/debian/patches/flavio0001-nfs-Use-libihash-for-the-node-cache.patch
@@ -0,0 +1,232 @@
+From 63ac03bc069b81559b04596d6b337880c3351700 Mon Sep 17 00:00:00 2001
+From: Flavio Cruz <flaviocruz@gmail.com>
+Date: Sun, 14 Feb 2016 18:37:54 -0500
+Subject: [PATCH hurd 1/2] 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.
+---
+ 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.1.4
+
diff --git a/debian/patches/flavio0002-libdiskfs-fix-and-improve-locking-in-nrefs-nput.patch b/debian/patches/flavio0002-libdiskfs-fix-and-improve-locking-in-nrefs-nput.patch
new file mode 100644
index 00000000..2999c041
--- /dev/null
+++ b/debian/patches/flavio0002-libdiskfs-fix-and-improve-locking-in-nrefs-nput.patch
@@ -0,0 +1,68 @@
+From 0f6a5081d875051e1b6275096d25332e66f0458c Mon Sep 17 00:00:00 2001
+From: Flavio Cruz <flaviocruz@gmail.com>
+Date: Sun, 14 Feb 2016 18:37:16 -0500
+Subject: [PATCH hurd 2/2] libdiskfs: fix and improve locking in nrefs/nput.
+
+* libnetfs/node-nput.c: Do not unlock the node since it will be unlocked
+later.
+* libnetfs/node-nrele.c: Do not lock the node twice if not needed.
+---
+ libdiskfs/node-nput.c | 1 -
+ libdiskfs/node-nrele.c | 8 ++++++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/libdiskfs/node-nput.c b/libdiskfs/node-nput.c
+index d23c103..d59769b 100644
+--- a/libdiskfs/node-nput.c
++++ b/libdiskfs/node-nput.c
+@@ -56,7 +56,6 @@ diskfs_nput (struct node *np)
+ hold a weak reference ourselves. */
+ diskfs_try_dropping_softrefs (np);
+ }
+- pthread_mutex_unlock (&np->lock);
+ }
+
+ /* Finally get rid of our reference. */
+diff --git a/libdiskfs/node-nrele.c b/libdiskfs/node-nrele.c
+index d962846..a96d134 100644
+--- a/libdiskfs/node-nrele.c
++++ b/libdiskfs/node-nrele.c
+@@ -28,6 +28,7 @@
+ void
+ diskfs_nrele (struct node *np)
+ {
++ int locked = FALSE;
+ struct references result;
+
+ /* While we call the diskfs_try_dropping_softrefs, we need to hold
+@@ -37,6 +38,7 @@ diskfs_nrele (struct node *np)
+
+ if (result.hard == 0)
+ {
++ locked = TRUE;
+ pthread_mutex_lock (&np->lock);
+ diskfs_lost_hardrefs (np);
+ if (!np->dn_stat.st_nlink)
+@@ -49,7 +51,6 @@ diskfs_nrele (struct node *np)
+ hold a weak reference ourselves. */
+ diskfs_try_dropping_softrefs (np);
+ }
+- pthread_mutex_unlock (&np->lock);
+ }
+
+ /* Finally get rid of our reference. */
+@@ -57,7 +58,10 @@ diskfs_nrele (struct node *np)
+
+ if (result.hard == 0 && result.weak == 0)
+ {
+- pthread_mutex_lock (&np->lock);
++ if (! locked)
++ pthread_mutex_lock (&np->lock);
+ diskfs_drop_node (np);
+ }
++ else if (locked)
++ pthread_mutex_unlock (&np->lock);
+ }
+--
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index 1c79e1af..06cbbed9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -36,3 +36,5 @@ exec_filename0002-Add-a-file_exec_file_name-RPC.patch
exec_filename0003-Use-the-new-_hurd_exec_file_name-function.patch
exec_filename0004-This-patch-is-an-amendment-of-exec_filename_exec.pat.patch
gpg0001-trans-add-transparent-GnuPG-translator.patch
+flavio0001-nfs-Use-libihash-for-the-node-cache.patch
+flavio0002-libdiskfs-fix-and-improve-locking-in-nrefs-nput.patch