summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2009-03-06 20:31:04 +0200
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2009-03-06 20:31:04 +0200
commit3cea8614816e68db569bbea21134c64273e037b5 (patch)
tree8fa552187ad145b9ccd80fe984969b2944f0926a
parent2fc7f8c49fc34cd2db65c36400200082a62138a1 (diff)
Added proxy nodes in the dynamic translator stack
When setting dynamic translators, nsmux used to offer the client a port to the dynamic translator directly. Now it gives off a proxy node, which contains a port to the translator. Also, proxy nodes are now included in dynamic translator stacks. Dynamic translator stacks now consist of the following interconnected conceptual blocks: -- shadow node -- translator -- proxy node --
-rw-r--r--node.c95
-rw-r--r--node.h12
-rw-r--r--nsmux.c54
3 files changed, 128 insertions, 33 deletions
diff --git a/node.c b/node.c
index f7db74107..1c47d735c 100644
--- a/node.c
+++ b/node.c
@@ -232,19 +232,23 @@ void node_destroy (node_t * np)
/*TODO: If this node is a shadow node, kill the translator sitting
on this node. */
- /*Lock the lnode corresponding to the current node */
- mutex_lock (&np->nn->lnode->lock);
+ /*If there is an lnode associated with the current node, detach
+ it */
+ if (np->nn->lnode)
+ {
+ if (np->nn->lnode->node == np)
+ {
+ mutex_lock (&np->nn->lnode->lock);
- /*If the node to be destroyed is a real netfs node */
- if (np->nn->lnode->node == np)
- /*orphan the light node */
- np->nn->lnode->node = NULL;
- else
- /*remove a reference to this node from the list of proxies */
- lnode_remove_proxy (np->nn->lnode, np);
+ /*orphan the light node */
+ np->nn->lnode->node = NULL;
- /*Remove a reference from the lnode */
- lnode_ref_remove (np->nn->lnode);
+ lnode_ref_remove (np->nn->lnode);
+ }
+ else
+ /*remove a reference to this node from the list of proxies */
+ lnode_remove_proxy (np->nn->lnode, np);
+ }
/*Free the netnode and the node itself */
free (np->nn);
@@ -919,3 +923,72 @@ error_t
} /*node_set_translator */
/*---------------------------------------------------------------------------*/
+/*Gets the port to the supplied node. */
+error_t
+ node_get_port
+ (struct protid * diruser, node_t * np, int flags, mach_port_t * port)
+{
+ error_t error = 0;
+
+ /*The new user for the port */
+ struct iouser * user;
+
+ /*The protid for the port */
+ struct protid * newpi;
+
+ /*Create a port to the supplied node without checking anything. */
+
+ flags &= ~OPENONLY_STATE_MODES;
+ error = iohelp_dup_iouser (&user, diruser->user);
+ if (error)
+ return error;
+
+ newpi = netfs_make_protid
+ (netfs_make_peropen (np, flags, diruser->po), user);
+ if (!newpi)
+ {
+ iohelp_free_iouser (user);
+ error = errno;
+ return error;
+ }
+
+ *port = ports_get_right (newpi);
+ ports_port_deref (newpi);
+ return error;
+} /*node_get_port */
+
+/*---------------------------------------------------------------------------*/
+/*Gets the send port right to the supplied node. */
+error_t
+ node_get_send_port
+ (struct protid * diruser, node_t * np, int flags, mach_port_t * port)
+{
+ error_t error = 0;
+
+ /*The new user for the port */
+ struct iouser * user;
+
+ /*The protid for the port */
+ struct protid * newpi;
+
+ /*Create a port to the supplied node without checking anything. */
+
+ flags &= ~OPENONLY_STATE_MODES;
+ error = iohelp_dup_iouser (&user, diruser->user);
+ if (error)
+ return error;
+
+ newpi = netfs_make_protid
+ (netfs_make_peropen (np, flags, diruser->po), user);
+ if (!newpi)
+ {
+ iohelp_free_iouser (user);
+ error = errno;
+ return error;
+ }
+
+ *port = ports_get_send_right (newpi);
+ ports_port_deref (newpi);
+ return error;
+} /*node_get_send_port */
+/*---------------------------------------------------------------------------*/
diff --git a/node.h b/node.h
index 9ae760f01..7cb154386 100644
--- a/node.h
+++ b/node.h
@@ -151,9 +151,19 @@ error_t node_unlink_file (node_t * dir, char *name);
/*Starts translator `trans` on the (shadow) node `np`, which should
mirror the file `filename`, and returns the port `port` to the root
of the translator opened as `flags.`*/
-error_t
+error_t
node_set_translator
(struct protid *diruser, node_t * np, char * trans, int flags,
char * filename, mach_port_t * port);
/*---------------------------------------------------------------------------*/
+/*Gets the port to the supplied node. */
+error_t
+ node_get_port
+ (struct protid * diruser, node_t * np, int flags, mach_port_t * port);
+/*---------------------------------------------------------------------------*/
+/*Gets the send port right to the supplied node. */
+error_t
+ node_get_send_port
+ (struct protid * diruser, node_t * np, int flags, mach_port_t * port);
+/*---------------------------------------------------------------------------*/
#endif /*__NODE_H__*/
diff --git a/nsmux.c b/nsmux.c
index 0f713f14a..d2da05086 100644
--- a/nsmux.c
+++ b/nsmux.c
@@ -765,7 +765,7 @@ error_t
struct protid *newpi;
struct iouser *user;
- /*The port to the file for the case when we don't need proxy nodes */
+ /*The port to the file */
file_t file = MACH_PORT_NULL;
/*The port to the same file with restricted rights */
@@ -905,6 +905,20 @@ error_t
netfs_nref (np);
mutex_unlock (&np->lock);
+
+ /*`np` is a proxy node of the lower translator. We
+ have to create a shadow node explicitly. */
+ error = node_get_send_port (diruser, np, flags, &file);
+ if (error)
+ goto out;
+
+ error = node_create_from_port(file, &np);
+ if (error)
+ goto out;
+
+ /*`np` is supposed to be unlocked by the following
+ code. */
+ mutex_unlock (&np->lock);
}
else
/*lookup the file in the real filesystem */
@@ -914,7 +928,7 @@ error_t
if (!error && !excl)
{
- /*if there is at least one more separator in the
+ /*If there is at least one more separator in the
filename, we will have to do a retry */
nextsep = magic_find_sep(sep);
if (nextsep)
@@ -925,7 +939,7 @@ error_t
goto out;
strncpy(trans, sep, trans_len);
trans[trans_len] = 0;
-
+
/*set the required translator on the node */
error = node_set_translator
(diruser, np, trans, flags, filename, &file);
@@ -947,28 +961,15 @@ error_t
netfs_nput (np);
error = node_create_from_port (file, &np);
+ /*create a port to the proxy node */
+
/*we don't check the permissions here, because
this check has been performed in the lookup of
- the real filename in the beginning of the
+ the real filename at the beginning of the
process of setting up the dynamic translator
stack */
- flags &= ~OPENONLY_STATE_MODES;
- error = iohelp_dup_iouser (&user, diruser->user);
- if (error)
- goto out;
-
- newpi = netfs_make_protid
- (netfs_make_peropen (np, flags, diruser->po), user);
- if (!newpi)
- {
- iohelp_free_iouser (user);
- error = errno;
- goto out;
- }
-
- *retry_port = ports_get_right (newpi);
- ports_port_deref (newpi);
+ error = node_get_port (diruser, np, flags, retry_port);
if (np)
netfs_nput (np);
@@ -985,10 +986,21 @@ error_t
if (error)
goto out;
+ /*create a proxy node for the port to the current
+ translator */
+ netfs_nput (np);
+ error = node_create_from_port (file, &np);
+
+ /*create a port to the proxy node */
+ error = node_get_port (diruser, np, flags, retry_port);
+ if (error)
+ goto out;
+
/*No more retries are necessary, if we are at the
last component of the filename */
if(lastcomp)
- goto justport;
+ /*goto justport; */
+ goto out;
else
/*TODO: Do a retry in case this is not the last
component of the filename. */