summaryrefslogtreecommitdiff
path: root/trans
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-05-05 19:19:51 +0000
committerRoland McGrath <roland@gnu.org>2002-05-05 19:19:51 +0000
commit487313dde283a4f8d1890d9d23dc45e481d68dbf (patch)
tree01187c27a71f4e4cb406c056bc1ee060b7823013 /trans
parent77d37fdfaafbfa2a6a2125da7525d754e77f8939 (diff)
2002-05-05 Roland McGrath <roland@frob.com>
* fakeroot.c (netfs_attempt_lookup): Unlock DIR before doing RPCs.
Diffstat (limited to 'trans')
-rw-r--r--trans/fakeroot.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index 0eb514a9..3592d720 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -324,23 +324,32 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
char *name, struct node **np)
{
error_t err;
- int flags = O_RDWR|O_EXEC;
- file_t file = file_name_lookup_under (dir->nn->file, name,
- flags | O_NOLINK, 0);
+ int flags;
+ const file_t dirfile = dir->nn->file;
+ file_t file;
+
+ /* We must unlock the directory before making RPCs to the underlying
+ filesystem in case they somehow wind up trying to refer back to one of
+ our nodes. The DIRFILE port will not change or die as long as DIR
+ lives, and our caller holds a reference keeping it alive. */
+ mutex_unlock (&dir->lock);
+
+ flags = O_RDWR|O_EXEC;
+ file = file_name_lookup_under (dirfile, name, flags | O_NOLINK, 0);
if (file == MACH_PORT_NULL && errno == EACCES)
{
flags = O_RDWR;
- file = file_name_lookup_under (dir->nn->file, name, flags | O_NOLINK, 0);
+ file = file_name_lookup_under (dirfile, name, flags | O_NOLINK, 0);
}
if (file == MACH_PORT_NULL && errno == EACCES)
{
flags = O_READ|O_EXEC;
- file = file_name_lookup_under (dir->nn->file, name, flags | O_NOLINK, 0);
+ file = file_name_lookup_under (dirfile, name, flags | O_NOLINK, 0);
}
if (file == MACH_PORT_NULL && errno == EACCES)
{
flags = O_READ;
- file = file_name_lookup_under (dir->nn->file, name, flags | O_NOLINK, 0);
+ file = file_name_lookup_under (dirfile, name, flags | O_NOLINK, 0);
}
*np = 0;
if (file == MACH_PORT_NULL)
@@ -372,7 +381,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
}
}
}
- mutex_unlock (&dir->lock);
+
if (*np)
mutex_lock (&(*np)->lock);
return err;