diff options
author | Justus Winter <justus@gnupg.org> | 2016-03-21 19:46:07 +0100 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-03-21 19:46:07 +0100 |
commit | 94f3a5a97de1aa03c74bb8682bde509eb07d21b7 (patch) | |
tree | a0c33265a45da977f2b1a9980c9309062811c3f7 | |
parent | 8d00a764c4abbb07fd4656ccaa7cd1deb0a27d41 (diff) |
drop old patch series
-rw-r--r-- | debian/patches/flavio0001-Remove-global-netfs-lock-and-use-hard-and-soft-refer.patch | 775 | ||||
-rw-r--r-- | debian/patches/series | 1 |
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 |