summaryrefslogtreecommitdiff
path: root/nfs
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 /nfs
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 'nfs')
-rw-r--r--nfs/cache.c40
-rw-r--r--nfs/ops.c5
2 files changed, 27 insertions, 18 deletions
diff --git a/nfs/cache.c b/nfs/cache.c
index b48152ea..2015603b 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 79cd3a64..33ab38b7 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;