Changes in uspace/srv/vfs/vfs_register.c [9593bc8:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_register.c
r9593bc8 rffa2c8ef 36 36 */ 37 37 38 #include <ipc/ipc.h>39 38 #include <ipc/services.h> 40 39 #include <async.h> 41 40 #include <fibril.h> 41 #include <fibril_synch.h> 42 42 #include <errno.h> 43 43 #include <stdio.h> 44 44 #include <stdlib.h> 45 #include <str ing.h>45 #include <str.h> 46 46 #include <ctype.h> 47 47 #include <bool.h> 48 #include <fibril_sync.h>49 48 #include <adt/list.h> 50 49 #include <as.h> … … 110 109 void vfs_register(ipc_callid_t rid, ipc_call_t *request) 111 110 { 112 ipc_callid_t callid; 113 ipc_call_t call; 114 int rc; 115 size_t size; 116 111 int phone; 112 117 113 dprintf("Processing VFS_REGISTER request received from %p.\n", 118 114 request->in_phone_hash); 119 120 /* 121 * The first call has to be IPC_M_DATA_SEND in which we receive the 122 * VFS info structure from the client FS. 123 */ 124 if (!ipc_data_write_receive(&callid, &size)) { 125 /* 126 * The client doesn't obey the same protocol as we do. 127 */ 128 dprintf("Receiving of VFS info failed.\n"); 129 ipc_answer_0(callid, EINVAL); 130 ipc_answer_0(rid, EINVAL); 131 return; 132 } 133 134 dprintf("VFS info received, size = %d\n", size); 135 136 /* 137 * We know the size of the VFS info structure. See if the client 138 * understands this easy concept too. 139 */ 140 if (size != sizeof(vfs_info_t)) { 141 /* 142 * The client is sending us something, which cannot be 143 * the info structure. 144 */ 145 dprintf("Received VFS info has bad size.\n"); 146 ipc_answer_0(callid, EINVAL); 147 ipc_answer_0(rid, EINVAL); 148 return; 149 } 150 151 /* 152 * Allocate and initialize a buffer for the fs_info structure. 153 */ 154 fs_info_t *fs_info; 155 fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 156 if (!fs_info) { 157 dprintf("Could not allocate memory for FS info.\n"); 158 ipc_answer_0(callid, ENOMEM); 159 ipc_answer_0(rid, ENOMEM); 160 return; 161 } 162 link_initialize(&fs_info->fs_link); 163 fibril_mutex_initialize(&fs_info->phone_lock); 164 165 rc = ipc_data_write_finalize(callid, &fs_info->vfs_info, size); 115 116 vfs_info_t *vfs_info; 117 int rc = async_data_write_accept((void **) &vfs_info, false, 118 sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL); 119 166 120 if (rc != EOK) { 167 121 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n", 168 122 rc); 169 free(fs_info); 170 ipc_answer_0(callid, rc); 171 ipc_answer_0(rid, rc); 172 return; 173 } 174 123 async_answer_0(rid, rc); 124 return; 125 } 126 127 /* 128 * Allocate and initialize a buffer for the fs_info structure. 129 */ 130 fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 131 if (!fs_info) { 132 dprintf("Could not allocate memory for FS info.\n"); 133 async_answer_0(rid, ENOMEM); 134 return; 135 } 136 137 link_initialize(&fs_info->fs_link); 138 fs_info->vfs_info = *vfs_info; 139 free(vfs_info); 140 175 141 dprintf("VFS info delivered.\n"); 176 142 177 143 if (!vfs_info_sane(&fs_info->vfs_info)) { 178 144 free(fs_info); 179 ipc_answer_0(callid, EINVAL); 180 ipc_answer_0(rid, EINVAL); 181 return; 182 } 183 145 async_answer_0(rid, EINVAL); 146 return; 147 } 148 184 149 fibril_mutex_lock(&fs_head_lock); 185 150 186 151 /* 187 152 * Check for duplicit registrations. … … 194 159 fibril_mutex_unlock(&fs_head_lock); 195 160 free(fs_info); 196 ipc_answer_0(callid, EEXISTS); 197 ipc_answer_0(rid, EEXISTS); 198 return; 199 } 200 161 async_answer_0(rid, EEXISTS); 162 return; 163 } 164 201 165 /* 202 166 * Add fs_info to the list of registered FS's. … … 210 174 * which to forward VFS requests to it. 211 175 */ 212 callid = async_get_call(&call); 213 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { 214 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); 176 ipc_call_t call; 177 ipc_callid_t callid = async_get_call(&call); 178 if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) { 179 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 215 180 list_remove(&fs_info->fs_link); 216 181 fibril_mutex_unlock(&fs_head_lock); 217 182 free(fs_info); 218 ipc_answer_0(callid, EINVAL); 219 ipc_answer_0(rid, EINVAL); 220 return; 221 } 222 fs_info->phone = IPC_GET_ARG5(call); 223 ipc_answer_0(callid, EOK); 224 183 async_answer_0(callid, EINVAL); 184 async_answer_0(rid, EINVAL); 185 return; 186 } 187 188 phone = IPC_GET_ARG5(call); 189 async_session_create(&fs_info->session, phone, 0); 190 async_answer_0(callid, EOK); 191 225 192 dprintf("Callback connection to FS created.\n"); 226 193 227 194 /* 228 195 * The client will want us to send him the address space area with PLB. 229 196 */ 230 231 if (!ipc_share_in_receive(&callid, &size)) { 232 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); 197 198 size_t size; 199 if (!async_share_in_receive(&callid, &size)) { 200 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call)); 233 201 list_remove(&fs_info->fs_link); 234 202 fibril_mutex_unlock(&fs_head_lock); 235 ipc_hangup(fs_info->phone); 236 free(fs_info); 237 ipc_answer_0(callid, EINVAL); 238 ipc_answer_0(rid, EINVAL); 203 async_session_destroy(&fs_info->session); 204 async_hangup(phone); 205 free(fs_info); 206 async_answer_0(callid, EINVAL); 207 async_answer_0(rid, EINVAL); 239 208 return; 240 209 } … … 247 216 list_remove(&fs_info->fs_link); 248 217 fibril_mutex_unlock(&fs_head_lock); 249 ipc_hangup(fs_info->phone); 250 free(fs_info); 251 ipc_answer_0(callid, EINVAL); 252 ipc_answer_0(rid, EINVAL); 253 return; 254 } 255 218 async_session_destroy(&fs_info->session); 219 async_hangup(phone); 220 free(fs_info); 221 async_answer_0(callid, EINVAL); 222 async_answer_0(rid, EINVAL); 223 return; 224 } 225 256 226 /* 257 227 * Commit to read-only sharing the PLB with the client. 258 228 */ 259 (void) ipc_share_in_finalize(callid, plb,229 (void) async_share_in_finalize(callid, plb, 260 230 AS_AREA_READ | AS_AREA_CACHEABLE); 261 231 262 232 dprintf("Sharing PLB.\n"); 263 233 264 234 /* 265 235 * That was it. The FS has been registered. … … 268 238 */ 269 239 fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next); 270 ipc_answer_1(rid, EOK, (ipcarg_t) fs_info->fs_handle);240 async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle); 271 241 272 242 fibril_condvar_broadcast(&fs_head_cv); … … 286 256 int vfs_grab_phone(fs_handle_t handle) 287 257 { 258 link_t *cur; 259 fs_info_t *fs; 288 260 int phone; 289 261 … … 296 268 */ 297 269 fibril_mutex_lock(&fs_head_lock); 298 link_t *cur;299 fs_info_t *fs;300 270 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 301 271 fs = list_get_instance(cur, fs_info_t, fs_link); 302 272 if (fs->fs_handle == handle) { 303 273 fibril_mutex_unlock(&fs_head_lock); 304 fibril_mutex_lock(&fs->phone_lock); 305 phone = ipc_connect_me_to(fs->phone, 0, 0, 0); 306 fibril_mutex_unlock(&fs->phone_lock); 274 phone = async_exchange_begin(&fs->session); 307 275 308 276 assert(phone > 0); … … 318 286 * @param phone Phone to FS task. 319 287 */ 320 void vfs_release_phone(int phone) 321 { 322 /* TODO: implement connection caching */ 323 ipc_hangup(phone); 288 void vfs_release_phone(fs_handle_t handle, int phone) 289 { 290 link_t *cur; 291 fs_info_t *fs; 292 293 fibril_mutex_lock(&fs_head_lock); 294 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 295 fs = list_get_instance(cur, fs_info_t, fs_link); 296 if (fs->fs_handle == handle) { 297 fibril_mutex_unlock(&fs_head_lock); 298 async_exchange_end(&fs->session, phone); 299 return; 300 } 301 } 302 /* should not really get here */ 303 abort(); 304 fibril_mutex_unlock(&fs_head_lock); 324 305 } 325 306 … … 351 332 } 352 333 334 /** Find the VFS info structure. 335 * 336 * @param handle FS handle for which the VFS info structure is sought. 337 * @return VFS info structure on success or NULL otherwise. 338 */ 339 vfs_info_t *fs_handle_to_info(fs_handle_t handle) 340 { 341 vfs_info_t *info = NULL; 342 link_t *cur; 343 344 fibril_mutex_lock(&fs_head_lock); 345 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) { 346 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link); 347 if (fs->fs_handle == handle) { 348 info = &fs->vfs_info; 349 break; 350 } 351 } 352 fibril_mutex_unlock(&fs_head_lock); 353 354 return info; 355 } 356 353 357 /** 354 358 * @}
Note:
See TracChangeset
for help on using the changeset viewer.