summaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/series1
-rw-r--r--debian/patches/translatorslist-detect-passive-translators.patch277
2 files changed, 278 insertions, 0 deletions
diff --git a/debian/patches/series b/debian/patches/series
index a7ce7502..e2e0aa49 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -43,3 +43,4 @@ exec_filename_fix.patch
mount-loop.patch
proc_set_init_task.patch
newRPC.patch
+translatorslist-detect-passive-translators.patch
diff --git a/debian/patches/translatorslist-detect-passive-translators.patch b/debian/patches/translatorslist-detect-passive-translators.patch
new file mode 100644
index 00000000..59aa0691
--- /dev/null
+++ b/debian/patches/translatorslist-detect-passive-translators.patch
@@ -0,0 +1,277 @@
+diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
+index 86116e3..57610a5 100644
+--- a/libdiskfs/dir-lookup.c
++++ b/libdiskfs/dir-lookup.c
+@@ -274,11 +274,16 @@ diskfs_S_dir_lookup (struct protid *dircred,
+ goto out;
+
+ dirport = ports_get_send_right (newpi);
+- ports_port_deref (newpi);
+- newpi = 0;
+ if (np != dnp)
+ pthread_mutex_unlock (&dnp->lock);
+
++ /* Check if an active translator is currently running. If
++ not, fshelp_fetch_root will start one. In that case, we
++ need to register it in the list of active
++ translators. */
++ boolean_t register_translator =
++ np->transbox.active == MACH_PORT_NULL;
++
+ error = fshelp_fetch_root (&np->transbox, dircred->po,
+ dirport, dircred->user,
+ lastcomp ? flags : 0,
+@@ -301,9 +306,28 @@ diskfs_S_dir_lookup (struct protid *dircred,
+ *end++ = '/';
+ strcpy (end, nextname);
+ }
++
++ if (register_translator)
++ {
++ char *stripped_relpath = strdupa (relpath);
++ char *end = strchr (stripped_relpath, '\0');
++ end -= 1;
++ if (*end == '/')
++ *end = '\0';
++
++ error = fshelp_set_active_translator (&newpi->pi,
++ stripped_relpath,
++ np->transbox.active);
++ if (error)
++ goto out;
++ }
++
+ goto out;
+ }
+
++ ports_port_deref (newpi);
++ newpi = NULL;
++
+ /* ENOENT means there was a hiccup, and the translator
+ vanished while NP was unlocked inside fshelp_fetch_root.
+ Reacquire the locks, and continue as normal. */
+diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c
+index 8de2e64..8752900 100644
+--- a/libdiskfs/file-set-trans.c
++++ b/libdiskfs/file-set-trans.c
+@@ -208,20 +208,8 @@ diskfs_S_file_set_translator (struct protid *cred,
+
+ pthread_mutex_unlock (&np->lock);
+
+- if (! error && cred->po->path)
+- error = fshelp_set_active_translator (cred->po->path, active);
+-
+- if (! error && active != MACH_PORT_NULL)
+- {
+- mach_port_t old;
+- error = mach_port_request_notification (mach_task_self (), active,
+- MACH_NOTIFY_DEAD_NAME, 0,
+- cred->pi.port_right,
+- MACH_MSG_TYPE_MAKE_SEND_ONCE,
+- &old);
+- if (old != MACH_PORT_NULL)
+- mach_port_deallocate (mach_task_self (), old);
+- }
++ if (! error && cred->po->path && active_flags & FS_TRANS_SET)
++ error = fshelp_set_active_translator (&cred->pi, cred->po->path, active);
+
+ return error;
+ }
+diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h
+index a7702ca..cd86e6f 100644
+--- a/libfshelp/fshelp.h
++++ b/libfshelp/fshelp.h
+@@ -34,14 +34,20 @@
+
+
+ /* Keeping track of active translators */
+-/* These routines keep a list of active translators. They are
+- self-contained and do not require multi threading or the ports
+- library. */
++/* These routines keep a list of active translators. They do not
++ require multi threading but depend on the ports library. */
++
++struct port_info;
+
+ /* Record an active translator being bound to the given file name
+- NAME. ACTIVE is the control port of the translator. */
++ NAME. ACTIVE is the control port of the translator. PI references
++ a receive port that is used to request dead name notifications,
++ typically the port for the underlying node passed to the
++ translator. */
+ error_t
+-fshelp_set_active_translator (const char *name, mach_port_t active);
++fshelp_set_active_translator (struct port_info *pi,
++ const char *name,
++ mach_port_t active);
+
+ /* Remove the active translator specified by its control port ACTIVE.
+ If there is no active translator with the given control port, this
+diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c
+index 87dcb21..b8bbd95 100644
+--- a/libfshelp/translator-list.c
++++ b/libfshelp/translator-list.c
+@@ -22,6 +22,7 @@
+ #include <argz.h>
+ #include <hurd/fsys.h>
+ #include <hurd/ihash.h>
++#include <hurd/ports.h>
+ #include <mach.h>
+ #include <mach/notify.h>
+ #include <pthread.h>
+@@ -33,6 +34,7 @@
+
+ struct translator
+ {
++ struct port_info *pi;
+ char *name;
+ mach_port_t active;
+ };
+@@ -49,8 +51,10 @@ translator_ihash_cleanup (void *element, void *arg)
+ {
+ struct translator *translator = element;
+
+- /* No need to deallocate port, we only keep the name of the
+- port, not a reference. */
++ if (translator->pi)
++ ports_port_deref (translator->pi);
++ /* No need to deallocate translator->active, we only keep the name of
++ the port, not a reference. */
+ free (translator->name);
+ free (translator);
+ }
+@@ -58,7 +62,9 @@ translator_ihash_cleanup (void *element, void *arg)
+ /* Record an active translator being bound to the given file name
+ NAME. ACTIVE is the control port of the translator. */
+ error_t
+-fshelp_set_active_translator (const char *name, mach_port_t active)
++fshelp_set_active_translator (struct port_info *pi,
++ const char *name,
++ mach_port_t active)
+ {
+ error_t err = 0;
+ pthread_mutex_lock (&translator_ihash_lock);
+@@ -79,6 +85,7 @@ fshelp_set_active_translator (const char *name, mach_port_t active)
+ return ENOMEM;
+
+ t->active = MACH_PORT_NULL;
++ t->pi = NULL;
+ t->name = strdup (name);
+ if (! t->name)
+ {
+@@ -93,9 +100,31 @@ fshelp_set_active_translator (const char *name, mach_port_t active)
+
+ update:
+ if (active)
+- /* No need to increment the reference count, we only keep the
+- name, not a reference. */
+- t->active = active;
++ {
++ if (t->pi != pi)
++ {
++ mach_port_t old;
++ err = mach_port_request_notification (mach_task_self (), active,
++ MACH_NOTIFY_DEAD_NAME, 0,
++ pi->port_right,
++ MACH_MSG_TYPE_MAKE_SEND_ONCE,
++ &old);
++ if (err)
++ return err;
++ if (old != MACH_PORT_NULL)
++ mach_port_deallocate (mach_task_self (), old);
++
++ if (t->pi)
++ ports_port_deref (t->pi);
++
++ ports_port_ref (pi);
++ t->pi = pi;
++ }
++
++ /* No need to increment the reference count, we only keep the
++ name, not a reference. */
++ t->active = active;
++ }
+ else
+ hurd_ihash_remove (&translator_ihash, (hurd_ihash_key_t) t);
+
+diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
+index 74351fa..9668a61 100644
+--- a/libnetfs/dir-lookup.c
++++ b/libnetfs/dir-lookup.c
+@@ -256,10 +256,16 @@ netfs_S_dir_lookup (struct protid *diruser,
+ }
+ }
+
++ boolean_t register_translator;
+ if (! error)
+ {
+ dirport = ports_get_send_right (newpi);
+- ports_port_deref (newpi);
++
++ /* Check if an active translator is currently running. If
++ not, fshelp_fetch_root will start one. In that case, we
++ need to register it in the list of active
++ translators. */
++ register_translator = np->transbox.active == MACH_PORT_NULL;
+
+ error = fshelp_fetch_root (&np->transbox, diruser->po,
+ dirport,
+@@ -283,9 +289,31 @@ netfs_S_dir_lookup (struct protid *diruser,
+ strcat (retry_name, "/");
+ strcat (retry_name, nextname);
+ }
++
++ if (register_translator)
++ {
++ char *stripped_relpath = strdupa (relpath);
++ char *end = strchr (stripped_relpath, '\0');
++ end -= 1;
++ if (*end == '/')
++ *end = '\0';
++
++ error = fshelp_set_active_translator (&newpi->pi,
++ stripped_relpath,
++ np->transbox.active);
++ if (error)
++ {
++ ports_port_deref (newpi);
++ goto out;
++ }
++ }
++
++ ports_port_deref (newpi);
+ goto out;
+ }
+
++ ports_port_deref (newpi);
++
+ /* ENOENT means there was a hiccup, and the translator vanished
+ while NP was unlocked inside fshelp_fetch_root; continue as normal. */
+ error = 0;
+diff --git a/libnetfs/file-set-translator.c b/libnetfs/file-set-translator.c
+index a9883a3..8b9a65f 100644
+--- a/libnetfs/file-set-translator.c
++++ b/libnetfs/file-set-translator.c
+@@ -175,20 +175,8 @@ netfs_S_file_set_translator (struct protid *user,
+ }
+ }
+
+- if (! err && user->po->path)
+- err = fshelp_set_active_translator (user->po->path, active);
+-
+- if (! err && active != MACH_PORT_NULL)
+- {
+- mach_port_t old;
+- err = mach_port_request_notification (mach_task_self (), active,
+- MACH_NOTIFY_DEAD_NAME, 0,
+- user->pi.port_right,
+- MACH_MSG_TYPE_MAKE_SEND_ONCE,
+- &old);
+- if (old != MACH_PORT_NULL)
+- mach_port_deallocate (mach_task_self (), old);
+- }
++ if (! err && user->po->path && active_flags & FS_TRANS_SET)
++ err = fshelp_set_active_translator (&user->pi, user->po->path, active);
+
+ out:
+ pthread_mutex_unlock (&np->lock);