bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 7/8] nfs: Use refcounts_t to track node references.


From: Flavio Cruz
Subject: [PATCH 7/8] nfs: Use refcounts_t to track node references.
Date: Sun, 6 Mar 2016 17:06:40 -0500
User-agent: Mutt/1.5.24 (2015-08-30)

* 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.
---
 nfs/cache.c | 40 +++++++++++++++++++++++-----------------
 nfs/ops.c   |  5 ++++-
 2 files changed, 27 insertions(+), 18 deletions(-)

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;
-- 
2.6.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]