bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 3/4] Conditionally forward some fsys_* RPCs to the mountee.


From: Sergiu Ivanov
Subject: [PATCH 3/4] Conditionally forward some fsys_* RPCs to the mountee.
Date: Fri, 17 Jul 2009 13:58:01 +0300
User-agent: Mutt/1.5.18 (2008-05-17)

>From 92d45847b0c625b5bbb4b44e8f82494fc5551d02 Mon Sep 17 00:00:00 2001
From: Sergiu Ivanov <unlimitedscolobb@gmail.com>
Date: Thu, 16 Jul 2009 11:23:37 +0000
Subject: [PATCH 3/4] Conditionally forward some fsys_* RPCs to the mountee.

* mount.c (shutting_down): New variable.
(mountee_server): Attempt to shutdown unionfs only it it is not
already shutting down.  Set shutting_down to 1 before shutting
down unionfs.
* mount.h (shutting_down): New variable.
* netfs.c (netfs_append_args): Forward fsys_get_options to the
mountee if unionmount is transparent.
(netfs_set_options): New function.
(netfs_attempt_syncfs): Forward fsys_syncfs to the mountee if
unionmount is transparent.
(netfs_shutdown): New function.
* node.c (node_ulfs_free): Don't destroy the port to the mountee.
---
 mount.c |    9 +++++-
 mount.h |    3 ++
 netfs.c |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 node.c  |    2 +-
 4 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/mount.c b/mount.c
index 26cbd9f..4d0a0d4 100644
--- a/mount.c
+++ b/mount.c
@@ -46,6 +46,9 @@ int mountee_started = 0;
    operates (transparent/non-transparent).  */
 int transparent_mount = 1;
 
+/* Shows whether unionmount is shutting down.  */
+int shutting_down = 0;
+
 /* The port for receiving the notification about the shutdown of the
    mountee.  */
 mach_port_t mountee_listen_port;
@@ -192,8 +195,12 @@ start_mountee (node_t * np, char * argz, size_t argz_len, 
int flags,
 error_t
 mountee_server (mach_msg_header_t * inp, mach_msg_header_t * outp)
 {
-  if (inp->msgh_id == MACH_NOTIFY_DEAD_NAME)
+  /* If `shutting_down` is set, the mountee has just been shut down by
+     netfs_shutdown and unionfs is on its way to going away.  */
+  if (!shutting_down && (inp->msgh_id == MACH_NOTIFY_DEAD_NAME))
     {
+      shutting_down = 1;
+
       /* Terminate operations conducted by unionfs and shut down.  */
       netfs_shutdown (FSYS_GOAWAY_FORCE);
       exit (0);
diff --git a/mount.h b/mount.h
index fd8408b..ebbfa93 100644
--- a/mount.h
+++ b/mount.h
@@ -45,6 +45,9 @@ extern int mountee_started;
    operates (transparent/non-transparent).  */
 extern int transparent_mount;
 
+/* Shows whether unionmount is shutting down.  */
+extern int shutting_down;
+
 /* Starts the mountee (given by `argz` and `argz_len`), sets it on
    node `np` and opens a port `port` to with `flags`.  `port` is not
    modified when an error occurs.  */
diff --git a/netfs.c b/netfs.c
index fc2572f..7e81771 100644
--- a/netfs.c
+++ b/netfs.c
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <hurd/paths.h>
 #include <sys/mman.h>
+#include <hurd/fsys.h>
 
 #include "unionfs.h"
 #include "ulfs.h"
@@ -50,6 +51,36 @@ netfs_append_args (char **argz, size_t *argz_len)
 {
   error_t err = 0;
 
+  if (transparent_mount)
+    {
+      /* We need to receive the mountee's arguments into a local
+        buffer first, because in the case of an error
+        netfs_S_fsys_get_options will try to free `*argz`, which
+        might have already been freed in the mountee.
+
+        The ``static'' bit is required because fsys_get_options
+        returns an mmapped region.  */
+      static char * m_argz = NULL;
+      static size_t m_argz_len;
+
+      /* Forward this RPC directly to the mountee.  */
+      err = fsys_get_options (mountee_control, &m_argz, &m_argz_len);
+      if (err)
+       return err;
+
+      /* netfs_S_fsys_get_options has already malloced `*argz` for us,
+        we will copy `m_argz` into it, because netfs_append_args is
+        expected to return a malloced buffer, while fsys_get_options
+        returns an mmapped buffer.  */
+      *argz = realloc (*argz, m_argz_len);
+      if(!*argz)
+       return ENOMEM;
+      memcpy (*argz, m_argz, m_argz_len);
+      *argz_len = m_argz_len;
+
+      return 0;
+    }
+
   /* Add the --mount or --no-mount option to the result.  */
   if (mountee_argz)
     {
@@ -108,6 +139,24 @@ netfs_append_args (char **argz, size_t *argz_len)
   return err;
 }
 
+error_t
+netfs_set_options (char *argz, size_t argz_len)
+{
+  if (transparent_mount)
+    {
+      error_t err;
+
+      /* Forward this RPC directly to the mountee.  */
+      err = fsys_set_options (mountee_control, argz, argz_len, 0);
+      return err;
+    }
+
+  if (netfs_runtime_argp)
+    return fshelp_set_options (netfs_runtime_argp, 0, argz, argz_len, 0);
+  else
+    return EOPNOTSUPP;
+}
+
 #ifndef __USE_FILE_OFFSET64
 #define OFFSET_T __off_t               /* Size in bytes.  */
 #else
@@ -318,6 +367,61 @@ netfs_attempt_sync (struct iouser *cred, struct node *np,
 error_t
 netfs_attempt_syncfs (struct iouser *cred, int wait)
 {
+  error_t err = 0;
+
+  if (transparent_mount)
+    {
+      /* Sync the mountee (and its children, too).  */
+      err = fsys_syncfs (mountee_control, wait, 1);
+    }
+
+  return err;
+}
+
+/* Shutdown the filesystem; flags are as for fsys_goaway.  */
+error_t
+netfs_shutdown (int flags)
+{
+  int nports;
+  int err;
+
+  if ((flags & FSYS_GOAWAY_UNLINK)
+      && S_ISDIR (netfs_root_node->nn_stat.st_mode))
+    return EBUSY;
+
+  /* Permit all current RPC's to finish, and then suspend any new ones.  */
+  err = ports_inhibit_class_rpcs (netfs_protid_class);
+  if (err)
+    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);
+
+      return EBUSY;
+    }
+
+  if (!(flags & FSYS_GOAWAY_NOSYNC))
+    {
+      err = netfs_attempt_syncfs (0, flags);
+      if (err)
+        return err;
+    }
+
+  /* If `shutting_down` is set, unionfs is going away because the
+     mounee has just died, so we don't need to attempt to shut it
+     down.  */
+  if (!shutting_down)
+    {
+      shutting_down = 1;
+      err = fsys_goaway (mountee_control, flags);
+      if (err)
+       return err;
+    }
+
   return 0;
 }
 
diff --git a/node.c b/node.c
index d9f26ba..9d86872 100644
--- a/node.c
+++ b/node.c
@@ -336,7 +336,7 @@ node_ulfs_free (node_t *node)
   node_ulfs_iterate_unlocked (node)
     {
       if (port_valid (node_ulfs->port)
-         && node_ulfs->port != underlying_node)
+         && (node_ulfs->port != underlying_node) && (node_ulfs->port != 
mountee_port))
        port_dealloc (node_ulfs->port);
     }
 
-- 
1.6.3.3





reply via email to

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