1.1 --- a/server/src/main.cc Mon Jul 22 17:36:37 2019 +0200
1.2 +++ b/server/src/main.cc Sun Dec 01 19:09:59 2019 +0100
1.3 @@ -19,12 +19,8 @@
1.4 * Boston, MA 02110-1301, USA
1.5 */
1.6
1.7 -#include <l4/util/util.h>
1.8 -
1.9 -#include <l4/re/c/dataspace.h>
1.10 #include <l4/re/env.h>
1.11 #include <l4/sys/err.h>
1.12 -#include <l4/sys/types.h>
1.13
1.14 #include <stdlib.h>
1.15 #include <stdio.h>
1.16 @@ -34,11 +30,17 @@
1.17 #include <map>
1.18
1.19 #include <fsclient/fsdesc.h>
1.20 -#include <fsclient/fs_ipc.h>
1.21 -#include <fsclient/ops.h>
1.22 -#include <fsserver/server.h>
1.23 +#include <fsclient/fsdesc_client.h>
1.24 #include "fspath.h"
1.25
1.26 +/* Exposure of the resource. */
1.27 +
1.28 +#include <fsserver/file_resource_server.h>
1.29 +
1.30 +/* Implemented interfaces. */
1.31 +
1.32 +#include <fsserver/user_filesystem_resource.h>
1.33 +
1.34
1.35
1.36 /* Mountpoint-to-server mapping. */
1.37 @@ -49,165 +51,161 @@
1.38
1.39
1.40
1.41 -/* Virtual filesystem server. */
1.42 +/* Virtual filesystem resource. */
1.43
1.44 -class Vfs_server : public OpeningServer
1.45 +class Vfs_resource : public UserFilesystemResource
1.46 {
1.47 private:
1.48 MountTable _servers;
1.49
1.50 public:
1.51 - explicit Vfs_server()
1.52 - : OpeningServer()
1.53 + explicit Vfs_resource()
1.54 + : UserFilesystemResource()
1.55 {
1.56 }
1.57
1.58 - void dispatch(ipc_message_t *msg)
1.59 +
1.60 +
1.61 + /* Obtain an object as a filesystem reference. */
1.62 +
1.63 + long getfs_object(fs_object_t *fsobj, l4_cap_idx_t *fs)
1.64 {
1.65 - switch (l4_msgtag_label(msg->tag))
1.66 - {
1.67 - case Fs_op_mount:
1.68 - mount(msg);
1.69 - break;
1.70 + file_descriptor_t desc;
1.71 + long err;
1.72 +
1.73 + /* Obtain a suitable descriptor. */
1.74 +
1.75 + err = init_desc(&desc, fsobj);
1.76 +
1.77 + if (err)
1.78 + return err;
1.79 +
1.80 + /* Return a reference to any directly-accessed object. */
1.81 +
1.82 + char *path = fsdesc_get_name(fsobj);
1.83
1.84 - case Fs_op_open:
1.85 - open(msg);
1.86 - break;
1.87 + if ((path != NULL) && !strlen(path))
1.88 + {
1.89 + *fs = desc.server;
1.90 + return L4_EOK;
1.91 + }
1.92 +
1.93 + /* Find the path within the selected filesystem. */
1.94 +
1.95 + /* Propagate the message to the identified filesystem.
1.96 + The L4_MSGTAG_PROPAGATE flag is not supported by Fiasco.OC, so this
1.97 + object has to act as intermediary. */
1.98
1.99 - case Fs_op_getfs:
1.100 - getfs(msg);
1.101 - break;
1.102 + err = fs_getfs(&desc);
1.103 +
1.104 + if (err)
1.105 + return err;
1.106 +
1.107 + /* Free the capabilities and buffer from this task. */
1.108
1.109 - default:
1.110 - ipc_message_send_error(msg, -L4_EBADPROTO);
1.111 - break;
1.112 - }
1.113 + fsdesc_deallocate_object(fsobj);
1.114 +
1.115 + /* Export and eventually free the server reference from this task. */
1.116 +
1.117 + *fs = discard_cap(desc.ref);
1.118 +
1.119 + return L4_EOK;
1.120 }
1.121
1.122 - void getfs(ipc_message_t *msg)
1.123 + /* Mount a filesystem at a particular location. */
1.124 +
1.125 + long mount_object(fs_object_t *fsobj, l4_cap_idx_t fs)
1.126 {
1.127 - _open(Fs_op_getfs, msg);
1.128 + /* Obtain the object's path. */
1.129 +
1.130 + char *path = fsdesc_get_name(fsobj);
1.131 +
1.132 + if (path == NULL)
1.133 + return -L4_EINVAL;
1.134 +
1.135 + /* Mount the supplied capability. */
1.136 +
1.137 + mount_at_path(fs, path);
1.138 +
1.139 + /* Free the capability and buffer from this task. */
1.140 +
1.141 + fsdesc_deallocate_buffer(fsobj);
1.142 +
1.143 + return L4_EOK;
1.144 }
1.145
1.146 - void open(ipc_message_t *msg)
1.147 - {
1.148 - _open(Fs_op_open, msg);
1.149 - }
1.150 + /* Open a filesystem object. */
1.151
1.152 - void _open(int op, ipc_message_t *msg)
1.153 + long open_object(fs_object_t *fsobj, int flags, size_t *size, l4_cap_idx_t *file)
1.154 {
1.155 file_descriptor_t desc;
1.156 - int flags;
1.157 long err;
1.158
1.159 - /* Obtain the flags. */
1.160 + /* Obtain a suitable descriptor. */
1.161 +
1.162 + err = init_desc(&desc, fsobj);
1.163 +
1.164 + if (err)
1.165 + return err;
1.166 +
1.167 + /* Find the path within the selected filesystem. */
1.168
1.169 - flags = ipc_message_get_word(msg, 0);
1.170 + /* Propagate the message to the identified filesystem.
1.171 + The L4_MSGTAG_PROPAGATE flag is not supported by Fiasco.OC, so this
1.172 + object has to act as intermediary. */
1.173
1.174 - /* Obtain the dataspace and IRQ object. */
1.175 + err = fs_open(&desc, flags);
1.176 +
1.177 + if (err)
1.178 + return err;
1.179 +
1.180 + /* Free the capabilities and buffer from this task. */
1.181
1.182 - err = fsdesc_import_object(msg, 0, &desc.obj);
1.183 - if (err)
1.184 - {
1.185 - ipc_message_send_error(msg, -L4_EIO);
1.186 - return;
1.187 - }
1.188 + fsdesc_deallocate_object(fsobj);
1.189 +
1.190 + /* Export and eventually free the server reference from this task. */
1.191 +
1.192 + *size = desc.obj.size;
1.193 + *file = discard_cap(desc.ref);
1.194 +
1.195 + return L4_EOK;
1.196 + }
1.197 +
1.198 +
1.199 +
1.200 + /* Non-exported methods. */
1.201 +
1.202 + /* Initialise a descriptor for accessing a mounted filesystem. */
1.203 +
1.204 + long init_desc(file_descriptor_t *desc, fs_object_t *obj)
1.205 + {
1.206 + /* Copy the object details into the descriptor. */
1.207 +
1.208 + desc->obj = *obj;
1.209
1.210 /* Match the path to a mountpoint. */
1.211
1.212 - char *path = fsdesc_get_name(&desc.obj);
1.213 + char *path = fsdesc_get_name(&desc->obj);
1.214
1.215 if (path == NULL)
1.216 - {
1.217 - ipc_message_send_error(msg, -L4_EINVAL);
1.218 - return;
1.219 - }
1.220 + return -L4_EINVAL;
1.221
1.222 MountTableIterator entry = find_mountpoint(path);
1.223
1.224 if (entry == _servers.end())
1.225 - {
1.226 - ipc_message_send_error(msg, -L4_ENOENT);
1.227 - return;
1.228 - }
1.229 + return -L4_ENOENT;
1.230
1.231 /* Rewrite the path for the selected filesystem. */
1.232
1.233 rewrite_path(path, entry->first);
1.234
1.235 - /* Find the path within the selected filesystem. */
1.236 -
1.237 - /* Propagate the message to the identified filesystem.
1.238 - NOTE: The L4_MSGTAG_PROPAGATE flag is not supported by Fiasco.OC, so this
1.239 - NOTE: object has to act as intermediary. */
1.240 -
1.241 - desc.server = entry->second;
1.242 -
1.243 - err = fs_ipc_open(&desc, flags, op);
1.244 - if (err)
1.245 - {
1.246 - ipc_message_send_error(msg, -L4_EIO);
1.247 - return;
1.248 - }
1.249 -
1.250 - /* Free the capabilities and buffer from this task. */
1.251 -
1.252 - fsdesc_deallocate_object(&desc.obj);
1.253 -
1.254 - /* Return the file size. */
1.255 -
1.256 - ipc_message_add_word(msg, desc.obj.size);
1.257 -
1.258 - /* Export and eventually free the server reference from this task. */
1.259 -
1.260 - ipc_message_propagate_item(msg, desc.ref);
1.261 - }
1.262 -
1.263 - void mount(ipc_message_t *msg)
1.264 - {
1.265 - fs_object_t fsobj;
1.266 - l4_cap_idx_t server;
1.267 - long err;
1.268 -
1.269 - /* Obtain the filesystem capability. */
1.270 + /* Use the filesystem as the target of any query. */
1.271
1.272 - err = ipc_message_import_capability(msg, 0, &server);
1.273 - if (err)
1.274 - {
1.275 - ipc_message_send_error(msg, -L4_EIO);
1.276 - return;
1.277 - }
1.278 -
1.279 - /* Obtain the dataspace. */
1.280 -
1.281 - err = fsdesc_import_dataspace(msg, 1, &fsobj);
1.282 - if (err)
1.283 - {
1.284 - ipc_message_send_error(msg, -L4_EIO);
1.285 - return;
1.286 - }
1.287 -
1.288 - /* Obtain the object's path. */
1.289 + desc->server = entry->second;
1.290
1.291 - char *path = fsdesc_get_name(&fsobj);
1.292 -
1.293 - if (path == NULL)
1.294 - {
1.295 - ipc_message_send_error(msg, -L4_EINVAL);
1.296 - return;
1.297 - }
1.298 -
1.299 - /* Mount the supplied capability. */
1.300 -
1.301 - mount_at_path(server, path);
1.302 -
1.303 - /* Free the capability and buffer from this task. */
1.304 -
1.305 - fsdesc_deallocate_buffer(&fsobj);
1.306 + return L4_EOK;
1.307 }
1.308
1.309 - /* Non-exported methods. */
1.310 -
1.311 void mount_at_path(l4_cap_idx_t server, const char *path)
1.312 {
1.313 /* NOTE: Should terminate with path separator if absent.
1.314 @@ -278,9 +276,10 @@
1.315
1.316 /* Initialise and register a new server object. */
1.317
1.318 - Vfs_server server_obj;
1.319 + Vfs_resource resource;
1.320 + UserFilesystemServer server(&resource);
1.321
1.322 - if (server_obj.bind("export"))
1.323 + if (server.bind("export"))
1.324 {
1.325 printf("Could not bind thread.\n");
1.326 return 1;
1.327 @@ -318,13 +317,14 @@
1.328 /* Terminate the path and register the mountpoint. */
1.329
1.330 *sep = '\0';
1.331 - server_obj.mount_at_path(fscap, buffer);
1.332 + resource.mount_at_path(fscap, buffer);
1.333 }
1.334
1.335 fclose(fp);
1.336
1.337 /* Enter the IPC server loop. */
1.338
1.339 - server_obj.loop();
1.340 + printf("Starting vfs resource...\n");
1.341 + server.start();
1.342 return 0;
1.343 }