summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-09-07 23:41:02 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-09-07 23:41:02 +0000
commit0c4e6afe2876a89fda34a9cdeeeadb7bd421eaaa (patch)
tree73edd85eb8f66b3daed0385e80d752d0468d252f
parentd08efc4f73ff782a83d676611474af0068ecb843 (diff)
Formerly dir-lookup.c.~5~
-rw-r--r--libdiskfs/dir-lookup.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 56b6580e..0b3cea14 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -163,7 +163,11 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* If this is translated, start the translator (if necessary)
and return. */
- if (!lastcomp || !(flags & O_NOTRANS))
+ /* The check for `np != dnp' simplifies this code a great
+ deal. Such a translator should already have been started,
+ so there's no lossage in doing it this way. */
+ if ((!lastcomp || !(flags & O_NOTRANS))
+ && np != dnp)
{
mach_port_t control;
uid_t *uids = 0, *gids;
@@ -173,14 +177,6 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* Be very careful not to hold an inode lock while fetching
a translator lock and vice versa. */
- /* Our code depends heavily on these being different.
- This case can't happen in real life, so we're fine. */
- if (np == dnp)
- {
- error = ED;
- goto out;
- }
-
mutex_unlock (&np->lock);
mutex_unlock (&dnp->lock);
@@ -254,6 +250,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
strcat (retryname, "/");
strcat (retryname, nextname);
}
+ *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
diskfs_nrele (dnp);
diskfs_nrele (np);
mach_port_deallocate (mach_task_self (), dirfile);
@@ -261,7 +258,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
}
else
{
- /* If we get here, then we have no control port.
+ /* If we get here, then we have no active control port.
Check to see if there is a passive translator, and if so
repeat the translator check. */
mutex_unlock (&np->translator.lock);
@@ -298,8 +295,20 @@ diskfs_S_dir_lookup (struct protid *dircred,
goto repeat_trans;
}
}
+
+ /* We're here if we tried the translator check, and it
+ failed. Lock everything back, and make sure we do it
+ in the right order. */
+ if (strcmp (path, ".."))
+ {
+ mutex_unlock (&np->lock);
+ mutex_lock (&dnp->lock);
+ mutex_lock (&np->lock);
+ }
+ else
+ mutex_lock (&dnp->lock);
}
-
+
if (S_ISLNK (np->dn_stat.st_mode)
&& !(lastcomp && (flags & (O_NOLINK|O_NOTRANS))))
{