diff options
Diffstat (limited to 'debian')
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 |