summaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1998-10-24 07:32:00 +0000
committerRoland McGrath <roland@gnu.org>1998-10-24 07:32:00 +0000
commit6875a586d28418b4ed203dc00cc8db3061f9a003 (patch)
treef0b45eea99c6c8c080936a60c1ae09815ee5f260 /libdiskfs
parentf8e9c21bc6f36840b308da7bb1c2d1be79386830 (diff)
1998-04-04 Roland McGrath <roland@baalperazim.frob.com>
* dir-lookup.c (diskfs_S_dir_lookup): Treat a shadow_root with null shadow_root_parent as a "virtual root".
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/dir-lookup.c89
1 files changed, 53 insertions, 36 deletions
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 681048cd..9bb1d8a1 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs:dir_lookup
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -134,37 +134,52 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* If we get an error we're done */
if (error == EAGAIN)
- if (dnp == dircred->po->shadow_root)
- /* We're at the root of a shadow tree. */
- {
- *retry = FS_RETRY_REAUTH;
- *returned_port = dircred->po->shadow_root_parent;
- *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
- if (! lastcomp)
- strcpy (retryname, nextname);
- error = 0;
- goto out;
- }
- else if (dircred->po->root_parent != MACH_PORT_NULL)
- /* We're at a real translator root; even if DIRCRED->po has a
- shadow root, we can get here if its in a directory that was
- renamed out from under it... */
- {
- *retry = FS_RETRY_REAUTH;
- *returned_port = dircred->po->root_parent;
- *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
- if (!lastcomp)
- strcpy (retryname, nextname);
- error = 0;
- goto out;
- }
- else
- /* We're at a REAL root, as in there's no way up from here. */
- {
- error = 0;
- np = dnp;
- diskfs_nref (np);
- }
+ {
+ if (dnp == dircred->po->shadow_root)
+ /* We're at the root of a shadow tree. */
+ {
+ if (dircred->po->shadow_root_parent == MACH_PORT_NULL)
+ {
+ /* This is a shadow root with no parent, meaning
+ we should treat it as a virtual root disconnected
+ from its real .. directory. */
+ error = 0;
+ np = dnp;
+ diskfs_nref (np);
+ }
+ else
+ {
+ /* Punt the client up to the shadow root parent. */
+ *retry = FS_RETRY_REAUTH;
+ *returned_port = dircred->po->shadow_root_parent;
+ *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
+ if (! lastcomp)
+ strcpy (retryname, nextname);
+ error = 0;
+ goto out;
+ }
+ }
+ else if (dircred->po->root_parent != MACH_PORT_NULL)
+ /* We're at a real translator root; even if DIRCRED->po has a
+ shadow root, we can get here if its in a directory that was
+ renamed out from under it... */
+ {
+ *retry = FS_RETRY_REAUTH;
+ *returned_port = dircred->po->root_parent;
+ *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
+ if (!lastcomp)
+ strcpy (retryname, nextname);
+ error = 0;
+ goto out;
+ }
+ else
+ /* We're at a REAL root, as in there's no way up from here. */
+ {
+ error = 0;
+ np = dnp;
+ diskfs_nref (np);
+ }
+ }
/* Create the new node if necessary */
if (lastcomp && create)
@@ -439,10 +454,12 @@ diskfs_S_dir_lookup (struct protid *dircred,
out:
if (np)
- if (dnp == np)
- diskfs_nrele (np);
- else
- diskfs_nput (np);
+ {
+ if (dnp == np)
+ diskfs_nrele (np);
+ else
+ diskfs_nput (np);
+ }
if (dnp)
diskfs_nput (dnp);