summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hurd/fs.defs20
-rw-r--r--hurd/fsys.defs25
-rw-r--r--libdiskfs/Makefile2
-rw-r--r--libdiskfs/file-get-children.c96
-rw-r--r--libdiskfs/fsys-get-children.c74
-rw-r--r--libdiskfs/fsys-get-source.c (renamed from libdiskfs/file-get-source.c)26
-rw-r--r--libfshelp/fshelp.h10
-rw-r--r--libfshelp/translator-list.c43
-rw-r--r--libnetfs/Makefile8
-rw-r--r--libnetfs/file-get-children.c108
-rw-r--r--libnetfs/fsys-get-children.c74
-rw-r--r--libnetfs/fsys-get-source.c (renamed from libnetfs/file-get-source.c)24
-rw-r--r--libtrivfs/Makefile5
-rw-r--r--libtrivfs/file-get-children.c36
-rw-r--r--libtrivfs/fsys-get-children.c41
-rw-r--r--libtrivfs/fsys-get-source.c (renamed from libtrivfs/file-get-source.c)22
-rw-r--r--trans/Makefile2
-rw-r--r--trans/mtab.c225
18 files changed, 367 insertions, 474 deletions
diff --git a/hurd/fs.defs b/hurd/fs.defs
index a4a48cc8..6c0b5731 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 b36b9447..35d483cf 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 93c96fa6..5716ac5b 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 98d5d60e..00000000
--- 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 <4winter@informatik.uni-hamburg.de>
-
- 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 00000000..7e2a37b1
--- /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
index d983a826..59eee55e 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 <4winter@informatik.uni-hamburg.de>
+ 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 7663ba1d..e8ce9733 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 7077b217..92b31dd0 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 c3830c03..de06816e 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 5a0ddf0e..00000000
--- 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 <4winter@informatik.uni-hamburg.de>
-
- 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 00000000..c4bd0f15
--- /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
index acd32306..bd33cb21 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 <4winter@informatik.uni-hamburg.de>
+ 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 4f9c71f7..4fd3150c 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 4126119e..00000000
--- 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 <4winter@informatik.uni-hamburg.de>
-
- 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 00000000..f0cd28c2
--- /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
index c2420fb8..5d063eb8 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 <4winter@informatik.uni-hamburg.de>
+ 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 02718dfe..8048d6f3 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 a69ede6e..794c07f4 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;
}