summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node.c10
-rw-r--r--node.h8
-rw-r--r--nsmux.c91
-rw-r--r--nsmux.h4
-rw-r--r--trans.c4
-rw-r--r--trans.h8
6 files changed, 112 insertions, 13 deletions
diff --git a/node.c b/node.c
index 778a73be5..a7c85fd4c 100644
--- a/node.c
+++ b/node.c
@@ -98,7 +98,7 @@ error_t node_create (lnode_t * lnode, node_t ** node)
/*initialize the data fields dealing with positioning this node
in the dynamic translator stack */
- node_new->nn->trans_cntl = MACH_PORT_NULL;
+ node_new->nn->dyntrans = NULL;
node_new->nn->below = NULL;
/*store the result of creation in the second parameter */
@@ -155,7 +155,7 @@ error_t node_create_proxy (lnode_t * lnode, node_t ** node)
/*initialize the data fields dealing with positioning this node
in the dynamic translator stack */
- node_new->nn->trans_cntl = MACH_PORT_NULL;
+ node_new->nn->dyntrans = NULL;
node_new->nn->below = NULL;
/*store the result of creation in the second parameter */
@@ -214,7 +214,7 @@ error_t node_create_from_port (mach_port_t port, node_t ** node)
/*initialize the data fields dealing with positioning this node
in the dynamic translator stack */
- node_new->nn->trans_cntl = MACH_PORT_NULL;
+ node_new->nn->dyntrans = NULL;
node_new->nn->below = NULL;
/*store the result of creation in the second parameter */
@@ -913,8 +913,8 @@ error_t
if (err)
return err;
- /*Store the current control port in the new supplied shadow node */
- np->nn->trans_cntl = active_control;
+ /*Register the new translator*/
+ err = trans_register (active_control, &np->nn->dyntrans);
/*Obtain the port to the top of the newly-set translator */
err = fsys_getroot
diff --git a/node.h b/node.h
index 72adcbebb..d930a3b69 100644
--- a/node.h
+++ b/node.h
@@ -32,6 +32,7 @@
#include <hurd/netfs.h>
/*---------------------------------------------------------------------------*/
#include "lnode.h"
+#include "trans.h"
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
@@ -74,9 +75,10 @@ struct netnode
/*a port to the underlying filesystem */
file_t port;
- /*the control port of the translator sitting on this node, in case
- this node is a shadow node */
- fsys_t trans_cntl;
+ /*a reference to the element in the list of dynamic translators
+ corresponding to the translator sitting on this node, in case this
+ node is a shadow node */
+ struct trans_el * dyntrans;
/*the reference to the shadow node that is below the current shadow
node in the dynamic translator stack */
diff --git a/nsmux.c b/nsmux.c
index 9e5d28a4e..2eb539e07 100644
--- a/nsmux.c
+++ b/nsmux.c
@@ -34,6 +34,7 @@
#include <hurd/netfs.h>
#include <fcntl.h>
#include <hurd/paths.h>
+#include <hurd/fsys.h>
/*---------------------------------------------------------------------------*/
#include "debug.h"
#include "options.h"
@@ -1640,6 +1641,96 @@ kern_return_t
} /*netfs_S_file_get_translator_cntl */
/*---------------------------------------------------------------------------*/
+/* Shutdown the filesystem; flags are as for fsys_goaway. */
+error_t
+netfs_shutdown (int flags)
+{
+ error_t
+ helper (struct node *node)
+ {
+ error_t err;
+ mach_port_t control;
+
+ err = fshelp_fetch_control (&node->transbox, &control);
+ if (!err && (control != MACH_PORT_NULL))
+ {
+ mutex_unlock (&node->lock);
+ err = fsys_goaway (control, flags);
+ mach_port_deallocate (mach_task_self (), control);
+ mutex_lock (&node->lock);
+ }
+ else
+ err = 0;
+
+ if ((err == MIG_SERVER_DIED) || (err == MACH_SEND_INVALID_DEST))
+ err = 0;
+
+ return err;
+ }
+
+ int nports;
+ int err;
+
+ if ((flags & FSYS_GOAWAY_UNLINK)
+ && S_ISDIR (netfs_root_node->nn_stat.st_mode))
+ return EBUSY;
+
+ if (flags & FSYS_GOAWAY_NOWAIT)
+ LOG_MSG("NOWAIT");
+ LOG_MSG("WAIT");
+
+ if (flags & FSYS_GOAWAY_RECURSE)
+ {
+ /*nsmux has been requested shut down recursively. Shut down all
+ dynamic translators. Statically set translators will not be
+ shut down, because libnetfs does not (yet?) do this itself, as
+ different from libdiskfs. */
+ err = trans_shutdown_all (flags);
+
+#ifdef NOTYET
+ err = netfs_node_iterate (helper);
+#endif
+ if (err)
+ return err;
+ }
+
+#ifdef NOTYET
+ rwlock_writer_lock (&netfs_fsys_lock);
+#endif
+
+ /* Permit all current RPC's to finish, and then suspend any new ones. */
+ err = ports_inhibit_class_rpcs (netfs_protid_class);
+ if (err)
+ {
+#ifdef NOTYET
+ rwlock_writer_unlock (&netfs_fsys_lock);
+#endif
+ return err;
+ }
+
+ nports = ports_count_class (netfs_protid_class);
+ if (((flags & FSYS_GOAWAY_FORCE) == 0) && nports)
+ /* There are outstanding user ports; resume operations. */
+ {
+ ports_enable_class (netfs_protid_class);
+ ports_resume_class_rpcs (netfs_protid_class);
+#ifdef NOTYET
+ rwlock_writer_unlock (&netfs_fsys_lock);
+#endif
+ return EBUSY;
+ }
+
+ if (!(flags & FSYS_GOAWAY_NOSYNC))
+ {
+ err = netfs_attempt_syncfs (0, flags);
+ if (err)
+ return err;
+ }
+
+ return 0;
+} /*netfs_shutdown */
+
+/*---------------------------------------------------------------------------*/
/*Entry point*/
int main (int argc, char **argv)
{
diff --git a/nsmux.h b/nsmux.h
index 8c6082fd1..38cf8c810 100644
--- a/nsmux.h
+++ b/nsmux.h
@@ -238,4 +238,8 @@ kern_return_t
netfs_S_file_get_translator_cntl
(struct protid *user, mach_port_t * cntl, mach_msg_type_name_t * cntltype);
/*---------------------------------------------------------------------------*/
+/* Shutdown the filesystem; flags are as for fsys_goaway. */
+error_t
+netfs_shutdown (int flags);
+/*---------------------------------------------------------------------------*/
#endif /*__NSMUX_H__*/
diff --git a/trans.c b/trans.c
index 8d05286ce..4b77f473d 100644
--- a/trans.c
+++ b/trans.c
@@ -42,7 +42,7 @@ trans_el_t * dyntrans = NULL;
/*Adds a translator control port to the list of ports. One should use
only this function to add a new element to the list of ports. */
error_t
-trans_register (mach_port_t cntl)
+trans_register (fsys_t cntl, trans_el_t ** new_trans)
{
/*The new entry in the list */
trans_el_t * el;
@@ -57,6 +57,8 @@ trans_register (mach_port_t cntl)
el->next = dyntrans;
dyntrans = el;
+ *new_trans = el;
+
return 0;
} /*trans_register */
diff --git a/trans.h b/trans.h
index 86e21c9d6..e28060f5e 100644
--- a/trans.h
+++ b/trans.h
@@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.*/
/*---------------------------------------------------------------------------*/
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
+#ifndef __TRANS_H__
+#define __TRANS_H__
/*---------------------------------------------------------------------------*/
#include <hurd.h>
@@ -35,7 +35,7 @@
struct trans_el
{
/*the control port to the translator */
- mach_port_t cntl;
+ fsys_t cntl;
/*the next and the previous elements in the list */
struct trans_el * next, * prev;
@@ -55,7 +55,7 @@ extern trans_el_t * dyntrans;
/*Adds a translator control port to the list of ports. One should use
only this function to add a new element to the list of ports. */
error_t
-trans_register (mach_port_t cntl);
+trans_register (fsys_t cntl, trans_el_t ** new_trans);
/*---------------------------------------------------------------------------*/
/*Removes a translator control port from the list of ports. One should
use only this function to remove an element from the list of