diff options
author | Roland McGrath <roland@gnu.org> | 2002-05-05 19:19:51 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-05-05 19:19:51 +0000 |
commit | 487313dde283a4f8d1890d9d23dc45e481d68dbf (patch) | |
tree | 01187c27a71f4e4cb406c056bc1ee060b7823013 /trans | |
parent | 77d37fdfaafbfa2a6a2125da7525d754e77f8939 (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.c | 23 |
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; |