diff options
author | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-03-06 20:31:04 +0200 |
---|---|---|
committer | Sergiu Ivanov <unlimitedscolobb@gmail.com> | 2009-03-06 20:31:04 +0200 |
commit | 3cea8614816e68db569bbea21134c64273e037b5 (patch) | |
tree | 8fa552187ad145b9ccd80fe984969b2944f0926a | |
parent | 2fc7f8c49fc34cd2db65c36400200082a62138a1 (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.c | 95 | ||||
-rw-r--r-- | node.h | 12 | ||||
-rw-r--r-- | nsmux.c | 54 |
3 files changed, 128 insertions, 33 deletions
@@ -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 */ +/*---------------------------------------------------------------------------*/ @@ -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__*/ @@ -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. */ |