commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 11/15: Traverse translator hierarchies using the fsys protocol.


From: Samuel Thibault
Subject: [hurd] 11/15: Traverse translator hierarchies using the fsys protocol.
Date: Sun, 19 Nov 2017 15:27:06 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch dde
in repository hurd.

commit 86ecc3fc9aa88091ac77ec35688d08634567d169
Author: Justus Winter <address@hidden>
Date:   Tue Aug 29 23:35:55 2017 +0200

    Traverse translator hierarchies using the fsys protocol.
    
    Previously, we used the fs protocol to traverse the translator
    hierarchies.  This, however, is conceptually flawed, because
    translators are bound to nodes, and a node can have zero or more links
    in the file system.  Therefore, the previous method of returning a
    list of paths to the client and expecting them to be able to follow
    these to reach the child translators was always unreliable.
    
    Fix this by using the fsys protocol to traverse the hierarchy, and
    returning the control ports of all children.  This is more robust, and
    also conceptually cleaner, because the fsys protocol is about
    translator linkage, hence this is the point to implement traversal.
    
    Also move the get source routine over.  A per-node source really
    does not fit the reality of most translators, while a per-translator
    source makes sense in many cases.
    
    * hurd/fs.defs (file_get_children): Drop routine.
    (file_get_source): Likewise.
    * hurd/fsys.defs (fsys_get_children): New routine.
    (fsys_get_source): Likewise.
    * libdiskfs/Makefile (FSYSSRCS): Remove files, add files.
    * libdiskfs/file-get-children.c: Remove file.
    * libdiskfs/fsys-get-children.c: New file.
    * libdiskfs/file-get-source.c: Remove file.
    * libdiskfs/fsys-get-source.c: New file.
    * libfshelp/fshelp.h (fshelp_filter): Remove type.
    (fshelp_get_active_translators): Remove filter and prefix argument,
    return list of control ports.
    * libfshelp/translator-list.c (fshelp_get_active_translators):
    Likewise.
    * libnetfs/Makefile (FSSRCS): Move 'get-source.c' too OTHERSRCS.
    (FSYSSRCS): Remove files, add files.
    * libnetfs/file-get-children.c: Remove file.
    * libnetfs/fsys-get-children.c: New file.
    * libnetfs/file-get-source.c: Remove file.
    * libnetfs/fsys-get-source.c: New file.
    * libtrivfs/Makefile: Move 'get-source.c' too OTHERSRCS.
    (FSYSSRCS): Remove files, add files.
    * libtrivfs/file-get-children.c: Remove file.
    * libtrivfs/fsys-get-children.c: New file.
    * libtrivfs/file-get-source.c: Remove file.
    * libtrivfs/fsys-get-source.c: Add file.
    * trans/Makefile (mtab): Build client stubs until the libc has caught
    on.
    * trans/mtab.c (target_control): New variable.
    (insecure): Drop variable.
    (all_translators): Likewise.
    (MAX_DEPTH): New macro.
    (max_depth): New variable.
    (options): Remove '--insecure' and '--all-translators', add '--depth'.
    (parse_opt): Adapt accordingly.
    (trivsfs_append_args): Likewise.
    (main): Get the control port of the target translator, then drop
    privileges.
    (is_filesystem_translator): Remove function.
    (mtab_mark_as_seen): Simplify.  Just check if the control port is
    known.
    (mtab_populate): Limit depth of recursion, adapt to traversing over
    the control ports, simplify.
    (open_hook): Remove scary comment, it is not applicable anymore
    because we no longer dir_lookup child translators.
---
 hurd/fs.defs                                       |  20 +-
 hurd/fsys.defs                                     |  25 ++-
 libdiskfs/Makefile                                 |   2 +-
 libdiskfs/file-get-children.c                      |  96 ---------
 libdiskfs/fsys-get-children.c                      |  74 +++++++
 libdiskfs/{file-get-source.c => fsys-get-source.c} |  26 +--
 libfshelp/fshelp.h                                 |  10 +-
 libfshelp/translator-list.c                        |  43 ++--
 libnetfs/Makefile                                  |   8 +-
 libnetfs/file-get-children.c                       | 108 ----------
 libnetfs/fsys-get-children.c                       |  74 +++++++
 libnetfs/{file-get-source.c => fsys-get-source.c}  |  24 ++-
 libtrivfs/Makefile                                 |   5 +-
 libtrivfs/file-get-children.c                      |  36 ----
 libtrivfs/fsys-get-children.c                      |  41 ++++
 libtrivfs/{file-get-source.c => fsys-get-source.c} |  22 +-
 trans/Makefile                                     |   2 +-
 trans/mtab.c                                       | 225 ++++++++-------------
 18 files changed, 367 insertions(+), 474 deletions(-)

diff --git a/hurd/fs.defs b/hurd/fs.defs
index a4a48cc..6c0b573 100644
--- a/hurd/fs.defs
+++ b/hurd/fs.defs
@@ -353,21 +353,5 @@ routine file_reparent (
        parent: mach_port_t;
        out new_file: mach_port_send_t);
 
-/* Return any active translators bound to nodes below FILE.  CHILDREN
-   is an argz vector containing file names relative to the path of
-   FILE.  */
-routine file_get_children (
-       file: file_t;
-       RPT
-       out children: data_t);
-
-/* Return information about the source of FILE.  If the concept of a
-   source is applicable, SOURCE should refer to the source of FILE and
-   should be a description considered appropriate in the context of
-   the translator.  For example, if FILE refers to a node on a
-   filesystems, SOURCE should be the file name of the underlying block
-   device.  */
-routine file_get_source (
-       file: file_t;
-       RPT
-       out source: string_t);
+skip;  /* Was: file_get_children.  */
+skip;  /* Was: file_get_source.  */
diff --git a/hurd/fsys.defs b/hurd/fsys.defs
index b36b944..35d483c 100644
--- a/hurd/fsys.defs
+++ b/hurd/fsys.defs
@@ -128,5 +128,26 @@ routine fsys_get_options (
        RPT
        out options: data_t, dealloc);
 
