summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-04-21 17:51:40 +0200
committerJustus Winter <justus@gnupg.org>2016-05-19 22:27:37 +0200
commit7dbebff1ff08d347aad14e76e371f1cb6991dac7 (patch)
treee7b2ca1470de643eaf2ee097d9f166c17832c066
parent13efe6721a370c38b65e0da3d33f310f42cfa05f (diff)
libnetfs: treat disconnected shadow roots as virtual roots
* libnetfs/dir-lookup.c (netfs_S_dir_lookup): Treat a shadow_root with null shadow_root_parent as a "virtual root". Analog to 6875a586.
-rw-r--r--libnetfs/dir-lookup.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index 3bcc745e..731e53cb 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -125,16 +125,29 @@ netfs_S_dir_lookup (struct protid *dircred,
if (dnp == dircred->po->shadow_root)
/* We're at the root of a shadow tree. */
{
- *do_retry = FS_RETRY_REAUTH;
- *retry_port = dircred->po->shadow_root_parent;
- *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (lastcomp && mustbedir) /* Trailing slash. */
- strcpy (retry_name, "/");
- else if (!lastcomp)
- strcpy (retry_name, nextname);
- err = 0;
- pthread_mutex_unlock (&dnp->lock);
- goto out;
+ 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. */
+ err = 0;
+ np = dnp;
+ netfs_nref (np);
+ }
+ else
+ {
+ /* Punt the client up to the shadow root parent. */
+ *do_retry = FS_RETRY_REAUTH;
+ *retry_port = dircred->po->shadow_root_parent;
+ *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
+ if (lastcomp && mustbedir) /* Trailing slash. */
+ strcpy (retry_name, "/");
+ else if (!lastcomp)
+ strcpy (retry_name, nextname);
+ err = 0;
+ pthread_mutex_unlock (&dnp->lock);
+ goto out;
+ }
}
else if (dircred->po->root_parent != MACH_PORT_NULL)
/* We're at a real translator root; even if DIRCRED->po has a