diff options
-rw-r--r-- | debian/patches/series | 1 | ||||
-rw-r--r-- | debian/patches/translatorslist-detect-passive-translators.patch | 277 |
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); |