-skip;  /* Was fsys_get_children */
-skip;  /* Was fsys_get_source */
+/* Return any active child translators.  NAMES is an argz vector
+   containing file names relative to the root of the translator.
+   CONTROLS is an array containing the corresponding control ports.
+   Note that translators are bound to nodes, and nodes can have zero
+   or more links in the file system, therefore there is no guarantee
+   that a translators name refers to an existing link in the file
+   system.  */
+routine fsys_get_children (
+       server: fsys_t;
+       RPT
+       out names: data_t;
+       out controls: portarray_t);
+
+/* Return information about the source of the translator.  If the
+   concept of a source is applicable, SOURCE should refer to the
+   source of the translator and should be a description considered
+   appropriate in the context of the translator.  For example, if the
+   translator is a filesystem residing on a block device, then SOURCE
+   should be the file name of the underlying block device.  */
+routine fsys_get_source (
+       server: fsys_t;
+       RPT
+       out source: string_t);
diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
index 93c96fa..5716ac5 100644
--- a/libdiskfs/Makefile
+++ b/libdiskfs/Makefile
@@ -35,7 +35,7 @@ IOSRCS= io-async-icky.c io-async.c io-duplicate.c 
io-get-conch.c io-revoke.c \
        io-select.c io-stat.c io-stubs.c io-write.c io-version.c io-sigio.c
 FSYSSRCS=fsys-getroot.c fsys-goaway.c fsys-startup.c fsys-getfile.c \
        fsys-options.c fsys-syncfs.c fsys-forward.c \
-       file-get-children.c file-get-source.c
+       fsys-get-children.c fsys-get-source.c
 IFSOCKSRCS=ifsock.c
 OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \
        extern-inline.c \
diff --git a/libdiskfs/file-get-children.c b/libdiskfs/file-get-children.c
deleted file mode 100644
index 98d5d60..0000000
--- a/libdiskfs/file-get-children.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* file_get_children
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
-
-   This file is part of the GNU Hurd.
-
-   The GNU Hurd is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   The GNU Hurd is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "priv.h"
-#include "fs_S.h"
-
-#include <argz.h>
-
-/* Return any active translators bound to nodes below CRED.  CHILDREN
-   is an argz vector containing file names relative to the path of
-   CRED.  */
-error_t
-diskfs_S_file_get_children (struct protid *cred,
-                           char **children,
-                           mach_msg_type_number_t *children_len)
-{
-  error_t err;
-  if (! cred
-      || cred->pi.bucket != diskfs_port_bucket
-      || cred->pi.class != diskfs_protid_class)
-    return EOPNOTSUPP;
-
-  /* check_access performs the same permission check as is normally
-     done, i.e. it checks that all but the last path components are
-     executable by the requesting user and that the last component is
-     readable. */
-  error_t check_access (const char *path)
-  {
-    error_t err;
-    char *elements = NULL;
-    size_t elements_len = 0;
-
-    err = argz_create_sep (path, '/', &elements, &elements_len);
-    if (err)
-      return err;
-
-    struct node *dp = diskfs_root_node;
-
-    for (char *entry = elements;
-        entry;
-        entry = argz_next (elements, elements_len, entry))
-      {
-       struct node *next;
-       err = diskfs_lookup (dp, entry, LOOKUP, &next, NULL, cred);
-
-       if (dp != diskfs_root_node)
-         diskfs_nput (dp);
-
-       if (err)
-         return err;
-
-       dp = next;
-      }
-
-    err = fshelp_access (&dp->dn_stat, S_IRUSR, cred->user);
-    diskfs_nput (dp);
-    return err;
-  }
-
-
-  char *c = NULL;
-  size_t c_len = 0;
-
-  err = fshelp_get_active_translators (&c, &c_len, check_access,
-                                      cred->po->path);
-  if (err)
-    goto errout;
-
-  err = iohelp_return_malloced_buffer (c, c_len, children, children_len);
-  if (err)
-    goto errout;
-
-  c = NULL; /* c was freed by iohelp_return_malloced_buffer. */
-
- errout:
-  free (c);
-  return err;
-}
diff --git a/libdiskfs/fsys-get-children.c b/libdiskfs/fsys-get-children.c
new file mode 100644
index 0000000..7e2a37b
--- /dev/null
+++ b/libdiskfs/fsys-get-children.c
@@ -0,0 +1,74 @@
+/* fsys_get_children
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "priv.h"
+#include "fsys_S.h"
+
+#include <argz.h>
+
+/* Return any active child translators.  NAMES is an argz vector
+   containing file names relative to the root of the translator.
+   CONTROLS is an array containing the corresponding control ports.
+   Note that translators are bound to nodes, and nodes can have zero
+   or more links in the file system, therefore there is no guarantee
+   that a translators name refers to an existing link in the file
+   system.  */
+error_t
+diskfs_S_fsys_get_children (struct diskfs_control *fsys,
+                            mach_port_t reply,
+                            mach_msg_type_name_t replytype,
+                           char **names,
+                           mach_msg_type_number_t *names_len,
+                            mach_port_t **controls,
+                            mach_msg_type_name_t *controlsPoly,
+                           mach_msg_type_number_t *controlsCnt)
+{
+  error_t err;
+  char *n = NULL;
+  size_t n_len = 0;
+  mach_port_t *c;
+  size_t c_count;
+
+  if (! fsys)
+    return EOPNOTSUPP;
+
+
+  err = fshelp_get_active_translators (&n, &n_len, &c, &c_count);
+  if (err)
+    goto errout;
+
+  err = iohelp_return_malloced_buffer (n, n_len, names, names_len);
+  if (err)
+    goto errout;
+  n = NULL; /* n was freed by iohelp_return_malloced_buffer. */
+
+  err = iohelp_return_malloced_buffer ((char *) c, c_count * sizeof *c,
+                                       (char **) controls, controlsCnt);
+  if (err)
+    goto errout;
+  c = NULL; /* c was freed by iohelp_return_malloced_buffer. */
+
+  *controlsPoly = MACH_MSG_TYPE_MOVE_SEND;
+  *controlsCnt = c_count;
+
+ errout:
+  free (n);
+  free (c);
+  return err;
+}
diff --git a/libdiskfs/file-get-source.c b/libdiskfs/fsys-get-source.c
similarity index 54%
rename from libdiskfs/file-get-source.c
rename to libdiskfs/fsys-get-source.c
index d983a82..59eee55 100644
--- a/libdiskfs/file-get-source.c
+++ b/libdiskfs/fsys-get-source.c
@@ -1,8 +1,6 @@
-/* file_get_source
+/* fsys_get_source
 
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+   Copyright (C) 2017 Free Software Foundation, Inc.
 
    This file is part of the GNU Hurd.
 
@@ -20,17 +18,21 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
-#include "fs_S.h"
-
-/* Return information about the source of the receiving
-   filesystem. */
+#include "fsys_S.h"
+
+/* Return information about the source of the translator.  If the
+   concept of a source is applicable, SOURCE should refer to the
+   source of the translator and should be a description considered
+   appropriate in the context of the translator.  For example, if the
+   translator is a filesystem residing on a block device, then SOURCE
+   should be the file name of the underlying block device.  */
 error_t
