From 7dbebff1ff08d347aad14e76e371f1cb6991dac7 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 21 Apr 2016 17:51:40 +0200 Subject: 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. --- libnetfs/dir-lookup.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'libnetfs') 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 -- cgit v1.2.3