| [0f78e74] | 1 | /*
 | 
|---|
| [0ee4322] | 2 |  * Copyright (c) 2008 Jakub Jermar
 | 
|---|
| [0f78e74] | 3 |  * All rights reserved.
 | 
|---|
 | 4 |  *
 | 
|---|
 | 5 |  * Redistribution and use in source and binary forms, with or without
 | 
|---|
 | 6 |  * modification, are permitted provided that the following conditions
 | 
|---|
 | 7 |  * are met:
 | 
|---|
 | 8 |  *
 | 
|---|
 | 9 |  * - Redistributions of source code must retain the above copyright
 | 
|---|
 | 10 |  *   notice, this list of conditions and the following disclaimer.
 | 
|---|
 | 11 |  * - Redistributions in binary form must reproduce the above copyright
 | 
|---|
 | 12 |  *   notice, this list of conditions and the following disclaimer in the
 | 
|---|
 | 13 |  *   documentation and/or other materials provided with the distribution.
 | 
|---|
 | 14 |  * - The name of the author may not be used to endorse or promote products
 | 
|---|
 | 15 |  *   derived from this software without specific prior written permission.
 | 
|---|
 | 16 |  *
 | 
|---|
 | 17 |  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | 
|---|
 | 18 |  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
|---|
 | 19 |  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
|---|
 | 20 |  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
|---|
 | 21 |  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
|---|
 | 22 |  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
|---|
 | 23 |  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
|---|
 | 24 |  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
|---|
 | 25 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
|---|
 | 26 |  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
|---|
 | 27 |  */
 | 
|---|
 | 28 | 
 | 
|---|
| [b1834a01] | 29 | /** @addtogroup vfs
 | 
|---|
| [0f78e74] | 30 |  * @{
 | 
|---|
| [8dc72b64] | 31 |  */
 | 
|---|
| [0f78e74] | 32 | 
 | 
|---|
 | 33 | /**
 | 
|---|
| [8dc72b64] | 34 |  * @file vfs.c
 | 
|---|
 | 35 |  * @brief VFS service for HelenOS.
 | 
|---|
| [0f78e74] | 36 |  */
 | 
|---|
 | 37 | 
 | 
|---|
| [e2ab36f1] | 38 | #include <vfs/vfs.h>
 | 
|---|
| [a481d81] | 39 | #include <stdlib.h>
 | 
|---|
| [c952465d] | 40 | #include <ipc/services.h>
 | 
|---|
| [a481d81] | 41 | #include <abi/ipc/methods.h>
 | 
|---|
 | 42 | #include <libarch/config.h>
 | 
|---|
| [79ae36dd] | 43 | #include <ns.h>
 | 
|---|
| [c952465d] | 44 | #include <async.h>
 | 
|---|
 | 45 | #include <errno.h>
 | 
|---|
| [c1694b6b] | 46 | #include <str_error.h>
 | 
|---|
| [47a776f9] | 47 | #include <stdio.h>
 | 
|---|
| [3e6a98c5] | 48 | #include <stdbool.h>
 | 
|---|
| [19f857a] | 49 | #include <str.h>
 | 
|---|
| [bcf23cf] | 50 | #include <as.h>
 | 
|---|
| [e2ab36f1] | 51 | #include <macros.h>
 | 
|---|
| [c952465d] | 52 | #include "vfs.h"
 | 
|---|
 | 53 | 
 | 
|---|
| [007e6efa] | 54 | #define NAME  "vfs"
 | 
|---|
| [6c89f20d] | 55 | 
 | 
|---|
| [984a9ba] | 56 | static void vfs_pager(ipc_call_t *icall, void *arg)
 | 
|---|
| [519a97d] | 57 | {
 | 
|---|
| [beb83c1] | 58 |         async_accept_0(icall);
 | 
|---|
| [a481d81] | 59 | 
 | 
|---|
 | 60 |         while (true) {
 | 
|---|
 | 61 |                 ipc_call_t call;
 | 
|---|
| [984a9ba] | 62 |                 async_get_call(&call);
 | 
|---|
| [a35b458] | 63 | 
 | 
|---|
| [889cdb1] | 64 |                 if (!IPC_GET_IMETHOD(call)) {
 | 
|---|
 | 65 |                         async_answer_0(&call, EOK);
 | 
|---|
| [a481d81] | 66 |                         break;
 | 
|---|
| [889cdb1] | 67 |                 }
 | 
|---|
| [a35b458] | 68 | 
 | 
|---|
| [a481d81] | 69 |                 switch (IPC_GET_IMETHOD(call)) {
 | 
|---|
 | 70 |                 case IPC_M_PAGE_IN:
 | 
|---|
| [984a9ba] | 71 |                         vfs_page_in(&call);
 | 
|---|
| [a481d81] | 72 |                         break;
 | 
|---|
 | 73 |                 default:
 | 
|---|
| [984a9ba] | 74 |                         async_answer_0(&call, ENOTSUP);
 | 
|---|
| [a481d81] | 75 |                         break;
 | 
|---|
 | 76 |                 }
 | 
|---|
 | 77 |         }
 | 
|---|
| [519a97d] | 78 | }
 | 
|---|
 | 79 | 
 | 
|---|
| [01c3bb4] | 80 | static void notification_handler(ipc_call_t *call, void *arg)
 | 
