summaryrefslogtreecommitdiff
path: root/console
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2016-03-15 04:50:02 -0400
committerJustus Winter <justus@gnupg.org>2016-03-21 19:45:11 +0100
commit5eef605eb523e4148ccd22578327492178cfd0c4 (patch)
treeaab9f03896e9acec97d99b5617bf7792f6022f0d /console
parent0da2914ac9d9321cca2d402b2c505881e436c725 (diff)
netfs: Remove global reference count lock.
* 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.
Diffstat (limited to 'console')
-rw-r--r--console/console.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/console/console.c b/console/console.c
index 57ae8133..9c5869dd 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;
}
}