-diskfs_S_file_get_source (struct protid *cred,
+diskfs_S_fsys_get_source (struct diskfs_control *fsys,
+                          mach_port_t reply,
+                          mach_msg_type_name_t replytype,
                          char *source)
 {
-  if (! cred
-      || cred->pi.bucket != diskfs_port_bucket
-      || cred->pi.class != diskfs_protid_class)
+  if (! fsys)
     return EOPNOTSUPP;
 
   return diskfs_get_source (source, 1024 /* XXX */);
diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h
index 7663ba1..e8ce973 100644
--- a/libfshelp/fshelp.h
+++ b/libfshelp/fshelp.h
@@ -55,12 +55,6 @@ fshelp_set_active_translator (struct port_info *pi,
 error_t
 fshelp_remove_active_translator (mach_port_t active);
 
-/* This kind of function is used by fshelp_get_active_translators to
-   filter the list of translators to return.  If a filter returns an
-   error for a given PATH, the translator bound to the PATH is not
-   included in the list.  */
-typedef error_t (*fshelp_filter) (const char *path);
-
 /* Records the list of active translators below PREFIX into the argz
    vector specified by TRANSLATORS filtered by FILTER.  If PREFIX is
    NULL, entries with any prefix are considered.  If FILTER is NULL,
@@ -68,8 +62,8 @@ typedef error_t (*fshelp_filter) (const char *path);
 error_t
 fshelp_get_active_translators (char **translators,
                               size_t *translators_len,
-                              fshelp_filter filter,
-                              const char *prefix);
+                              mach_port_t **controls,
+                               size_t *controls_count);
 
 /* Call FUN for each active translator.  If FUN returns non-zero, the
    iteration immediately stops, and returns that value.  FUN is called
diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c
index 7077b21..92b31dd 100644
--- a/libfshelp/translator-list.c
+++ b/libfshelp/translator-list.c
@@ -198,45 +198,32 @@ fshelp_remove_active_translator (mach_port_t active)
 error_t
 fshelp_get_active_translators (char **translators,
                               size_t *translators_len,
-                              fshelp_filter filter,
-                              const char *prefix)
+                              mach_port_t **controls,
+                               size_t *controls_count)
 {
   error_t err = 0;
   pthread_mutex_lock (&translator_ihash_lock);
 
-  if (prefix && strlen (prefix) == 0)
-    prefix = NULL;
+  *controls = calloc (translator_ihash.nr_items, sizeof **controls);
+  if (*controls == NULL)
+    {
+      pthread_mutex_unlock (&translator_ihash_lock);
+      return ENOMEM;
+    }
+  *controls_count = 0;
 
   HURD_IHASH_ITERATE (&translator_ihash, value)
     {
       struct translator *t = value;
 
-      if (prefix != NULL
-         && (strncmp (t->name, prefix, strlen (prefix)) != 0
-             || t->name[strlen (prefix)] != '/'))
-       /* Skip this entry, as it is not below PREFIX.  */
+      err = mach_port_mod_refs (mach_task_self (), t->active,
+                               MACH_PORT_RIGHT_SEND, +1);
+      if (err)
        continue;
+      (*controls)[*controls_count] = t->active;
+      (*controls_count)++;
 
-      if (filter)
-       {
-         char *dir = strdup (t->name);
-         if (! dir)
-           {
-             err = ENOMEM;
-             break;
-           }
-
-         err = filter (dirname (dir));
-         free (dir);
-         if (err)
-           {
-             err = 0;
-             continue; /* Skip this entry.  */
-           }
-       }
-
-      err = argz_add (translators, translators_len,
-                     &t->name[prefix? strlen (prefix) + 1: 0]);
+      err = argz_add (translators, translators_len, t->name);
       if (err)
        break;
     }
diff --git a/libnetfs/Makefile b/libnetfs/Makefile
index c3830c0..de06816 100644
--- a/libnetfs/Makefile
+++ b/libnetfs/Makefile
@@ -34,8 +34,7 @@ FSSRCS= dir-link.c dir-lookup.c dir-mkdir.c dir-mkfile.c \
        file-get-translator.c file-getcontrol.c file-getlinknode.c \
        file-lock-stat.c file-lock.c file-set-size.c \
        file-set-translator.c file-statfs.c file-sync.c file-syncfs.c \
-       file-utimes.c file-reparent.c fsstubs.c file-get-transcntl.c \
-       get-source.c
+       file-utimes.c file-reparent.c fsstubs.c file-get-transcntl.c
 
 IOSRCS=        io-read.c io-readable.c io-seek.c io-write.c io-stat.c 
io-async.c     \
        io-set-all-openmodes.c io-get-openmodes.c io-set-some-openmodes.c     \
@@ -45,7 +44,7 @@ IOSRCS=       io-read.c io-readable.c io-seek.c io-write.c 
io-stat.c io-async.c     \
        io-version.c
 
 FSYSSRCS= fsys-syncfs.c fsys-getroot.c fsys-get-options.c fsys-set-options.c \
-       fsys-goaway.c fsysstubs.c file-get-children.c file-get-source.c
+       fsys-goaway.c fsysstubs.c fsys-get-children.c fsys-get-source.c
 
 IFSOCKSRCS=
 OTHERSRCS= drop-node.c init-init.c make-node.c make-peropen.c make-protid.c   \
@@ -53,7 +52,8 @@ OTHERSRCS= drop-node.c init-init.c make-node.c make-peropen.c 
make-protid.c   \
        init-startup.c startup-argp.c set-options.c append-args.c             \
        runtime-argp.c std-runtime-argp.c std-startup-argp.c                  \
        append-std-options.c trans-callback.c set-get-trans.c                 \
-       nref.c nrele.c nput.c file-get-storage-info-default.c dead-name.c
+       nref.c nrele.c nput.c file-get-storage-info-default.c dead-name.c     \
+       get-source.c
 
 SRCS= $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS)
 
diff --git a/libnetfs/file-get-children.c b/libnetfs/file-get-children.c
deleted file mode 100644
index 5a0ddf0..0000000
--- a/libnetfs/file-get-children.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* file_get_children
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
-
-   This file is part of the GNU Hurd.
-
-   The GNU Hurd is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   The GNU Hurd is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "priv.h"
-#include "fs_S.h"
-
-#include <argz.h>
-
-/* Return any active translators bound to nodes below CRED.  CHILDREN
-   is an argz vector containing file names relative to the path of
-   CRED.  */
-error_t
-netfs_S_file_get_children (struct protid *cred,
-                          char **children,
-                          mach_msg_type_number_t *children_len)
-{
-  error_t err;
-  if (! cred)
-    return EOPNOTSUPP;
-
-  /* check_access performs the same permission check as is normally
-     done, i.e. it checks that all but the last path components are
-     executable by the requesting user and that the last component is
-     readable. */
-  error_t check_access (const char *path)
-  {
-    error_t err;
-    char *elements = NULL;
-    size_t elements_len = 0;
-
-    err = argz_create_sep (path, '/', &elements, &elements_len);
-    if (err)
-      return err;
-
-    struct node *dp = netfs_root_node;
-
-    /* Lock the root node. netfs_attempt_lookup expects the directory to
-       be locked.  */
-    pthread_mutex_lock (&dp->lock);
-
-    /* Increase the reference count, it will be decremented in the loop
-       ahead.  */
-    netfs_nref (dp);
-
-    for (char *entry = elements;
-        entry;
-        entry = argz_next (elements, elements_len, entry))
-      {
-       struct node *next;
-       err = netfs_attempt_lookup (cred->user, dp, entry, &next);
-       /* netfs_attempt_lookup has unlocked dp and returned next
-          locked, so there is no locking to do here.  */
-
-       /* Decrease reference count.  */
-       netfs_nrele (dp);
-
-       if (err)
-         goto errout;
-
-       dp = next;
-      }
-
-    err = fshelp_access (&dp->nn_stat, S_IRUSR, cred->user);
-
-  errout:
-    /* Unlock and unreference the last node.  */
-    netfs_nput (dp);
-
-    free (elements);
-    return err;
-  }
-
-  char *c = NULL;
-  size_t c_len = 0;
-
-  err = fshelp_get_active_translators (&c, &c_len, check_access,
-                                      cred->po->path);
-  if (err)
-    goto errout;
-
-  err = iohelp_return_malloced_buffer (c, c_len, children, children_len);
-  if (err)
-    goto errout;
-
-  c = NULL; /* c was freed by iohelp_return_malloced_buffer. */
-
- errout:
-  free (c);
-  return err;
-}
diff --git a/libnetfs/fsys-get-children.c b/libnetfs/fsys-get-children.c
new file mode 100644
index 0000000..c4bd0f1
--- /dev/null
+++ b/libnetfs/fsys-get-children.c
@@ -0,0 +1,74 @@
+/* fsys_get_children
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "priv.h"
+#include "fsys_S.h"
+
+#include <argz.h>
+
+/* Return any active child translators.  NAMES is an argz vector
+   containing file names relative to the root of the translator.
+   CONTROLS is an array containing the corresponding control ports.
+   Note that translators are bound to nodes, and nodes can have zero
+   or more links in the file system, therefore there is no guarantee
+   that a translators name refers to an existing link in the file
+   system.  */
+error_t
+netfs_S_fsys_get_children (struct netfs_control *fsys,
+                          mach_port_t reply,
+                          mach_msg_type_name_t reply_type,
+                          char **names,
+                          mach_msg_type_number_t *names_len,
+                          mach_port_t **controls,
+                          mach_msg_type_name_t *controlsPoly,
+                          mach_msg_type_number_t *controlsCnt)
+{
+  error_t err;
+  char *n = NULL;
+  size_t n_len = 0;
+  mach_port_t *c;
+  size_t c_count;
+
+  if (! fsys)
+    return EOPNOTSUPP;
+
+
+  err = fshelp_get_active_translators (&n, &n_len, &c, &c_count);
+  if (err)
+    goto errout;
+
+  err = iohelp_return_malloced_buffer (n, n_len, names, names_len);
+  if (err)
+    goto errout;
+  n = NULL; /* n was freed by iohelp_return_malloced_buffer. */
+
+  err = iohelp_return_malloced_buffer ((char *) c, c_count * sizeof *c,
+                                       (char **) controls, controlsCnt);
+  if (err)
+    goto errout;
+  c = NULL; /* c was freed by iohelp_return_malloced_buffer. */
+
+  *controlsPoly = MACH_MSG_TYPE_MOVE_SEND;
+  *controlsCnt = c_count;
+
+ errout:
+  free (n);
+  free (c);
+  return err;
+}
diff --git a/libnetfs/file-get-source.c b/libnetfs/fsys-get-source.c
similarity index 54%
rename from libnetfs/file-get-source.c
rename to libnetfs/fsys-get-source.c
index acd3230..bd33cb2 100644
--- a/libnetfs/file-get-source.c
+++ b/libnetfs/fsys-get-source.c
@@ -1,8 +1,6 @@
-/* file_get_source
+/* fsys_get_source
 
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+   Copyright (C) 2017 Free Software Foundation, Inc.
 
    This file is part of the GNU Hurd.
 
@@ -20,15 +18,21 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
-#include "fs_S.h"
-
-/* Return information about the source of the receiving
-   filesystem.  */
+#include "fsys_S.h"
+
+/* Return information about the source of the translator.  If the
+   concept of a source is applicable, SOURCE should refer to the
+   source of the translator and should be a description considered
+   appropriate in the context of the translator.  For example, if the
+   translator is a filesystem residing on a block device, then SOURCE
+   should be the file name of the underlying block device.  */
 error_t
-netfs_S_file_get_source (struct protid *cred,
+netfs_S_fsys_get_source (struct netfs_control *fsys,
+                         mach_port_t reply,
+                         mach_msg_type_name_t reply_type,
                         char *source)
 {
-  if (! cred)
+  if (! fsys)
     return EOPNOTSUPP;
 
   return netfs_get_source (source, 1024 /* XXX */);
diff --git a/libtrivfs/Makefile b/libtrivfs/Makefile
index 4f9c71f..4fd3150 100644
--- a/libtrivfs/Makefile
+++ b/libtrivfs/Makefile
@@ -25,7 +25,7 @@ FSSRCS= dir-link.c dir-mkdir.c dir-mkfile.c dir-lookup.c 
dir-readdir.c \
        file-getlinknode.c file-lock.c file-set-trans.c file-statfs.c \
        file-sync.c file-syncfs.c file-set-size.c file-utimes.c file-exec.c \
        file-access.c dir-chg.c file-chg.c file-get-storage-info.c \
-       file-get-fs-options.c file-reparent.c get-source.c
+       file-get-fs-options.c file-reparent.c \
 
 IOSRCS=io-async-icky.c io-async.c io-duplicate.c io-map.c io-modes-get.c \
        io-modes-off.c io-modes-on.c io-modes-set.c io-owner-get.c \
@@ -35,11 +35,12 @@ IOSRCS=io-async-icky.c io-async.c io-duplicate.c io-map.c 
io-modes-get.c \
 
 FSYSSRCS=fsys-getroot.c fsys-goaway.c fsys-stubs.c fsys-syncfs.c \
        fsys-forward.c fsys-set-options.c fsys-get-options.c \
-       file-get-children.c file-get-source.c
+       fsys-get-children.c fsys-get-source.c \
 
 OTHERSRCS=demuxer.c protid-clean.c protid-dup.c cntl-create.c \
        cntl-clean.c times.c startup.c open.c \
        runtime-argp.c set-options.c append-args.c dyn-classes.c \
+       get-source.c
 
 SRCS=$(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(OTHERSRCS)
 
diff --git a/libtrivfs/file-get-children.c b/libtrivfs/file-get-children.c
deleted file mode 100644
index 4126119..0000000
--- a/libtrivfs/file-get-children.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* file_get_children
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
-
-   This file is part of the GNU Hurd.
-
-   The GNU Hurd is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   The GNU Hurd is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "priv.h"
-#include "trivfs_fs_S.h"
-
-/* Return any active translators bound to nodes of the receiving
-   filesystem.  CHILDREN is an argz vector containing file names
-   relative to the root of the receiving translator.  */
-error_t
-trivfs_S_file_get_children (struct trivfs_protid *cred,
-                           mach_port_t reply,
-                           mach_msg_type_name_t replyPoly,
-                           char **children,
-                           mach_msg_type_number_t *children_len)
-{
-  return EOPNOTSUPP;
-}
diff --git a/libtrivfs/fsys-get-children.c b/libtrivfs/fsys-get-children.c
new file mode 100644
index 0000000..f0cd28c
--- /dev/null
+++ b/libtrivfs/fsys-get-children.c
@@ -0,0 +1,41 @@
+/* fsys_get_children
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "priv.h"
+#include "trivfs_fsys_S.h"
+
+/* Return any active child translators.  NAMES is an argz vector
+   containing file names relative to the root of the translator.
+   CONTROLS is an array containing the corresponding control ports.
+   Note that translators are bound to nodes, and nodes can have zero
+   or more links in the file system, therefore there is no guarantee
+   that a translators name refers to an existing link in the file
+   system.  */
+error_t
+trivfs_S_fsys_get_children (struct trivfs_control *fsys,
+                           mach_port_t reply,
+                           mach_msg_type_name_t replyPoly,
+                           char **names,
+                           mach_msg_type_number_t *names_len,
+                            mach_port_t **controls,
+                            mach_msg_type_name_t *controlsPoly,
+                           mach_msg_type_number_t *controlsCnt)
+{
+  return EOPNOTSUPP;
+}
diff --git a/libtrivfs/file-get-source.c b/libtrivfs/fsys-get-source.c
similarity index 56%
rename from libtrivfs/file-get-source.c
rename to libtrivfs/fsys-get-source.c
index c2420fb..5d063eb 100644
--- a/libtrivfs/file-get-source.c
+++ b/libtrivfs/fsys-get-source.c
@@ -1,8 +1,6 @@
-/* file_get_source
+/* fsys_get_source
 
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+   Copyright (C) 2017 Free Software Foundation, Inc.
 
    This file is part of the GNU Hurd.
 
@@ -20,15 +18,19 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
-#include "trivfs_fs_S.h"
-
-/* Return information about the source of the receiving
-   filesystem. */
+#include "trivfs_fsys_S.h"
+
+/* Return information about the source of the translator.  If the
+   concept of a source is applicable, SOURCE should refer to the
+   source of the translator and should be a description considered
+   appropriate in the context of the translator.  For example, if the
+   translator is a filesystem residing on a block device, then SOURCE
+   should be the file name of the underlying block device.  */
 error_t
-trivfs_S_file_get_source (struct trivfs_protid *cred,
+trivfs_S_fsys_get_source (struct trivfs_control *fsys,
                          mach_port_t reply,
                          mach_msg_type_name_t replyPoly,
                          char *source)
 {
-  return cred ? trivfs_get_source (source, 1024 /* XXX */) : EOPNOTSUPP;
+  return fsys ? trivfs_get_source (source, 1024 /* XXX */) : EOPNOTSUPP;
 }
diff --git a/trans/Makefile b/trans/Makefile
index 02718df..8048d6f 100644
--- a/trans/Makefile
+++ b/trans/Makefile
@@ -73,7 +73,7 @@ vpath elfcore.c $(top_srcdir)/exec
 
 crash: crashServer.o crash_replyUser.o msgServer.o elfcore.o
 ifsock: ifsockServer.o
-mtab: fsUser.o
+mtab: fsysUser.o
 password: passwordServer.o
 proxy-defpager: default_pagerServer.o default_pagerUser.o
 streamio: device_replyServer.o
diff --git a/trans/mtab.c b/trans/mtab.c
index a69ede6..794c07f 100644
--- a/trans/mtab.c
+++ b/trans/mtab.c
@@ -26,6 +26,12 @@
 #include <hurd.h>
 #include <hurd/ihash.h>
 #include <hurd/trivfs.h>
+#if XXX_libc_has_included_our_new_rpc
+#include <hurd/fsys.h>
+... also remember to remove the client code from the Makefile...
+#else
+#include "fsys_U.h"
+#endif
 #include <inttypes.h>
 #include <mntent.h>
 #include <nullauth.h>
@@ -39,11 +45,13 @@
 #include <version.h>
 
 #include "libtrivfs/trivfs_io_S.h"
-#include "fs_U.h"
+
+/* The targets control port.  */
+static mach_port_t target_control;
 
 static char *target_path = NULL;
-static int insecure = 0;
-static int all_translators = 0;
+#define MAX_DEPTH      10
+static int max_depth = MAX_DEPTH;
 
 /* Our control port.  */
 struct trivfs_control *control;
@@ -63,25 +71,21 @@ const char *argp_program_version = STANDARD_HURD_VERSION 
(mtab);
 
 static const struct argp_option options[] =
 {
-  {"insecure", 'I', 0, 0,
-   "Follow translators not bound to nodes owned by you or root"},
-  {"all-translators", 'A', 0, 0,
-   "List all translators, even those that are probably not "
-   "filesystem translators"},
+  {"depth", 'd', "DEPTH", 0,
+   "Maximum depth to traverse"},
   {}
 };
 
 /* Parse a command line option.         */
 error_t parse_opt (int key, char *arg, struct argp_state *state)
 {
+  char *end;
   switch (key)
     {
-    case 'I':
-      insecure = 1;
-      break;
-
-    case 'A':
-      all_translators = 1;
+    case 'd':
+      max_depth = strtoull (arg, &end, 10);
+      if (arg == end || end[0] != 0)
+        argp_error (state, "Could not parse depth '%s'.", arg);
       break;
 
     case ARGP_KEY_ARG:
@@ -117,9 +121,14 @@ trivfs_append_args (struct trivfs_control *fsys,
 {
   error_t err;
 
-  if (insecure)
+  if (max_depth != MAX_DEPTH)
     {
-      err = argz_add (argz, argz_len, target_path);
+      char *arg;
+      if (asprintf (&arg, "--depth=%d", max_depth) < 0)
+        return errno;
+
+      err = argz_add (argz, argz_len, arg);
+      free (arg);
       if (err)
        return err;
     }
@@ -201,7 +210,8 @@ is_owner (io_statbuf_t *st)
 }
 
 error_t
-mtab_populate (struct mtab *mtab, const char *path, int insecure);
+mtab_populate (struct mtab *mtab, const char *path, mach_port_t control,
+               int depth);
 
 error_t
 argz_add_device (char **options, size_t *options_len, const char *device);
@@ -213,6 +223,7 @@ int
 main (int argc, char *argv[])
 {
   error_t err;
+  mach_port_t node;
 
   err = argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
   if (err)
@@ -222,14 +233,27 @@ main (int argc, char *argv[])
   if (err)
     error (2, err, "getting credentials");
 
+  /* Do the lookup without O_NOTRANS to get the root node.  */
+  node = file_name_lookup (target_path, 0, 0);
+  if (! MACH_PORT_VALID (node))
+    error (2, errno, "%s", target_path);
+
+  /* Get the control port.  */
+  err = file_getcontrol (node, &target_control);
+  if (err)
+    error (2, err, "file_getcontrol");
+
+  /* Now that we have the control port, we can drop our
+     privileges.  */
+  err = setnullauth ();
+  if (err)
+    error (3, err, "dropping credentials");
+
   mach_port_t bootstrap;
   task_get_bootstrap_port (mach_task_self (), &bootstrap);
   if (bootstrap != MACH_PORT_NULL)
     {
       /* Started as a translator.  */
-      err = setnullauth ();
-      if (err)
-        error (3, err, "dropping credentials");
 
       /* Reply to our parent.  */
       err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &control);
@@ -254,7 +278,7 @@ main (int argc, char *argv[])
           .lock = PTHREAD_MUTEX_INITIALIZER,
           .ports_seen = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP),
         };
-      err = mtab_populate (&mtab, target_path, insecure);
+      err = mtab_populate (&mtab, target_path, target_control, max_depth);
       if (err)
        error (5, err, "%s", target_path);
 
@@ -284,56 +308,23 @@ mtab_add_entry (struct mtab *mtab, const char *entry, 
size_t length)
   return 0;
 }
 
-/* Check whether the given NODE is a directory on a filesystem
-   translator.  */
-static boolean_t
-is_filesystem_translator (file_t node)
-{
-  error_t err;
-  char *data = NULL;
-  size_t datacnt = 0;
-  int amount;
-  err = dir_readdir (node, &data, &datacnt, 0, 1, 0, &amount);
-  if (data != NULL && datacnt > 0)
-    vm_deallocate (mach_task_self (), (vm_address_t) data, datacnt);
-
-  /* Filesystem translators return either no error, or, if NODE has
-     not been looked up with O_READ, EBADF to dir_readdir
-     requests.  */
-  switch (err)
-    {
-    case 0:
-    case EBADF:
-      return TRUE;
-    default:
-      return FALSE;
-    }
-}
-
-/* Records NODE's idport in ports_seen, returns true if we have
-   already seen this node or there was an error getting the id
-   port.  */
+/* Records CONTROL in ports_seen, returns true if we have already seen
+   this port.  */
 boolean_t
-mtab_mark_as_seen (struct mtab *mtab, mach_port_t node)
+mtab_mark_as_seen (struct mtab *mtab, mach_port_t control)
 {
   error_t err;
-  mach_port_t idport, fsidport;
-  ino_t fileno;
+  if (hurd_ihash_find (&mtab->ports_seen, (hurd_ihash_key_t) control))
+    return TRUE;
 
-  err = io_identity (node, &idport, &fsidport, &fileno);
+  err = mach_port_mod_refs (mach_task_self (), control,
+                            MACH_PORT_RIGHT_SEND, +1);
   if (err)
+    /* Ewww.  */
     return TRUE;
 
-  mach_port_deallocate (mach_task_self (), fsidport);
-
-  if (hurd_ihash_find (&mtab->ports_seen, idport))
-    {
-      /* Already seen.  Get rid of the extra reference.  */
-      mach_port_deallocate (mach_task_self (), idport);
-      return TRUE;
-    }
-
-  hurd_ihash_add (&mtab->ports_seen, idport, (hurd_ihash_value_t) idport);
+  hurd_ihash_add (&mtab->ports_seen,
+                  (hurd_ihash_key_t) control, (hurd_ihash_value_t) control);
   return FALSE;
 }
 
@@ -342,12 +333,13 @@ mtab_mark_as_seen (struct mtab *mtab, mach_port_t node)
    by root or the current user.  */
 /* XXX split up */
 error_t
-mtab_populate (struct mtab *mtab, const char *path, int insecure)
+mtab_populate (struct mtab *mtab, const char *path, mach_port_t control,
+               int depth)
 {
   error_t err = 0;
 
   /* These resources are freed in the epilogue.         */
-  file_t node = MACH_PORT_NULL, underlying_node = MACH_PORT_NULL;
+  file_t node = MACH_PORT_NULL;
   char *argz = NULL;
   size_t argz_len = 0;
   char **argv = NULL;
@@ -359,53 +351,22 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
   size_t entry_len = 0;
   char *children = NULL;
   size_t children_len = 0;
+  mach_port_t *controls = NULL;
+  size_t controls_count = 0;
+  size_t i;
 
-  /* Get the underlying node.  */
-  underlying_node = file_name_lookup (path, O_NOTRANS, 0666);
-  if (underlying_node == MACH_PORT_NULL)
-    {
-      err = errno;
-      goto errout;
-    }
-
-  if (! insecure)
-    {
-      /* Check who owns the node the translator is bound to.  */
-      io_statbuf_t st;
-      err = io_stat (underlying_node, &st);
-      if (err)
-       goto errout;
-
-      if (st.st_uid != 0 && st.st_gid != 0 && ! is_owner (&st))
-       {
-         err = EPERM;
-         goto errout;
-       }
-    }
-
-  /* (Re-)do the lookup without O_NOTRANS to get the root node.  */
-  node = file_name_lookup (path, 0, 0666);
-  if (node == MACH_PORT_NULL)
-    {
-      err = errno;
-      goto errout;
-    }
-
-  if (! (all_translators || is_filesystem_translator (node)))
-    {
-      err = 0;
-      goto errout;
-    }
+  if (depth < 0)
+    return 0;
 
   /* Avoid running in circles.  */
-  if (mtab_mark_as_seen (mtab, underlying_node))
+  if (mtab_mark_as_seen (mtab, control))
     {
       err = 0;
       goto errout;
     }
 
   /* Query its options.         */
-  err = file_get_fs_options (node, &argz, &argz_len);
+  err = fsys_get_options (control, &argz, &argz_len);
   if (err)
     {
       if (err == EOPNOTSUPP)
@@ -452,7 +413,7 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
   argz_stringify (options, options_len, ',');
 
   string_t source;
-  err = file_get_source (node, source);
+  err = fsys_get_source (control, source);
   if (err)
     goto errout;
 
@@ -473,8 +434,9 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
   if (err)
     goto errout;
 
-  /* path has an active translator, query its children.         */
-  err = file_get_children (node, &children, &children_len);
+  /* Recurse.  */
+  err = fsys_get_children (control, &children, &children_len,
+                           &controls, &controls_count);
   if (err == EOPNOTSUPP)
     {
       err = 0;
@@ -484,10 +446,16 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
   if (err)
     goto errout;
 
-  if (children_len)
-    for (char *c = children; c; c = argz_next (children, children_len, c))
+  char *c;
+  if (children_len && controls_count)
+    for (c = children, i = 0; c && i < controls_count;
+         c = argz_next (children, children_len, c), i++)
       {
        char *p = NULL;
+
+        if (! MACH_PORT_VALID (controls[i]))
+          continue;
+
        asprintf (&p, "%s%s%s",
                  path,
                  path[strlen (path) - 1] == '/'? "": "/",
@@ -498,7 +466,7 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
            goto errout;
          }
 
-       err = mtab_populate (mtab, p, insecure);
+       err = mtab_populate (mtab, p, controls[i], depth - 1);
        if (err)
          {
            /* There is really not much we can do about errors here.  */
@@ -507,11 +475,12 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
          }
 
        free (p);
+        err = mach_port_deallocate (mach_task_self (), controls[i]);
+        assert_perror_backtrace (err);
+        controls[i] = MACH_PORT_NULL;
       }
 
  errout:
-  if (underlying_node != MACH_PORT_NULL)
-    mach_port_deallocate (mach_task_self (), underlying_node);
   if (node != MACH_PORT_NULL)
     mach_port_deallocate (mach_task_self (), node);
 
@@ -529,6 +498,9 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
 
   if (children)
     vm_deallocate (mach_task_self (), (vm_address_t) children, children_len);
+  if (controls)
+    vm_deallocate (mach_task_self (), (vm_address_t) controls,
+                   controls_count * sizeof *controls);
 
   return err;
 }
@@ -647,29 +619,6 @@ open_hook (struct trivfs_peropen *peropen)
   mtab->contents_len = 0;
   hurd_ihash_init (&mtab->ports_seen, HURD_IHASH_NO_LOCP);
 
-  /* The mtab object is initialized, but not yet populated.  We delay
-     that until that data is really needed.  This avoids the following
-     problems:
-
-     Suppose you have
-
-     settrans -ac /foo /hurd/mtab /
-
-     If you now access /foo, the mtab translator will walk the tree of
-     all active translators starting from /.  If it visits /foo, it
-     will talk to itself.  Previously the translator migitated this by
-     comparing the control port of the translator with its own.  This
-     does not work if you got two mtab translators like this:
-
-     settrans -ac /foo /hurd/mtab /
-     settrans -ac /bar /hurd/mtab /
-
-     With a single-threaded mtab server this results in a dead-lock,
-     with a multi-threaded server this will create more and more
-     threads.
-
-     Delaying the data generation until it is really needed cleanly
-     avoids these kind of problems.  */
   return 0;
 }
 
@@ -710,7 +659,7 @@ trivfs_S_io_read (struct trivfs_protid *cred,
 
   if (op->contents == NULL)
     {
-      err = mtab_populate (op, target_path, insecure);
+      err = mtab_populate (op, target_path, target_control, max_depth);
       if (err)
        goto out;
     }
@@ -766,7 +715,7 @@ trivfs_S_io_seek (struct trivfs_protid *cred,
 
   if (op->contents == NULL)
     {
-      err = mtab_populate (op, target_path, insecure);
+      err = mtab_populate (op, target_path, target_control, max_depth);
       if (err)
        goto out;
     }
@@ -823,7 +772,7 @@ trivfs_S_io_readable (struct trivfs_protid *cred,
 
   if (op->contents == NULL)
     {
-      error_t err = mtab_populate (op, target_path, insecure);
+      error_t err = mtab_populate (op, target_path, target_control, max_depth);
       if (err)
        goto out;
     }

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]