commit-hurd
[Top][All Lists]
Advanced

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

[hurd] 01/53: trans/fakeroot: fix cached node retrieval on lookup


From: Samuel Thibault
Subject: [hurd] 01/53: trans/fakeroot: fix cached node retrieval on lookup
Date: Thu, 20 Mar 2014 02:23:49 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch upstream
in repository hurd.

commit 1ea83c98a8fb8f58a4de8368d1fa29d341a2a73c
Author: Richard Braun <address@hidden>
Date:   Fri Feb 7 22:54:24 2014 +0100

    trans/fakeroot: fix cached node retrieval on lookup
    
    When a client finds a node from the hash table, it could happen that
    another thread is still holding one reference on it before the current
    thread has acquired its own. Simply checking for a non zero refcount isn't
    enough, the new client must atomically acquire its own reference.
    
    * trans/fakeroot.c (netfs_S_dir_lookup): Find and acquire node reference
    while holding netfs_node_refcnt_lock.
---
 trans/fakeroot.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index 3038612..c519180 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -348,6 +348,10 @@ 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);
   struct netnode *nn = hurd_ihash_find (&idport_ihash, idport);
   if (nn != NULL)
     {
@@ -359,12 +363,17 @@ netfs_S_dir_lookup (struct protid *diruser,
          /* But it might be in the process of being released.  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 = nn->np;
+      np->references++;
+      pthread_spin_unlock (&netfs_node_refcnt_lock);
+
       mach_port_deallocate (mach_task_self (), idport);
 
       if (np == dnp)
@@ -377,12 +386,12 @@ netfs_S_dir_lookup (struct protid *diruser,
          pthread_mutex_unlock (&dnp->lock);
        }
 
-      netfs_nref (np);
       err = check_openmodes (np->nn, (flags & (O_RDWR|O_EXEC)), file);
       pthread_mutex_unlock (&idport_ihash_lock);
     }
   else
     {
+      pthread_spin_unlock (&netfs_node_refcnt_lock);
       err = new_node (file, idport, 1, flags, &np);
       pthread_mutex_unlock (&dnp->lock);
       if (!err)

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

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