|---|
| [2bc13887] | 81 | {
 | 
|---|
| [8820544] | 82 |         if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
 | 
|---|
| [354b642] | 83 |                 vfs_op_pass_handle(
 | 
|---|
| [8820544] | 84 |                     (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
 | 
|---|
| [6769005] | 85 |                     IPC_GET_ARG5(*call)), call->task_id,
 | 
|---|
| [8820544] | 86 |                     (int) IPC_GET_ARG2(*call));
 | 
|---|
| [2bc13887] | 87 | }
 | 
|---|
 | 88 | 
 | 
|---|
| [0f78e74] | 89 | int main(int argc, char **argv)
 | 
|---|
 | 90 | {
 | 
|---|
| [a47f522] | 91 |         printf("%s: HelenOS VFS server\n", NAME);
 | 
|---|
| [a35b458] | 92 | 
 | 
|---|
| [b818cff] | 93 |         /*
 | 
|---|
 | 94 |          * Initialize VFS node hash table.
 | 
|---|
 | 95 |          */
 | 
|---|
 | 96 |         if (!vfs_nodes_init()) {
 | 
|---|
| [a47f522] | 97 |                 printf("%s: Failed to initialize VFS node hash table\n",
 | 
|---|
 | 98 |                     NAME);
 | 
|---|
| [b818cff] | 99 |                 return ENOMEM;
 | 
|---|
 | 100 |         }
 | 
|---|
| [a35b458] | 101 | 
 | 
|---|
| [bcf23cf] | 102 |         /*
 | 
|---|
 | 103 |          * Allocate and initialize the Path Lookup Buffer.
 | 
|---|
 | 104 |          */
 | 
|---|
| [faba839] | 105 |         plb = as_area_create(AS_AREA_ANY, PLB_SIZE,
 | 
|---|
| [6aeca0d] | 106 |             AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
 | 
|---|
| [faba839] | 107 |         if (plb == AS_MAP_FAILED) {
 | 
|---|
| [a47f522] | 108 |                 printf("%s: Cannot create address space area\n", NAME);
 | 
|---|
| [37e7dc54] | 109 |                 return ENOMEM;
 | 
|---|
 | 110 |         }
 | 
|---|
 | 111 |         memset(plb, 0, PLB_SIZE);
 | 
|---|
| [a35b458] | 112 | 
 | 
|---|
| [b75e929] | 113 |         /*
 | 
|---|
 | 114 |          * Set client data constructor and destructor.
 | 
|---|
 | 115 |          */
 | 
|---|
 | 116 |         async_set_client_data_constructor(vfs_client_data_create);
 | 
|---|
 | 117 |         async_set_client_data_destructor(vfs_client_data_destroy);
 | 
|---|
 | 118 | 
 | 
|---|
| [2bc13887] | 119 |         /*
 | 
|---|
| [8820544] | 120 |          * Subscribe to notifications.
 | 
|---|
| [2bc13887] | 121 |          */
 | 
|---|
| [8820544] | 122 |         async_event_task_subscribe(EVENT_TASK_STATE_CHANGE, notification_handler,
 | 
|---|
 | 123 |             NULL);
 | 
|---|
| [a35b458] | 124 | 
 | 
|---|
| [bcf23cf] | 125 |         /*
 | 
|---|
 | 126 |          * Register at the naming service.
 | 
|---|
 | 127 |          */
 | 
|---|
| [9b1baac] | 128 |         errno_t rc = service_register(SERVICE_VFS, INTERFACE_PAGER, vfs_pager, NULL);
 | 
|---|
 | 129 |         if (rc != EOK) {
 | 
|---|
 | 130 |                 printf("%s: Cannot register VFS pager port: %s\n", NAME, str_error(rc));
 | 
|---|
 | 131 |                 return rc;
 | 
|---|
 | 132 |         }
 | 
|---|
 | 133 | 
 | 
|---|
 | 134 |         rc = service_register(SERVICE_VFS, INTERFACE_VFS, vfs_connection, NULL);
 | 
|---|
 | 135 |         if (rc != EOK) {
 | 
|---|
 | 136 |                 printf("%s: Cannot register VFS file system port: %s\n", NAME, str_error(rc));
 | 
|---|
 | 137 |                 return rc;
 | 
|---|
 | 138 |         }
 | 
|---|
 | 139 | 
 | 
|---|
 | 140 |         rc = service_register(SERVICE_VFS, INTERFACE_VFS_DRIVER, vfs_connection, NULL);
 | 
|---|
| [a47f522] | 141 |         if (rc != EOK) {
 | 
|---|
| [9b1baac] | 142 |                 printf("%s: Cannot register VFS driver port: %s\n", NAME, str_error(rc));
 | 
|---|
| [a47f522] | 143 |                 return rc;
 | 
|---|
| [007e6efa] | 144 |         }
 | 
|---|
| [a35b458] | 145 | 
 | 
|---|
| [bcf23cf] | 146 |         /*
 | 
|---|
 | 147 |          * Start accepting connections.
 | 
|---|
 | 148 |          */
 | 
|---|
| [a47f522] | 149 |         printf("%s: Accepting connections\n", NAME);
 | 
|---|
| [c952465d] | 150 |         async_manager();
 | 
|---|
| [0f78e74] | 151 |         return 0;
 | 
|---|
 | 152 | }
 | 
|---|
 | 153 | 
 | 
|---|
 | 154 | /**
 | 
|---|
 | 155 |  * @}
 | 
|---|
| [8dc72b64] | 156 |  */
 | 
|---|