diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-10-08 12:42:52 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 19:17:59 +0100 |
commit | 9c2d39405c30b75bc817a6212a116421ebb927f1 (patch) | |
tree | 94c4df9c1f97e98b9dda0b4777328a98d28eadec | |
parent | 4de65c4af42894f57b8b8c3a050260725a96b109 (diff) |
libdiskfs: register passive translator startups
Detect passive translator startup and add the resulting active
translator to the list of active translators.
Note that newpi is properly deallocated in the function epilogue.
* libdiskfs/dir-lookup.c (diskfs_S_dir_lookup): Detect and register
passive translator startup.
-rw-r--r-- | libdiskfs/dir-lookup.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index 86116e35..3950bf9c 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -1,6 +1,6 @@ /* libdiskfs implementation of fs.defs:dir_lookup Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2008, 2013 Free Software Foundation, Inc. + 2002, 2008, 2013, 2014 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -74,6 +74,10 @@ diskfs_S_dir_lookup (struct protid *dircred, if (! relpath) return ENOMEM; + /* Keep a pointer to the start of the path for length + calculations. */ + char *path_start = path; + *returned_port_poly = MACH_MSG_TYPE_MAKE_SEND; *retry = FS_RETRY_NORMAL; retryname[0] = '\0'; @@ -274,11 +278,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 +310,35 @@ diskfs_S_dir_lookup (struct protid *dircred, *end++ = '/'; strcpy (end, nextname); } + + if (register_translator) + { + char *translator_path = strdupa (relpath); + if (nextname != NULL) + { + /* This was not the last path component. + NEXTNAME points to the next component, locate + the end of the current component and use it + to trim TRANSLATOR_PATH. */ + char *end = nextname; + while (*end != 0) + end--; + translator_path[end - path_start] = '\0'; + } + + error = fshelp_set_active_translator (&newpi->pi, + translator_path, + 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. */ |