summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-03-21 19:46:07 +0100
committerJustus Winter <justus@gnupg.org>2016-03-21 19:46:07 +0100
commit94f3a5a97de1aa03c74bb8682bde509eb07d21b7 (patch)
treea0c33265a45da977f2b1a9980c9309062811c3f7
parent8d00a764c4abbb07fd4656ccaa7cd1deb0a27d41 (diff)
drop old patch series
-rw-r--r--debian/patches/flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch775
-rw-r--r--debian/patches/series1
2 files changed, 0 insertions, 776 deletions
diff --git a/debian/patches/flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch b/debian/patches/flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch
deleted file mode 100644
index 78e6a27e..00000000
--- a/debian/patches/flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch
+++ /dev/null
@@ -1,775 +0,0 @@
-From 72c6525daf26404bbc3a0e20c90d1cd6cd824eff Mon Sep 17 00:00:00 2001
-From: Flavio Cruz <flaviocruz@gmail.com>
-Date: Sun, 6 Mar 2016 18:14:52 -0500
-Subject: [PATCH hurd] Remove global netfs lock and use hard and soft
- references for nodes.
-
-* libnetfs/drop-node.c: Remove use of netfs_node_refcnt_lock.
-* libnetfs/init-init.c: Remove netfs_node_refcnt_lock.
-* libnetfs/make-node.c: Initialize refcounts in refcounts_init.
-* libnetfs/netfs.h: Use refcounts_t for tracking node references. Remove
-netfs_node_refcnt_lock. Add netfs_nref_light, netfs_nrele_light and
-handler netfs_try_dropping_softrefs. Adjust comments.
-* libnetfs/nput.c: Use refcounts_t. Call netfs_try_dropping_softrefs to
-remove any soft reference that the translator might have acquired
-during the lifetime of the node. Implement empty
-netfs_try_dropping_softrefs.
-* libnetfs/nref.c: Implement netfs_nref_light.
-* libnetfs/nrele.c: Use refcounts_t and netfs_try_dropping_softrefs.
-Implement netfs_nrele_light.
-* ftpfs/dir.c: Use netfs_nref without locking the old
-netfs_node_refcnt_lock.
-* ftpfs/node.c: Likewise.
-* usermux/mux.c: Use netfs_nref to increase hard references of the node.
-* hostmux/mux.c: Use netfs_nref to increase hard references of the node.
-* trans/fakeroot.c (new_node): Use a light reference when storing a node in the
-hash table.
-* trans/fakeroot.c (netfs_try_dropping_softrefs): Implement
-netfs_try_dropping_softrefs to remove the node from the hash table.
-* trans/fakeroot.c (netfs_node_norefs): Remove code to remove the node
-from the hash table.
-* trans/fakeroot.c (netfs_S_dir_lookup): Simplify lookup code since we
-don't need to lock netfs_node_refcnt_lock anymore.
-* procfs/netfs.c: Remove use of netfs_node_refcnt_lock.
-* nfs/cache.c: Add mutex to handle exclusive access to nodehash. This
-replaces the use of netfs_node_refcnt_lock.
-* nfs/cache.c (lookup_handle): Use nodehash_ihash_lock when accessing
-nodehash. Use netfs_nref_light to add one soft reference to the node
-just added to nodehash.
-* nfs/cache.c (netfs_node_norefs): Use netfs_nref. Don't use
-netfs_node_refcnt_lock and don't remove the node from nodehash here.
-* nfs/cache.c (netfs_try_dropping_softrefs): Drop the light reference
-when the node has no more hard references.
-* nfs/cache.c (recache_handle): Use nodehash_ihash_lock instead.
-* nfs/ops.c (netds_attempt_unlink): Use refcounts_references.
-* console/console.c (netfs_node_norefs): Use a soft reference to store
-a node in dir_node, cons_node, disp_node, inp_node.
-* console/console.c (netfs_try_dropping_softrefs): When dropping all
-soft references remove node pointer from the fields above.
----
- console/console.c | 64 ++++++++++++++++++++++++++++++----------------------
- ftpfs/dir.c | 27 +++++-----------------
- ftpfs/node.c | 8 +------
- hostmux/mux.c | 6 ++---
- libnetfs/drop-node.c | 1 -
- libnetfs/init-init.c | 2 --
- libnetfs/make-node.c | 2 +-
- libnetfs/netfs.h | 42 ++++++++++++++++++++++------------
- libnetfs/nput.c | 27 ++++++++++++++--------
- libnetfs/nref.c | 12 +++++++---
- libnetfs/nrele.c | 37 ++++++++++++++++++++++++------
- nfs/cache.c | 40 ++++++++++++++++++--------------
- nfs/ops.c | 5 +++-
- procfs/netfs.c | 4 ----
- trans/fakeroot.c | 45 +++++++++++++++++++++---------------
- usermux/mux.c | 6 ++---
- 16 files changed, 187 insertions(+), 141 deletions(-)
-
-diff --git a/console/console.c b/console/console.c
-index 57ae813..9c5869d 100644
---- a/console/console.c
-+++ b/console/console.c
-@@ -415,47 +415,51 @@ new_node (struct node **np, vcons_t vcons, vcons_node_type type)
-
- /* Node management. */
-
--/* Node NP has no more references; free all its associated
-- storage. */
-+/* We need to drop the soft references on NP. */
- void
--netfs_node_norefs (struct node *np)
-+netfs_try_dropping_softrefs (struct node *np)
- {
- vcons_t vcons = np->nn->vcons;
-+ int release = FALSE;
-
-- /* The root node does never go away. */
-- assert (!np->nn->cons && np->nn->vcons);
--
-- /* Avoid deadlock. */
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
--
-- /* Find the back reference to ourself in the virtual console
-- structure, and delete it. */
- pthread_mutex_lock (&vcons->lock);
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- if (np->references)
-+ if (np == vcons->dir_node)
- {
-- /* Someone else got a reference while we were attempting to go
-- away. This can happen in netfs_attempt_lookup. In this
-- case, just unlock the node and do nothing else. */
-- pthread_mutex_unlock (&vcons->lock);
-- pthread_mutex_unlock (&np->lock);
-- return;
-+ release = TRUE;
-+ vcons->dir_node = 0;
- }
-- if (np == vcons->dir_node)
-- vcons->dir_node = 0;
- else if (np == vcons->cons_node)
-- vcons->cons_node = 0;
-+ {
-+ release = TRUE;
-+ vcons->cons_node = 0;
-+ }
- else if (np == vcons->disp_node)
-- vcons->disp_node = 0;
-- else
- {
-- assert (np == vcons->inpt_node);
-+ release = TRUE;
-+ vcons->disp_node = 0;
-+ }
-+ else if (np == vcons->inpt_node)
-+ {
-+ release = TRUE;
- vcons->inpt_node = 0;
- }
-+ if (release)
-+ netfs_nrele_light (np);
- pthread_mutex_unlock (&vcons->lock);
-
- /* Release our reference. */
-- vcons_release (vcons);
-+ if (release)
-+ vcons_release (vcons);
-+
-+}
-+
-+/* Node NP has no more references; free all its associated
-+ storage. */
-+void
-+netfs_node_norefs (struct node *np)
-+{
-+ /* The root node does never go away. */
-+ assert (!np->nn->cons && np->nn->vcons);
-
- free (np->nn);
- free (np);
-@@ -634,7 +638,10 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
- the virtual console. */
- err = new_node (node, vcons, VCONS_NODE_DIR);
- if (!err)
-- vcons->dir_node = *node;
-+ {
-+ vcons->dir_node = *node;
-+ netfs_nref_light (*node);
-+ }
- else
- release_vcons = 1;
- }
-@@ -663,6 +670,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
- if (!err)
- {
- vcons->cons_node = *node;
-+ netfs_nref_light (*node);
- ref_vcons = 1;
- }
- }
-@@ -682,6 +690,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
- if (!err)
- {
- vcons->disp_node = *node;
-+ netfs_nref_light (*node);
- ref_vcons = 1;
- }
- }
-@@ -701,6 +710,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
- if (!err)
- {
- vcons->inpt_node = *node;
-+ netfs_nref_light (*node);
- ref_vcons = 1;
- }
- }
-diff --git a/ftpfs/dir.c b/ftpfs/dir.c
-index 733a2dc..2ea29b5 100644
---- a/ftpfs/dir.c
-+++ b/ftpfs/dir.c
-@@ -654,10 +654,8 @@ ftpfs_dir_lookup (struct ftpfs_dir *dir, const char *name,
- {
- /* If there's already a node, add a ref so that it doesn't go
- away. */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- if (e->node)
-- e->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ if (e->node)
-+ netfs_nref (e->node);
-
- if (! e->node)
- /* No node; make one and install it into E. */
-@@ -682,11 +680,7 @@ ftpfs_dir_lookup (struct ftpfs_dir *dir, const char *name,
- if (!err && dir->num_live_entries++ == 0)
- /* Keep a reference to dir's node corresponding to
- children. */
-- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- dir->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-- }
-+ netfs_nref (dir->node);
- }
- }
-
-@@ -737,10 +731,8 @@ ftpfs_dir_null_lookup (struct ftpfs_dir *dir, struct node **node)
- /* We've got a dir entry, get a node for it. */
- {
- /* If there's already a node, add a ref so that it doesn't go away. */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- if (e->node)
-- e->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (e->node);
-
- if (! e->node)
- /* No node; make one and install it into E. */
-@@ -749,11 +741,7 @@ ftpfs_dir_null_lookup (struct ftpfs_dir *dir, struct node **node)
-
- if (!err && dir->num_live_entries++ == 0)
- /* Keep a reference to dir's node corresponding to children. */
-- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- dir->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-- }
-+ netfs_nref (dir->node);
- }
-
- if (! err)
-@@ -783,10 +771,7 @@ ftpfs_dir_create (struct ftpfs *fs, struct node *node, const char *rmt_path,
- return ENOMEM;
- }
-
-- /* Hold a reference to the new dir's node. */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (node);
-
- hurd_ihash_init (&new->htable, offsetof (struct ftpfs_dir_entry, dir_locp));
- hurd_ihash_set_gki (&new->htable, ihash_hash, ihash_compare);
-diff --git a/ftpfs/node.c b/ftpfs/node.c
-index 74cd402..cc9bf43 100644
---- a/ftpfs/node.c
-+++ b/ftpfs/node.c
-@@ -84,10 +84,7 @@ netfs_node_norefs (struct node *node)
- {
- struct netnode *nn = node->nn;
-
-- /* Ftpfs_detach_node does ref count frobbing (of other nodes), so we have
-- to unlock NETFS_NODE_REFCNT_LOCK during it. */
-- node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (node);
-
- /* Remove NODE from any entry it is attached to. */
- ftpfs_detach_node (node);
-@@ -108,7 +105,4 @@ netfs_node_norefs (struct node *node)
-
- free (nn);
- free (node);
--
-- /* Caller expects us to leave this locked... */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- }
-diff --git a/hostmux/mux.c b/hostmux/mux.c
-index 81d3961..ddca89d 100644
---- a/hostmux/mux.c
-+++ b/hostmux/mux.c
-@@ -240,10 +240,8 @@ lookup_cached (struct hostmux *mux, const char *host, int purge,
-
- if (strcasecmp (host, nm->name) == 0)
- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- if (nm->node)
-- nm->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ if (nm->node)
-+ netfs_nref (nm->node);
-
- if (nm->node)
- {
-diff --git a/libnetfs/drop-node.c b/libnetfs/drop-node.c
-index 2fe5ce9..f0d69be 100644
---- a/libnetfs/drop-node.c
-+++ b/libnetfs/drop-node.c
-@@ -25,5 +25,4 @@ netfs_drop_node (struct node *np)
- {
- fshelp_drop_transbox (&np->transbox);
- netfs_node_norefs (np);
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
- }
-diff --git a/libnetfs/init-init.c b/libnetfs/init-init.c
-index a088ad5..9ca1aac 100644
---- a/libnetfs/init-init.c
-+++ b/libnetfs/init-init.c
-@@ -24,8 +24,6 @@
- /* For safe inlining of netfs_node_netnode and netfs_netnode_node. */
- size_t const _netfs_sizeof_struct_node = sizeof (struct node);
-
--pthread_spinlock_t netfs_node_refcnt_lock = PTHREAD_SPINLOCK_INITIALIZER;
--
- struct node *netfs_root_node = 0;
- struct port_bucket *netfs_port_bucket = 0;
- struct port_class *netfs_protid_class = 0;
-diff --git a/libnetfs/make-node.c b/libnetfs/make-node.c
-index 6bd8109..a292dc6 100644
---- a/libnetfs/make-node.c
-+++ b/libnetfs/make-node.c
-@@ -27,7 +27,7 @@ init_node (struct node *np, struct netnode *nn)
- np->nn = nn;
-
- pthread_mutex_init (&np->lock, NULL);
-- np->references = 1;
-+ refcounts_init (&np->refcounts, 1, 0);
- np->sockaddr = MACH_PORT_NULL;
- np->owner = 0;
-
-diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h
-index 67a6a9a..6c989a4 100644
---- a/libnetfs/netfs.h
-+++ b/libnetfs/netfs.h
-@@ -82,8 +82,8 @@ struct node
-
- pthread_mutex_t lock;
-
-- /* The number of references to this node. */
-- int references;
-+ /* Hard and soft references to this node. */
-+ refcounts_t refcounts;
-
- mach_port_t sockaddr;
-
-@@ -397,10 +397,6 @@ netfs_netnode_node (struct netnode *netnode)
- return (struct node *) ((char *) netnode - _netfs_sizeof_struct_node);
- }
-
--/* Whenever node->references is to be touched, this lock must be
-- held. Cf. netfs_nrele, netfs_nput, netfs_nref and netfs_drop_node. */
--extern pthread_spinlock_t netfs_node_refcnt_lock;
--
- /* Normally called in main. This function sets up some of the netfs
- server's internal state. */
- void netfs_init (void);
-@@ -425,22 +421,38 @@ struct protid *netfs_make_protid (struct peropen *po, struct iouser *user);
- struct peropen *netfs_make_peropen (struct node *, int,
- struct peropen *context);
-
--/* Add a reference to node NP. Unless you already hold a reference,
-+/* Add a hard reference to node NP. Unless you already hold a reference,
- NP must be locked. */
- void netfs_nref (struct node *np);
-
--/* Releases a node. Drops a reference to node NP, which must not be
-- locked by the caller. If this was the last reference, drops the
-- node. The node cannot be used again without first obtaining a
-- reference to it. */
-+/* Add a light reference to a node. */
-+void netfs_nref_light (struct node *np);
-+
-+/* Releases a hard reference on NP. If NP is locked by anyone, then
-+ this cannot be the last hard reference (because you must hold a
-+ hard reference in order to hold the lock). If this is the last
-+ hard reference then request soft references to be dropped. */
- void netfs_nrele (struct node *np);
-
--/* Puts a node back. Drops a reference to the node NP, which must be
-- locked by the caller (this lock will be released by netfs_nput).
-- If this was the last reference, drops the node. The node cannot be
-- used again without first obtaining a reference to it. */
-+/* Release a soft reference on NP. If NP is locked by anyone, then
-+ this cannot be the last reference (because you must hold a hard
-+ reference in order to hold the lock). */
-+void netfs_nrele_light (struct node *np);
-+
-+/* Puts a node back by releasing a hard reference on NP, which must
-+ be locked by the caller (this lock will be released by netfs_nput).
-+ If this was the last reference, then request soft references to be
-+ dropped. */
- void netfs_nput (struct node *np);
-
-+/* The user must define this function in order to drop the soft references
-+ that this node may have. When this function is called, node NP has just
-+ lost its hard references and is now trying to also drop its soft references.
-+ If the node is stored in another data structure (for caching purposes),
-+ this allows the user to remove it so that the node can be safely deleted
-+ from memory. */
-+void netfs_try_dropping_softrefs (struct node *np);
-+
- /* Called internally when no more references to node NP exist. */
- void netfs_drop_node (struct node *np);
-
-diff --git a/libnetfs/nput.c b/libnetfs/nput.c
-index 522c714..b04fc4b 100644
---- a/libnetfs/nput.c
-+++ b/libnetfs/nput.c
-@@ -23,15 +23,24 @@
- void
- netfs_nput (struct node *np)
- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- assert (np->references);
-- np->references--;
-- if (np->references == 0)
-+ struct references result;
-+
-+ refcounts_demote (&np->refcounts, &result);
-+
-+ if (result.hard == 0)
-+ netfs_try_dropping_softrefs (np);
-+
-+ refcounts_deref_weak (&np->refcounts, &result);
-+
-+ if (result.hard == 0 && result.weak == 0)
- netfs_drop_node (np);
-- /* netfs_drop_node drops netfs_node_refcnt_lock for us. */
- else
-- {
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-- pthread_mutex_unlock (&np->lock);
-- }
-+ pthread_mutex_unlock (&np->lock);
-+}
-+
-+/* The last hard reference to NP has gone away; the user must define
-+ this function in order to drop all the soft references. */
-+void __attribute__ ((weak))
-+netfs_try_dropping_softrefs (struct node *np)
-+{
- }
-diff --git a/libnetfs/nref.c b/libnetfs/nref.c
-index 86b4992..d48d9c8 100644
---- a/libnetfs/nref.c
-+++ b/libnetfs/nref.c
-@@ -23,7 +23,13 @@
- void
- netfs_nref (struct node *np)
- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- np->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ struct references result;
-+ refcounts_ref (&np->refcounts, &result);
-+}
-+
-+void
-+netfs_nref_light (struct node *np)
-+{
-+ struct references result;
-+ refcounts_ref_weak (&np->refcounts, &result);
- }
-diff --git a/libnetfs/nrele.c b/libnetfs/nrele.c
-index 6f9a014..4dddd1f 100644
---- a/libnetfs/nrele.c
-+++ b/libnetfs/nrele.c
-@@ -23,15 +23,38 @@
- void
- netfs_nrele (struct node *np)
- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- assert (np->references);
-- np->references--;
-- if (np->references == 0)
-+ struct references result;
-+ int locked = FALSE;
-+
-+ refcounts_demote (&np->refcounts, &result);
-+
-+ if (result.hard == 0)
-+ {
-+ pthread_mutex_lock (&np->lock);
-+ netfs_try_dropping_softrefs (np);
-+ locked = TRUE;
-+ }
-+
-+ refcounts_deref_weak (&np->refcounts, &result);
-+
-+ if (result.hard == 0 && result.weak == 0)
-+ {
-+ if (! locked)
-+ pthread_mutex_lock (&np->lock);
-+ netfs_drop_node (np);
-+ } else if (locked)
-+ pthread_mutex_unlock (&np->lock);
-+}
-+
-+void
-+netfs_nrele_light (struct node *np)
-+{
-+ struct references result;
-+
-+ refcounts_deref_weak (&np->refcounts, &result);
-+ if (result.hard == 0 && result.weak == 0)
- {
- pthread_mutex_lock (&np->lock);
- netfs_drop_node (np);
-- /* netfs_drop_node drops netfs_node_refcnt_lock for us. */
- }
-- else
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
- }
-diff --git a/nfs/cache.c b/nfs/cache.c
-index b48152e..2015603 100644
---- a/nfs/cache.c
-+++ b/nfs/cache.c
-@@ -49,6 +49,8 @@ static struct hurd_ihash nodehash =
- + offsetof (struct netnode, slot), NULL, NULL,
- ihash_hash, ihash_compare);
-
-+pthread_mutex_t nodehash_ihash_lock = PTHREAD_MUTEX_INITIALIZER;
-+
- /* 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
-@@ -60,12 +62,12 @@ lookup_fhandle (struct fhandle *handle, struct node **npp)
- struct node *np;
- struct netnode *nn;
-
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-+ pthread_mutex_lock (&nodehash_ihash_lock);
- np = hurd_ihash_find (&nodehash, (hurd_ihash_key_t) handle);
- if (np)
- {
-- np->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (np);
-+ pthread_mutex_unlock (&nodehash_ihash_lock);
- pthread_mutex_lock (&np->lock);
- *npp = np;
- return;
-@@ -84,9 +86,9 @@ lookup_fhandle (struct fhandle *handle, struct node **npp)
- nn->dead_name = 0;
-
- hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &nn->handle, np);
-+ netfs_nref_light (np);
-+ pthread_mutex_unlock (&nodehash_ihash_lock);
- pthread_mutex_lock (&np->lock);
--
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-
- *npp = np;
- }
-@@ -114,9 +116,7 @@ forked_node_delete (void *arg)
- };
-
- /* Called by libnetfs when node NP has no more references. (See
-- <hurd/libnetfs.h> for details. Just clear its local state and
-- remove it from the hash table. Called and expected to leave with
-- NETFS_NODE_REFCNT_LOCK held. */
-+ <hurd/libnetfs.h> for details. */
- void
- netfs_node_norefs (struct node *np)
- {
-@@ -129,8 +129,7 @@ netfs_node_norefs (struct node *np)
- args = malloc (sizeof (struct fnd));
- assert (args);
-
-- np->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (np);
-
- args->dir = np->nn->dead_dir;
- args->name = np->nn->dead_name;
-@@ -149,19 +148,26 @@ netfs_node_norefs (struct node *np)
- errno = err;
- perror ("pthread_create");
- }
--
-- /* Caller expects us to leave this locked... */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- }
- else
- {
-- hurd_ihash_locp_remove (&nodehash, np->nn->slot);
- if (np->nn->dtrans == SYMLINK)
-- free (np->nn->transarg.name);
-+ free (np->nn->transarg.name);
- free (np);
- }
- }
-
-+/* When dropping soft refs, we simply remove the node from the
-+ node cache. */
-+void
-+netfs_try_dropping_softrefs (struct node *np)
-+{
-+ pthread_mutex_lock (&nodehash_ihash_lock);
-+ hurd_ihash_locp_remove (&nodehash, np->nn->slot);
-+ netfs_nrele_light (np);
-+ pthread_mutex_unlock (&nodehash_ihash_lock);
-+}
-+
- /* Change the file handle used for node NP to be the handle at P.
- Make sure the hash table stays up to date. Return the address
- after the handle. The lock on the node should be held. */
-@@ -179,7 +185,7 @@ recache_handle (int *p, struct node *np)
- }
-
- /* Unlink it */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-+ pthread_mutex_lock (&nodehash_ihash_lock);
- hurd_ihash_locp_remove (&nodehash, np->nn->slot);
-
- /* Change the name */
-@@ -189,6 +195,6 @@ recache_handle (int *p, struct node *np)
- /* Reinsert it */
- hurd_ihash_add (&nodehash, (hurd_ihash_key_t) &np->nn->handle, np);
-
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ pthread_mutex_unlock (&nodehash_ihash_lock);
- return p + len / sizeof (int);
- }
-diff --git a/nfs/ops.c b/nfs/ops.c
-index 79cd3a6..33ab38b 100644
---- a/nfs/ops.c
-+++ b/nfs/ops.c
-@@ -1267,7 +1267,10 @@ netfs_attempt_unlink (struct iouser *cred, struct node *dir,
- one we just got; if so, we must give this file another link
- so that when we delete the one we are asked for it doesn't go
- away entirely. */
-- if (np->references > 1)
-+ struct references result;
-+ refcounts_references (&np->refcounts, &result);
-+
-+ if (result.hard > 1)
- {
- char *newname = 0;
- int n = 0;
-diff --git a/procfs/netfs.c b/procfs/netfs.c
-index 276c57c..0b3d31a 100644
---- a/procfs/netfs.c
-+++ b/procfs/netfs.c
-@@ -222,12 +222,8 @@ error_t netfs_attempt_lookup (struct iouser *user, struct node *dir,
- free all its associated storage. */
- void netfs_node_norefs (struct node *np)
- {
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
--
- procfs_cleanup (np);
- free (np);
--
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- }
-
- /* The user may define this function (but should define it together
-diff --git a/trans/fakeroot.c b/trans/fakeroot.c
-index cb4f818..6fdf75a 100644
---- a/trans/fakeroot.c
-+++ b/trans/fakeroot.c
-@@ -110,6 +110,9 @@ new_node (file_t file, mach_port_t idport, int locked, int openmodes,
-
- if (!locked)
- pthread_mutex_lock (&idport_ihash_lock);
-+ /* The light reference allows us to safely keep the node in the
-+ hash table. */
-+ netfs_nref_light (*np);
- err = hurd_ihash_add (&idport_ihash, nn->idport, *np);
- if (err)
- goto lose;
-@@ -155,22 +158,31 @@ set_faked_attribute (struct node *np, unsigned int faked)
- }
- }
-
-+void
-+netfs_try_dropping_softrefs (struct node *np)
-+{
-+ /* We have to drop our light reference by removing the node from the
-+ idport_ihash hash table. */
-+ pthread_mutex_lock (&idport_ihash_lock);
-+
-+ hurd_ihash_locp_remove (&idport_ihash, netfs_node_netnode (np)->idport_locp);
-+ netfs_nrele_light (np);
-+
-+ pthread_mutex_unlock (&idport_ihash_lock);
-+}
-+
- /* Node NP has no more references; free all its associated storage. */
- void
- netfs_node_norefs (struct node *np)
- {
- pthread_mutex_unlock (&np->lock);
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-
-- pthread_mutex_lock (&idport_ihash_lock);
-- hurd_ihash_locp_remove (&idport_ihash, netfs_node_netnode (np)->idport_locp);
-- pthread_mutex_unlock (&idport_ihash_lock);
-+ /* NP was already removed from idport_ihash through
-+ netfs_try_dropping_softrefs. */
-
- mach_port_deallocate (mach_task_self (), netfs_node_netnode (np)->file);
- mach_port_deallocate (mach_task_self (), netfs_node_netnode (np)->idport);
- free (np);
--
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- }
-
- /* This is the cleanup function we install in netfs_protid_class. If
-@@ -363,29 +375,27 @@ netfs_S_dir_lookup (struct protid *diruser,
- redo_hash_lookup:
- pthread_mutex_lock (&idport_ihash_lock);
- pthread_mutex_lock (&dnp->lock);
-- /* The hashtable may not hold a true reference on the node. Acquire the
-- refcount lock so that, if a node is found, its reference counter cannot
-- drop to 0 before we get our own reference. */
-- pthread_spin_lock (&netfs_node_refcnt_lock);
- np = hurd_ihash_find (&idport_ihash, idport);
- if (np != NULL)
- {
-- /* We already know about this node. */
-+ /* We quickly check that NP has hard references. If the node is being
-+ removed, netfs_try_dropping_softrefs is attempting to drop the light
-+ reference on this. */
-+ struct references result;
-+
-+ refcounts_references (&np->refcounts, &result);
-
-- if (np->references == 0)
-+ if (result.hard == 0)
- {
-- /* But it might be in the process of being released. If so,
-- unlock the hash table to give the node a chance to actually
-+ /* If so, unlock the hash table to give the node a chance to actually
- be removed and retry. */
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
- pthread_mutex_unlock (&dnp->lock);
- pthread_mutex_unlock (&idport_ihash_lock);
- goto redo_hash_lookup;
- }
-
- /* Otherwise, reference it right away. */
-- np->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ netfs_nref (np);
-
- mach_port_deallocate (mach_task_self (), idport);
-
-@@ -405,7 +415,6 @@ netfs_S_dir_lookup (struct protid *diruser,
- }
- else
- {
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
- err = new_node (file, idport, 1, flags & (O_RDWR|O_EXEC), &np);
- pthread_mutex_unlock (&dnp->lock);
- if (!err)
-diff --git a/usermux/mux.c b/usermux/mux.c
-index bfa95fd..7c57f94 100644
---- a/usermux/mux.c
-+++ b/usermux/mux.c
-@@ -298,10 +298,8 @@ lookup_cached (struct usermux *mux, const char *user, int purge,
-
- if (strcasecmp (user, nm->name) == 0)
- {
-- pthread_spin_lock (&netfs_node_refcnt_lock);
-- if (nm->node)
-- nm->node->references++;
-- pthread_spin_unlock (&netfs_node_refcnt_lock);
-+ if (nm->node)
-+ netfs_nref (nm->node);
-
- if (nm->node)
- {
---
-2.1.4
-
diff --git a/debian/patches/series b/debian/patches/series
index 7dc39d91..cf958390 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -36,6 +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
crash0001-xxx-crash-logging-works.patch
-flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch
gpg0001-trans-add-transparent-GnuPG-translator.patch
gpg0002-adjust-to-lockless-libnetfs.patch