summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergiu Ivanov <unlimitedscolobb@gmail.com>2009-01-29 22:53:57 +0200
committerSergiu Ivanov <unlimitedscolobb@gmail.com>2009-01-29 22:53:57 +0200
commiteeba2e52b08c78f2ba362174c8bfc8d222133b45 (patch)
treea3081b26013a887bfe0d6b10fdbb0787536e0e3f
parent966522f2fa9239d9c2ba08152cc7019d996c2516 (diff)
Made nsmux able to pass retries to the client
Now, when nsmux sets another dynamic translator, it sends a retry to the client, so that it could set the (possible) next dynamic translator in the next execution of netfs_S_dir_lookup, which will occur due to the retry. However, nsmux cannot handle the retry properly yet. The reason for splitting the functionality of *only* passing the retry to client in a separate commit is that it required some tricky code manipulation and hence I feel that keeping it in a separate commit is quite reasonable.
-rw-r--r--nsmux.c96
1 files changed, 84 insertions, 12 deletions
diff --git a/nsmux.c b/nsmux.c
index 8dd9b9c90..312552858 100644
--- a/nsmux.c
+++ b/nsmux.c
@@ -778,7 +778,13 @@ error_t
char * sep;
/*The position of the next magic separator in the filename */
- char * next_sep;
+ char * nextsep;
+
+ /*The name of the translator to set in this retry */
+ char * trans = NULL;
+
+ /*The length of the name of the translator to set in this retry */
+ int trans_len = 0;
if (!diruser)
return EOPNOTSUPP;
@@ -884,31 +890,97 @@ error_t
if (sep)
{
- /*We have to create a shadow node and set a translator
- on it. */
-
sep[0] = sep[1] = 0;
sep += 2;
+ /*We have to create a shadow node and set a translator
+ on it. */
+
error = netfs_attempt_lookup_improved
(diruser->user, dnp, filename, flags, lastcomp, &np, &file, 1);
if (!error && !excl)
{
+ /*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)
+ {
+ trans_len = nextsep - sep;
+ trans = malloc (trans_len + 1);
+ if (!trans)
+ 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);
+ if (error)
+ goto out;
+
+ free (trans);
+
+ /*prepare the information for the retry */
+
+/* *retry_port_type = MACH_MSG_TYPE_MOVE_SEND; */
+ strcpy (retry_name, nextsep);
+ if (nextname)
+ {
+ strcat (retry_name, "/");
+ strcat (retry_name, nextname);
+ }
+
+ /*create a proxy node for the port to the root
+ of translator */
+ netfs_nput (np);
+ error = node_create_from_port (file, &np);
+
+ /*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
+ 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);
+
+ if (np)
+ netfs_nput (np);
+ if (dnp)
+ netfs_nrele (dnp);
+
+ /*ask the client to retry */
+ return 0;
+ }
+
/*set the required translator on the node */
error = node_set_translator
(diruser, np, sep, flags, filename, &file);
if (error)
goto out;
- /*if there is at least one more separator in the
- filename, we will have to do a retry */
- next_sep = magic_find_sep(sep);
- if (next_sep)
- {
- }
- else
- /*No (more) retries are necessary */
+ /*No more retries are necessary, if we are at the
+ last component of the filename */
+ if(lastcomp)
goto justport;
+ else
+ /*TODO: Do a retry in case this is not the last
+ component of the filename. */
+ ;
}
}
else