Rev 2521 | Rev 2526 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2521 | Rev 2523 | ||
---|---|---|---|
Line 37... | Line 37... | ||
37 | 37 | ||
38 | #include <ipc/ipc.h> |
38 | #include <ipc/ipc.h> |
39 | #include <ipc/services.h> |
39 | #include <ipc/services.h> |
40 | #include <async.h> |
40 | #include <async.h> |
41 | #include <errno.h> |
41 | #include <errno.h> |
- | 42 | #include <stdlib.h> |
|
- | 43 | #include <bool.h> |
|
42 | #include "vfs.h" |
44 | #include "vfs.h" |
43 | 45 | ||
- | 46 | /** Verify the VFS info structure. |
|
- | 47 | * |
|
- | 48 | * @param info Info structure to be verified. |
|
- | 49 | * |
|
- | 50 | * @return Non-zero if the info structure is sane, zero otherwise. |
|
- | 51 | */ |
|
- | 52 | static int vfs_info_sane(vfs_info_t *info) |
|
- | 53 | { |
|
- | 54 | return 1; /* XXX */ |
|
- | 55 | } |
|
- | 56 | ||
- | 57 | /** VFS_REGISTER protocol function. |
|
- | 58 | * |
|
- | 59 | * @param rid Hash of the call with the request. |
|
- | 60 | * @param request Call structure with the request. |
|
- | 61 | */ |
|
44 | static void vfs_register(ipc_callid_t iid, ipc_call_t *icall) |
62 | static void vfs_register(ipc_callid_t rid, ipc_call_t *request) |
45 | { |
63 | { |
46 | ipc_callid_t callid; |
64 | ipc_callid_t callid; |
47 | ipc_call_t call; |
65 | ipc_call_t call; |
- | 66 | int rc; |
|
- | 67 | size_t size; |
|
48 | 68 | ||
49 | callid = async_get_call(&call); |
- | |
50 | if (IPC_GET_METHOD(call) == IPC_M_DATA_SEND) { |
- | |
51 | size_t size = IPC_GET_ARG3(call); |
- | |
52 | if (size != sizeof(vfs_info_t)) { |
- | |
53 | /* |
69 | /* |
54 | * The client is sending us something, which cannot be |
70 | * The first call has to be IPC_M_DATA_SEND in which we receive the |
55 | * the info structure. |
71 | * VFS info structure from the client FS. |
56 | */ |
72 | */ |
57 | ipc_answer_fast(iid, EINVAL, 0, 0); |
- | |
58 | ipc_answer_fast(callid, EINVAL, 0, 0); |
73 | if (!ipc_data_send_accept(&callid, &call, NULL, &size)) { |
59 | return; |
- | |
60 | } |
- | |
61 | /* |
- | |
62 | * XXX: continue here |
- | |
63 | * Allocate an info structue, answer the call, check sanity |
- | |
64 | * of the copied-in info structure, ... |
- | |
65 | */ |
- | |
66 | } else { |
- | |
67 | /* |
74 | /* |
68 | * The client doesn't obey the same protocol as we do. |
75 | * The client doesn't obey the same protocol as we do. |
69 | */ |
76 | */ |
70 | ipc_answer_fast(iid, EINVAL, 0, 0); |
- | |
71 | ipc_answer_fast(callid, EINVAL, 0, 0); |
77 | ipc_answer_fast(callid, EINVAL, 0, 0); |
- | 78 | ipc_answer_fast(rid, EINVAL, 0, 0); |
|
72 | return; |
79 | return; |
73 | } |
80 | } |
- | 81 | ||
- | 82 | /* |
|
- | 83 | * We know the size of the info structure. See if the client understands |
|
- | 84 | * this easy concept too. |
|
- | 85 | */ |
|
- | 86 | if (size != sizeof(vfs_info_t)) { |
|
- | 87 | /* |
|
- | 88 | * The client is sending us something, which cannot be |
|
- | 89 | * the info structure. |
|
- | 90 | */ |
|
- | 91 | ipc_answer_fast(callid, EINVAL, 0, 0); |
|
- | 92 | ipc_answer_fast(rid, EINVAL, 0, 0); |
|
- | 93 | return; |
|
- | 94 | } |
|
- | 95 | vfs_info_t *info; |
|
- | 96 | ||
- | 97 | /* |
|
- | 98 | * Allocate a buffer for the info structure. |
|
- | 99 | */ |
|
- | 100 | info = (vfs_info_t *) malloc(sizeof(vfs_info_t)); |
|
- | 101 | if (!info) { |
|
- | 102 | ipc_answer_fast(callid, ENOMEM, 0, 0); |
|
- | 103 | ipc_answer_fast(rid, ENOMEM, 0, 0); |
|
- | 104 | return; |
|
- | 105 | } |
|
- | 106 | ||
- | 107 | rc = ipc_data_send_answer(callid, &call, info, size); |
|
- | 108 | if (!rc) { |
|
- | 109 | free(info); |
|
- | 110 | ipc_answer_fast(callid, rc, 0, 0); |
|
- | 111 | ipc_answer_fast(rid, rc, 0, 0); |
|
- | 112 | return; |
|
- | 113 | } |
|
- | 114 | ||
- | 115 | if (!vfs_info_sane(info)) { |
|
- | 116 | free(info); |
|
- | 117 | ipc_answer_fast(callid, EINVAL, 0, 0); |
|
- | 118 | ipc_answer_fast(rid, EINVAL, 0, 0); |
|
- | 119 | return; |
|
- | 120 | } |
|
- | 121 | ||
74 | } |
122 | } |
75 | 123 | ||
76 | static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall) |
124 | static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall) |
77 | { |
125 | { |
78 | ipcarg_t iarg1, iarg2; |
126 | bool keep_on_going = 1; |
79 | 127 | ||
80 | /* |
128 | /* |
81 | * The connection was opened via the IPC_CONNECT_ME_TO call. |
129 | * The connection was opened via the IPC_CONNECT_ME_TO call. |
82 | * This call needs to be answered. |
130 | * This call needs to be answered. |
83 | * |
- | |
84 | * The protocol is that the requested action is specified in ARG1 |
- | |
85 | * of the opening call. If the request has a single integer argument, |
- | |
86 | * it is passed in ARG2. |
- | |
87 | */ |
131 | */ |
88 | iarg1 = IPC_GET_ARG1(*icall); |
- | |
89 | iarg2 = IPC_GET_ARG2(*icall); |
132 | ipc_answer_fast(iid, EOK, 0, 0); |
90 | 133 | ||
91 | /* |
134 | /* |
- | 135 | * Here we enter the main connection fibril loop. |
|
- | 136 | * The logic behind this loop and the protocol is that we'd like to keep |
|
92 | * Now, the connection can either be from an individual FS, |
137 | * each connection open for a while before we close it. The benefit of |
93 | * which is trying to register itself and pass us its capabilities. |
138 | * this is that the client doesn't have to establish a new connection |
- | 139 | * upon each request. On the other hand, the client must be ready to |
|
94 | * Or, the connection is a regular connection from a client that wants |
140 | * re-establish a connection if we hang it up due to reaching of maximum |
95 | * us to do something for it (e.g. open a file, mount a fs etc.). |
141 | * number of requests per connection or due to the client timing out. |
96 | */ |
142 | */ |
- | 143 | ||
- | 144 | while (keep_on_going) { |
|
- | 145 | ipc_callid_t callid; |
|
- | 146 | ipc_call_t call; |
|
- | 147 | ||
- | 148 | callid = async_get_call(&call); |
|
- | 149 | ||
97 | switch (iarg1) { |
150 | switch (IPC_GET_METHOD(call)) { |
- | 151 | case IPC_M_PHONE_HUNGUP: |
|
- | 152 | keep_on_going = false; |
|
- | 153 | break; |
|
98 | case VFS_REGISTER: |
154 | case VFS_REGISTER: |
99 | vfs_register(iid, icall); |
155 | vfs_register(callid, &call); |
- | 156 | keep_on_going = false; |
|
100 | break; |
157 | break; |
101 | case VFS_MOUNT: |
158 | case VFS_MOUNT: |
102 | case VFS_UNMOUNT: |
159 | case VFS_UNMOUNT: |
103 | case VFS_OPEN: |
160 | case VFS_OPEN: |
- | 161 | case VFS_CREATE: |
|
- | 162 | case VFS_CLOSE: |
|
- | 163 | case VFS_READ: |
|
- | 164 | case VFS_WRITE: |
|
- | 165 | case VFS_SEEK: |
|
104 | default: |
166 | default: |
105 | ipc_answer_fast(iid, ENOTSUP, 0, 0); |
167 | ipc_answer_fast(callid, ENOTSUP, 0, 0); |
106 | break; |
168 | break; |
- | 169 | } |
|
107 | } |
170 | } |
- | 171 | ||
- | 172 | /* TODO: cleanup after the client */ |
|
- | 173 | ||
108 | } |
174 | } |
109 | 175 | ||
110 | int main(int argc, char **argv) |
176 | int main(int argc, char **argv) |
111 | { |
177 | { |
112 | ipcarg_t phonead; |
178 | ipcarg_t phonead; |