summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Cruz <flaviocruz@gmail.com>2016-01-13 00:58:59 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-01-13 00:58:59 +0100
commit076957fe8c12344ddae2fa4b966c7be9be232654 (patch)
treeda32c0b3738f6acc2e05d708d9236d62069fd8ff
parent1a7e27057ed5974be103c60afecdc8aae691584f (diff)
Fix O_DIRECTORY lookup on trivial translators
* libdiskfs/dir-lookup.c (diskfs_S_dir_lookup): If mustbedir, make sure entry is a directory by retrying "/", or starting the translator and retrying "/". * libnetfs/dir-lookup.c (netfs_S_dir_lookup): Likewise.
-rw-r--r--libdiskfs/dir-lookup.c21
-rw-r--r--libnetfs/dir-lookup.c22
2 files changed, 31 insertions, 12 deletions
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 75df9b80..8b986e49 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -161,7 +161,9 @@ diskfs_S_dir_lookup (struct protid *dircred,
*retry = FS_RETRY_REAUTH;
*returned_port = dircred->po->shadow_root_parent;
*returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
- if (! lastcomp)
+ if (lastcomp && mustbedir) /* Trailing slash. */
+ strcpy (retryname, "/");
+ else if (!lastcomp)
strcpy (retryname, nextname);
err = 0;
goto out;
@@ -175,7 +177,9 @@ diskfs_S_dir_lookup (struct protid *dircred,
*retry = FS_RETRY_REAUTH;
*returned_port = dircred->po->root_parent;
*returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
- if (!lastcomp)
+ if (lastcomp && mustbedir) /* Trailing slash. */
+ strcpy (retryname, "/");
+ else if (!lastcomp)
strcpy (retryname, nextname);
err = 0;
goto out;
@@ -213,7 +217,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
/* If this is translated, start the translator (if necessary)
and return. */
- if ((((flags & O_NOTRANS) == 0) || !lastcomp)
+ if ((((flags & O_NOTRANS) == 0) || !lastcomp || mustbedir)
&& ((np->dn_stat.st_mode & S_IPTRANS)
|| S_ISFIFO (np->dn_stat.st_mode)
|| S_ISCHR (np->dn_stat.st_mode)
@@ -304,11 +308,16 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (err != ENOENT)
{
*returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
- if (!lastcomp && !err)
+ if (!err)
{
char *end = strchr (retryname, '\0');
- *end++ = '/';
- strcpy (end, nextname);
+ if (mustbedir)
+ *end++ = '/'; /* Trailing slash. */
+ else if (!lastcomp) {
+ if (end != retryname)
+ *end++ = '/';
+ strcpy (end, nextname);
+ }
}
if (register_translator)
diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index 8b8cd6ec..1fefd3ff 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -128,7 +128,9 @@ netfs_S_dir_lookup (struct protid *diruser,
*do_retry = FS_RETRY_REAUTH;
*retry_port = diruser->po->shadow_root_parent;
*retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (! lastcomp)
+ if (lastcomp && mustbedir) /* Trailing slash. */
+ strcpy (retry_name, "/");
+ else if (!lastcomp)
strcpy (retry_name, nextname);
error = 0;
pthread_mutex_unlock (&dnp->lock);
@@ -142,7 +144,9 @@ netfs_S_dir_lookup (struct protid *diruser,
*do_retry = FS_RETRY_REAUTH;
*retry_port = diruser->po->root_parent;
*retry_port_type = MACH_MSG_TYPE_COPY_SEND;
- if (!lastcomp)
+ if (lastcomp && mustbedir) /* Trailing slash. */
+ strcpy (retry_name, "/");
+ else if (!lastcomp)
strcpy (retry_name, nextname);
error = 0;
pthread_mutex_unlock (&dnp->lock);
@@ -194,7 +198,7 @@ netfs_S_dir_lookup (struct protid *diruser,
if (error)
goto out;
- if ((((flags & O_NOTRANS) == 0) || !lastcomp)
+ if ((((flags & O_NOTRANS) == 0) || !lastcomp || mustbedir)
&& ((np->nn_translated & S_IPTRANS)
|| S_ISFIFO (np->nn_translated)
|| S_ISCHR (np->nn_translated)
@@ -288,10 +292,16 @@ netfs_S_dir_lookup (struct protid *diruser,
if (error != ENOENT)
{
*retry_port_type = MACH_MSG_TYPE_MOVE_SEND;
- if (!lastcomp && !error)
+ if (!error)
{
- strcat (retry_name, "/");
- strcat (retry_name, nextname);
+ char *end = strchr (retry_name, '\0');
+ if (mustbedir)
+ *end++ = '/'; /* Trailing slash. */
+ else if (!lastcomp) {
+ if (end != retry_name)
+ *end++ = '/';
+ strcpy (end, nextname);
+ }
}
if (register_translator)