Changeset 1313ee9 in mainline
- Timestamp:
- 2009-12-13T15:17:08Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 963dd91
- Parents:
- fc6dd18
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
rfc6dd18 r1313ee9 100 100 if (s.is_file) 101 101 printf("%-40s\t%llu\n", name, (long long) s.size); 102 else if (s.is_directory) 103 printf("%-40s\t<dir>\n", name); 102 104 else 103 105 printf("%-40s\n", name); -
uspace/app/init/init.c
rfc6dd18 r1313ee9 58 58 { 59 59 char *opts = ""; 60 const char *root_dev = " initrd";60 const char *root_dev = "bd/initrd"; 61 61 62 62 if (str_cmp(fstype, "tmpfs") == 0) … … 97 97 } 98 98 99 snprintf(null, MAX_DEVICE_NAME, "null %d", null_id);99 snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id); 100 100 int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING); 101 101 … … 170 170 } 171 171 172 if ( texit != TASK_EXIT_NORMAL || retval != 0) {172 if ((texit != TASK_EXIT_NORMAL) || (retval != 0)) { 173 173 printf(NAME ": Server %s failed to start (returned %d)\n", 174 174 fname, retval); … … 206 206 int rc; 207 207 208 printf("Trying to mount disk0 on /data... ");208 printf("Trying to mount bd/disk0 on /data... "); 209 209 fflush(stdout); 210 210 211 rc = mount("fat", "/data", " disk0", "wtcache", 0);211 rc = mount("fat", "/data", "bd/disk0", "wtcache", 0); 212 212 if (rc == EOK) 213 213 printf("OK\n"); … … 256 256 #endif 257 257 258 getvc(" vc0", "/app/bdsh");259 getvc(" vc1", "/app/bdsh");260 getvc(" vc2", "/app/bdsh");261 getvc(" vc3", "/app/bdsh");262 getvc(" vc4", "/app/bdsh");263 getvc(" vc5", "/app/bdsh");264 getvc(" vc6", "/app/klog");258 getvc("term/vc0", "/app/bdsh"); 259 getvc("term/vc1", "/app/bdsh"); 260 getvc("term/vc2", "/app/bdsh"); 261 getvc("term/vc3", "/app/bdsh"); 262 getvc("term/vc4", "/app/bdsh"); 263 getvc("term/vc5", "/app/bdsh"); 264 getvc("term/vc6", "/app/klog"); 265 265 266 266 return 0; -
uspace/app/tester/vfs/vfs1.c
rfc6dd18 r1313ee9 85 85 return "Unable to create null device"; 86 86 87 snprintf(null, MAX_DEVICE_NAME, "null %d", null_id);87 snprintf(null, MAX_DEVICE_NAME, "null/%d", null_id); 88 88 int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS); 89 89 switch (rc) { -
uspace/lib/libc/generic/devmap.c
rfc6dd18 r1313ee9 35 35 #include <async.h> 36 36 #include <errno.h> 37 #include <malloc.h> 38 #include <bool.h> 37 39 38 40 static int devmap_phone_driver = -1; … … 105 107 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 106 108 107 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 108 109 ipcarg_t retval = async_data_write_start(phone, name, str_size(name)); 109 110 if (retval != EOK) { 110 111 async_wait_for(req, NULL); … … 126 127 /** Register new device. 127 128 * 128 * @param name Device name. 129 * @param handle Output: Handle to the created instance of device. 129 * @param namespace Namespace name. 130 * @param fqdn Fully qualified device name. 131 * @param handle Output: Handle to the created instance of device. 130 132 * 131 133 */ 132 int devmap_device_register(const char * name, dev_handle_t *handle)134 int devmap_device_register(const char *fqdn, dev_handle_t *handle) 133 135 { 134 136 int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING); … … 143 145 &answer); 144 146 145 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 146 147 ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 147 148 if (retval != EOK) { 148 149 async_wait_for(req, NULL); … … 167 168 } 168 169 169 int devmap_device_get_handle(const char * name, dev_handle_t *handle, unsigned int flags)170 int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags) 170 171 { 171 172 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); … … 180 181 &answer); 181 182 182 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 183 183 ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn)); 184 184 if (retval != EOK) { 185 185 async_wait_for(req, NULL); … … 202 202 203 203 return retval; 204 } 205 206 int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags) 207 { 208 int phone = devmap_get_phone(DEVMAP_CLIENT, flags); 209 210 if (phone < 0) 211 return phone; 212 213 async_serialize_start(); 214 215 ipc_call_t answer; 216 aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0, 217 &answer); 218 219 ipcarg_t retval = async_data_write_start(phone, name, str_size(name)); 220 if (retval != EOK) { 221 async_wait_for(req, NULL); 222 async_serialize_end(); 223 return retval; 224 } 225 226 async_wait_for(req, &retval); 227 228 async_serialize_end(); 229 230 if (retval != EOK) { 231 if (handle != NULL) 232 *handle = (dev_handle_t) -1; 233 return retval; 234 } 235 236 if (handle != NULL) 237 *handle = (dev_handle_t) IPC_GET_ARG1(answer); 238 239 return retval; 240 } 241 242 devmap_handle_type_t devmap_handle_probe(dev_handle_t handle) 243 { 244 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 245 246 if (phone < 0) 247 return phone; 248 249 ipcarg_t type; 250 int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type); 251 if (retval != EOK) 252 return DEV_HANDLE_NONE; 253 254 return (devmap_handle_type_t) type; 204 255 } 205 256 … … 227 278 228 279 ipcarg_t null_id; 229 int retval = async_req_0_1(phone, DEVMAP_ DEVICE_NULL_CREATE, &null_id);280 int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id); 230 281 if (retval != EOK) 231 282 return -1; … … 241 292 return; 242 293 243 async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id); 244 } 245 246 ipcarg_t devmap_device_get_count(void) 247 { 248 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 249 250 if (phone < 0) 251 return 0; 252 294 async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id); 295 } 296 297 static size_t devmap_count_namespaces_internal(int phone) 298 { 253 299 ipcarg_t count; 254 int retval = async_req_0_1(phone, DEVMAP_ DEVICE_GET_COUNT, &count);300 int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count); 255 301 if (retval != EOK) 256 302 return 0; … … 259 305 } 260 306 261 ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data) 262 { 263 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 264 265 if (phone < 0) 266 return 0; 267 268 async_serialize_start(); 269 270 ipc_call_t answer; 271 aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer); 272 273 ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t)); 274 275 if (retval != EOK) { 276 async_wait_for(req, NULL); 277 async_serialize_end(); 278 return 0; 279 } 280 281 async_wait_for(req, &retval); 282 283 async_serialize_end(); 284 307 static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle) 308 { 309 ipcarg_t count; 310 int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count); 285 311 if (retval != EOK) 286 312 return 0; 287 313 288 return IPC_GET_ARG1(answer); 289 } 314 return count; 315 } 316 317 size_t devmap_count_namespaces(void) 318 { 319 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 320 321 if (phone < 0) 322 return 0; 323 324 return devmap_count_namespaces_internal(phone); 325 } 326 327 size_t devmap_count_devices(dev_handle_t ns_handle) 328 { 329 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 330 331 if (phone < 0) 332 return 0; 333 334 return devmap_count_devices_internal(phone, ns_handle); 335 } 336 337 size_t devmap_get_namespaces(dev_desc_t **data) 338 { 339 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 340 341 if (phone < 0) 342 return 0; 343 344 /* Loop until namespaces read succesful */ 345 while (true) { 346 size_t count = devmap_count_namespaces_internal(phone); 347 if (count == 0) 348 return 0; 349 350 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t)); 351 if (devs == NULL) 352 return 0; 353 354 async_serialize_start(); 355 356 ipc_call_t answer; 357 aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer); 358 359 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 360 if (rc == EOVERFLOW) { 361 /* 362 * Number of namespaces has changed since 363 * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT 364 */ 365 async_serialize_end(); 366 free(devs); 367 continue; 368 } 369 370 if (rc != EOK) { 371 async_wait_for(req, NULL); 372 async_serialize_end(); 373 free(devs); 374 return 0; 375 } 376 377 ipcarg_t retval; 378 async_wait_for(req, &retval); 379 async_serialize_end(); 380 381 if (retval != EOK) 382 return 0; 383 384 *data = devs; 385 return count; 386 } 387 } 388 389 size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data) 390 { 391 int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING); 392 393 if (phone < 0) 394 return 0; 395 396 /* Loop until namespaces read succesful */ 397 while (true) { 398 size_t count = devmap_count_devices_internal(phone, ns_handle); 399 if (count == 0) 400 return 0; 401 402 dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t)); 403 if (devs == NULL) 404 return 0; 405 406 async_serialize_start(); 407 408 ipc_call_t answer; 409 aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer); 410 411 int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t)); 412 if (rc == EOVERFLOW) { 413 /* 414 * Number of devices has changed since 415 * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT 416 */ 417 async_serialize_end(); 418 free(devs); 419 continue; 420 } 421 422 if (rc != EOK) { 423 async_wait_for(req, NULL); 424 async_serialize_end(); 425 free(devs); 426 return 0; 427 } 428 429 ipcarg_t retval; 430 async_wait_for(req, &retval); 431 async_serialize_end(); 432 433 if (retval != EOK) 434 return 0; 435 436 *data = devs; 437 return count; 438 } 439 } -
uspace/lib/libc/generic/vfs/vfs.c
rfc6dd18 r1313ee9 117 117 } 118 118 119 int mount(const char *fs_name, const char *mp, const char * dev,119 int mount(const char *fs_name, const char *mp, const char *fqdn, 120 120 const char *opts, unsigned int flags) 121 121 { … … 126 126 dev_handle_t dev_handle; 127 127 128 res = devmap_device_get_handle( dev, &dev_handle, flags);128 res = devmap_device_get_handle(fqdn, &dev_handle, flags); 129 129 if (res != EOK) 130 130 return res; … … 703 703 rc = fstat(fildes, &stat); 704 704 705 if (!stat.dev fs_stat.device)705 if (!stat.device) 706 706 return -1; 707 707 708 return devmap_device_connect(stat.dev fs_stat.device, 0);708 return devmap_device_connect(stat.device, 0); 709 709 } 710 710 -
uspace/lib/libc/include/devmap.h
rfc6dd18 r1313ee9 38 38 #include <ipc/devmap.h> 39 39 #include <async.h> 40 #include <bool.h> 40 41 41 42 extern int devmap_get_phone(devmap_interface_t, unsigned int); … … 46 47 47 48 extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int); 49 extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int); 50 extern devmap_handle_type_t devmap_handle_probe(dev_handle_t); 51 48 52 extern int devmap_device_connect(dev_handle_t, unsigned int); 49 53 … … 51 55 extern void devmap_null_destroy(int); 52 56 53 extern ipcarg_t devmap_device_get_count(void); 54 extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *); 57 extern size_t devmap_count_namespaces(void); 58 extern size_t devmap_count_devices(dev_handle_t); 59 60 extern size_t devmap_get_namespaces(dev_desc_t **); 61 extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **); 55 62 56 63 #endif -
uspace/lib/libc/include/ipc/devmap.h
rfc6dd18 r1313ee9 43 43 44 44 typedef enum { 45 DEV_HANDLE_NONE, 46 DEV_HANDLE_NAMESPACE, 47 DEV_HANDLE_DEVICE 48 } devmap_handle_type_t; 49 50 typedef enum { 45 51 DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD, 46 52 DEVMAP_DRIVER_UNREGISTER, 47 53 DEVMAP_DEVICE_REGISTER, 48 54 DEVMAP_DEVICE_UNREGISTER, 49 DEVMAP_DEVICE_GET_NAME,50 55 DEVMAP_DEVICE_GET_HANDLE, 51 DEVMAP_DEVICE_NULL_CREATE, 52 DEVMAP_DEVICE_NULL_DESTROY, 53 DEVMAP_DEVICE_GET_COUNT, 54 DEVMAP_DEVICE_GET_DEVICES 56 DEVMAP_NAMESPACE_GET_HANDLE, 57 DEVMAP_HANDLE_PROBE, 58 DEVMAP_NULL_CREATE, 59 DEVMAP_NULL_DESTROY, 60 DEVMAP_GET_NAMESPACE_COUNT, 61 DEVMAP_GET_DEVICE_COUNT, 62 DEVMAP_GET_NAMESPACES, 63 DEVMAP_GET_DEVICES 55 64 } devmap_request_t; 56 65 -
uspace/lib/libc/include/sys/stat.h
rfc6dd18 r1313ee9 42 42 43 43 struct stat { 44 fs_handle_t fs_handle; 45 dev_handle_t dev_handle; 46 fs_index_t index; 47 unsigned lnkcnt; 48 bool is_file; 49 off_t size; 50 union { 51 struct { 52 dev_handle_t device; 53 } devfs_stat; 54 }; 44 fs_handle_t fs_handle; 45 dev_handle_t dev_handle; 46 fs_index_t index; 47 unsigned int lnkcnt; 48 bool is_file; 49 bool is_directory; 50 off_t size; 51 dev_handle_t device; 55 52 }; 56 53 -
uspace/lib/libfs/libfs.c
rfc6dd18 r1313ee9 1 1 /* 2 * Copyright (c) 2009 Jakub Jermar 2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libfs 29 /** @addtogroup libfs 30 30 * @{ 31 */ 31 */ 32 32 /** 33 33 * @file 34 * Glue code which is common od to all FS implementations.35 */ 36 37 #include "libfs.h" 34 * Glue code which is common to all FS implementations. 35 */ 36 37 #include "libfs.h" 38 38 #include "../../srv/vfs/vfs.h" 39 39 #include <errno.h> … … 67 67 * code. 68 68 * 69 * @param vfs_phone Open phone for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 72 * @param info VFS info structure supplied by the file system 73 * implementation. 74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 76 * 77 * @return EOK on success or a non-zero error code on errror. 69 * @param vfs_phone Open phone for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 72 * @param info VFS info structure supplied by the file system 73 * implementation. 74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 76 * 77 * @return EOK on success or a non-zero error code on errror. 78 * 78 79 */ 79 80 int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info, … … 87 88 ipc_call_t answer; 88 89 aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer); 89 90 90 91 /* 91 92 * Send our VFS info structure to VFS. … … 96 97 return rc; 97 98 } 98 99 99 100 /* 100 101 * Ask VFS for callback connection. 101 102 */ 102 103 ipc_connect_to_me(vfs_phone, 0, 0, 0, ®->vfs_phonehash); 103 104 104 105 /* 105 106 * Allocate piece of address space for PLB. … … 110 111 return ENOMEM; 111 112 } 112 113 113 114 /* 114 115 * Request sharing the Path Lookup Buffer with VFS. … … 136 137 */ 137 138 async_set_client_connection(conn); 138 139 139 140 return IPC_GET_RETVAL(answer); 140 141 } … … 154 155 int res; 155 156 ipcarg_t rc; 156 157 157 158 ipc_call_t call; 158 159 ipc_callid_t callid; 159 160 /* accept the phone */160 161 /* Accept the phone */ 161 162 callid = async_get_call(&call); 162 163 int mountee_phone = (int)IPC_GET_ARG1(call); 163 164 if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) || 164 mountee_phone < 0) {165 (mountee_phone < 0)) { 165 166 ipc_answer_0(callid, EINVAL); 166 167 ipc_answer_0(rid, EINVAL); 167 168 return; 168 169 } 169 ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */ 170 171 /* Acknowledge the mountee_phone */ 172 ipc_answer_0(callid, EOK); 170 173 171 174 res = async_data_write_receive(&callid, NULL); … … 176 179 return; 177 180 } 178 181 179 182 fs_node_t *fn; 180 183 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index); 181 if ( res != EOK || !fn) {184 if ((res != EOK) || (!fn)) { 182 185 ipc_hangup(mountee_phone); 183 186 ipc_answer_0(callid, combine_rc(res, ENOENT)); … … 185 188 return; 186 189 } 187 190 188 191 if (fn->mp_data.mp_active) { 189 192 ipc_hangup(mountee_phone); … … 193 196 return; 194 197 } 195 198 196 199 rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME); 197 200 if (rc != EOK) { … … 215 218 fn->mp_data.phone = mountee_phone; 216 219 } 220 217 221 /* 218 222 * Do not release the FS node so that it stays in memory. … … 238 242 ipc_call_t *request) 239 243 { 240 unsigned first = IPC_GET_ARG1(*request);241 unsigned last = IPC_GET_ARG2(*request);242 unsigned next = first;244 unsigned int first = IPC_GET_ARG1(*request); 245 unsigned int last = IPC_GET_ARG2(*request); 246 unsigned int next = first; 243 247 dev_handle_t dev_handle = IPC_GET_ARG3(*request); 244 248 int lflag = IPC_GET_ARG4(*request); 245 fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */249 fs_index_t index = IPC_GET_ARG5(*request); 246 250 char component[NAME_MAX + 1]; 247 251 int len; 248 252 int rc; 249 253 250 254 if (last < next) 251 255 last += PLB_SIZE; 252 256 253 257 fs_node_t *par = NULL; 254 258 fs_node_t *cur = NULL; 255 259 fs_node_t *tmp = NULL; 256 260 257 261 rc = ops->root_get(&cur, dev_handle); 258 262 on_error(rc, goto out_with_answer); 259 263 260 264 if (cur->mp_data.mp_active) { 261 265 ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP, … … 265 269 return; 266 270 } 267 271 272 /* Eat slash */ 268 273 if (ops->plb_get_char(next) == '/') 269 next++; /* eat slash */274 next++; 270 275 271 276 while (next <= last) { 272 277 bool has_children; 273 278 274 279 rc = ops->has_children(&has_children, cur); 275 280 on_error(rc, goto out_with_answer); 276 281 if (!has_children) 277 282 break; 278 279 /* collect the component */283 284 /* Collect the component */ 280 285 len = 0; 281 while ((next <= last) && 286 while ((next <= last) && (ops->plb_get_char(next) != '/')) { 282 287 if (len + 1 == NAME_MAX) { 283 /* component length overflow */288 /* Component length overflow */ 284 289 ipc_answer_0(rid, ENAMETOOLONG); 285 290 goto out; 286 291 } 287 292 component[len++] = ops->plb_get_char(next); 288 next++; /* process next character */ 293 /* Process next character */ 294 next++; 289 295 } 290 296 291 297 assert(len); 292 298 component[len] = '\0'; 293 next++; /* eat slash */ 294 295 /* match the component */ 299 /* Eat slash */ 300 next++; 301 302 /* Match the component */ 296 303 rc = ops->match(&tmp, cur, component); 297 304 on_error(rc, goto out_with_answer); 298 299 if ( tmp && tmp->mp_data.mp_active) {305 306 if ((tmp) && (tmp->mp_data.mp_active)) { 300 307 if (next > last) 301 308 next = last = first; 302 309 else 303 310 next--; 304 311 305 312 ipc_forward_slow(rid, tmp->mp_data.phone, 306 313 VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle, … … 312 319 return; 313 320 } 314 315 /* handle miss: match amongst siblings */321 322 /* Handle miss: match amongst siblings */ 316 323 if (!tmp) { 317 324 if (next <= last) { 318 /* there are unprocessed components */325 /* There are unprocessed components */ 319 326 ipc_answer_0(rid, ENOENT); 320 327 goto out; 321 328 } 322 /* miss in the last component */ 323 if (lflag & (L_CREATE | L_LINK)) { 324 /* request to create a new link */ 329 330 /* Miss in the last component */ 331 if (lflag & (L_CREATE | L_LINK)) { 332 /* Request to create a new link */ 325 333 if (!ops->is_directory(cur)) { 326 334 ipc_answer_0(rid, ENOTDIR); 327 335 goto out; 328 336 } 337 329 338 fs_node_t *fn; 330 339 if (lflag & L_CREATE) … … 335 344 index); 336 345 on_error(rc, goto out_with_answer); 346 337 347 if (fn) { 338 348 rc = ops->link(cur, fn, component); … … 349 359 (void) ops->node_put(fn); 350 360 } 351 } else {361 } else 352 362 ipc_answer_0(rid, ENOSPC); 353 }363 354 364 goto out; 355 } 365 } 366 356 367 ipc_answer_0(rid, ENOENT); 357 368 goto out; 358 369 } 359 370 360 371 if (par) { 361 372 rc = ops->node_put(par); 362 373 on_error(rc, goto out_with_answer); 363 374 } 364 365 /* descend one level */375 376 /* Descend one level */ 366 377 par = cur; 367 378 cur = tmp; 368 379 tmp = NULL; 369 380 } 370 371 /* handle miss: excessive components */381 382 /* Handle miss: excessive components */ 372 383 if (next <= last) { 373 384 bool has_children; 374 375 385 rc = ops->has_children(&has_children, cur); 376 386 on_error(rc, goto out_with_answer); 387 377 388 if (has_children) 378 389 goto skip_miss; 379 390 380 391 if (lflag & (L_CREATE | L_LINK)) { 381 392 if (!ops->is_directory(cur)) { … … 383 394 goto out; 384 395 } 385 386 /* collect next component */396 397 /* Collect next component */ 387 398 len = 0; 388 399 while (next <= last) { 389 400 if (ops->plb_get_char(next) == '/') { 390 /* more than one component */401 /* More than one component */ 391 402 ipc_answer_0(rid, ENOENT); 392 403 goto out; 393 404 } 405 394 406 if (len + 1 == NAME_MAX) { 395 /* component length overflow */407 /* Component length overflow */ 396 408 ipc_answer_0(rid, ENAMETOOLONG); 397 409 goto out; 398 410 } 411 399 412 component[len++] = ops->plb_get_char(next); 400 next++; /* process next character */ 413 /* Process next character */ 414 next++; 401 415 } 416 402 417 assert(len); 403 418 component[len] = '\0'; 404 419 405 420 fs_node_t *fn; 406 421 if (lflag & L_CREATE) … … 409 424 rc = ops->node_get(&fn, dev_handle, index); 410 425 on_error(rc, goto out_with_answer); 426 411 427 if (fn) { 412 428 rc = ops->link(cur, fn, component); … … 423 439 (void) ops->node_put(fn); 424 440 } 425 } else {441 } else 426 442 ipc_answer_0(rid, ENOSPC); 427 }443 428 444 goto out; 429 445 } 446 430 447 ipc_answer_0(rid, ENOENT); 431 448 goto out; 432 449 } 450 433 451 skip_miss: 434 435 /* handle hit */452 453 /* Handle hit */ 436 454 if (lflag & L_UNLINK) { 437 unsigned old_lnkcnt = ops->lnkcnt_get(cur);455 unsigned int old_lnkcnt = ops->lnkcnt_get(cur); 438 456 rc = ops->unlink(par, cur, component); 439 ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,457 ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle, 440 458 ops->index_get(cur), ops->size_get(cur), old_lnkcnt); 441 459 goto out; 442 460 } 461 443 462 if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) || 444 463 (lflag & L_LINK)) { … … 446 465 goto out; 447 466 } 467 448 468 if ((lflag & L_FILE) && (ops->is_directory(cur))) { 449 469 ipc_answer_0(rid, EISDIR); 450 470 goto out; 451 471 } 472 452 473 if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) { 453 474 ipc_answer_0(rid, ENOTDIR); 454 475 goto out; 455 476 } 456 477 457 478 out_with_answer: 479 458 480 if (rc == EOK) { 459 ipc_answer_5(rid, EOK, fs_handle, dev_handle, 481 if (lflag & L_OPEN) 482 rc = ops->node_open(cur); 483 484 ipc_answer_5(rid, rc, fs_handle, dev_handle, 460 485 ops->index_get(cur), ops->size_get(cur), 461 486 ops->lnkcnt_get(cur)); 462 } else {487 } else 463 488 ipc_answer_0(rid, rc); 464 } 465 489 466 490 out: 491 467 492 if (par) 468 493 (void) ops->node_put(par); 494 469 495 if (cur) 470 496 (void) ops->node_put(cur); 497 471 498 if (tmp) 472 499 (void) ops->node_put(tmp); … … 478 505 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 479 506 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 507 480 508 fs_node_t *fn; 481 int rc; 482 483 rc = ops->node_get(&fn, dev_handle, index); 509 int rc = ops->node_get(&fn, dev_handle, index); 484 510 on_error(rc, answer_and_return(rid, rc)); 485 511 486 512 ipc_callid_t callid; 487 513 size_t size; 488 if (!async_data_read_receive(&callid, &size) || 489 size != sizeof(struct stat)) { 514 if ((!async_data_read_receive(&callid, &size)) || 515 (size != sizeof(struct stat))) { 516 ops->node_put(fn); 490 517 ipc_answer_0(callid, EINVAL); 491 518 ipc_answer_0(rid, EINVAL); 492 519 return; 493 520 } 494 521 495 522 struct stat stat; 496 523 memset(&stat, 0, sizeof(struct stat)); … … 499 526 stat.dev_handle = dev_handle; 500 527 stat.index = index; 501 stat.lnkcnt = ops->lnkcnt_get(fn); 528 stat.lnkcnt = ops->lnkcnt_get(fn); 502 529 stat.is_file = ops->is_file(fn); 530 stat.is_directory = ops->is_directory(fn); 503 531 stat.size = ops->size_get(fn); 504 532 stat.device = ops->device_get(fn); 533 534 ops->node_put(fn); 535 505 536 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 506 537 ipc_answer_0(rid, EOK); … … 509 540 /** Open VFS triplet. 510 541 * 511 * @param ops 512 * 513 * @param rid 514 * @param request 542 * @param ops libfs operations structure with function pointers to 543 * file system implementation 544 * @param rid Request ID of the VFS_OUT_OPEN_NODE request. 545 * @param request VFS_OUT_OPEN_NODE request data itself. 515 546 * 516 547 */ … … 531 562 } 532 563 533 ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn), 564 rc = ops->node_open(fn); 565 ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn), 534 566 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 535 567 -
uspace/lib/libfs/libfs.h
rfc6dd18 r1313ee9 64 64 int (* match)(fs_node_t **, fs_node_t *, const char *); 65 65 int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t); 66 int (* node_open)(fs_node_t *); 66 67 int (* node_put)(fs_node_t *); 67 68 int (* create)(fs_node_t **, dev_handle_t, int); … … 76 77 fs_index_t (* index_get)(fs_node_t *); 77 78 size_t (* size_get)(fs_node_t *); 78 unsigned (* lnkcnt_get)(fs_node_t *);79 unsigned int (* lnkcnt_get)(fs_node_t *); 79 80 char (* plb_get_char)(unsigned pos); 80 81 bool (* is_directory)(fs_node_t *); 81 82 bool (* is_file)(fs_node_t *); 83 dev_handle_t (* device_get)(fs_node_t *); 82 84 } libfs_ops_t; 83 85 -
uspace/srv/bd/ata_bd/ata_bd.c
rfc6dd18 r1313ee9 66 66 #include "ata_bd.h" 67 67 68 #define NAME "ata_bd" 68 #define NAME "ata_bd" 69 #define NAMESPACE "bd" 69 70 70 71 /** Physical block size. Should be always 512. */ … … 135 136 if (disk[i].present == false) 136 137 continue; 137 138 snprintf(name, 16, " disk%d", i);138 139 snprintf(name, 16, "%s/disk%d", NAMESPACE, i); 139 140 rc = devmap_device_register(name, &disk[i].dev_handle); 140 141 if (rc != EOK) { 141 142 devmap_hangup_phone(DEVMAP_DRIVER); 142 printf(NAME ": Unable to register device %s.\n", 143 name); 143 printf(NAME ": Unable to register device %s.\n", name); 144 144 return rc; 145 145 } -
uspace/srv/bd/gxe_bd/gxe_bd.c
rfc6dd18 r1313ee9 50 50 #include <task.h> 51 51 52 #define NAME "gxe_bd" 52 #define NAME "gxe_bd" 53 #define NAMESPACE "bd" 53 54 54 55 enum { … … 141 142 142 143 for (i = 0; i < MAX_DISKS; i++) { 143 snprintf(name, 16, " disk%d", i);144 snprintf(name, 16, "%s/disk%d", NAMESPACE, i); 144 145 rc = devmap_device_register(name, &dev_handle[i]); 145 146 if (rc != EOK) { 146 147 devmap_hangup_phone(DEVMAP_DRIVER); 147 printf(NAME ": Unable to register device %s.\n", 148 name); 148 printf(NAME ": Unable to register device %s.\n", name); 149 149 return rc; 150 150 } -
uspace/srv/bd/rd/rd.c
rfc6dd18 r1313ee9 228 228 229 229 dev_handle_t dev_handle; 230 if (devmap_device_register(" initrd", &dev_handle) != EOK) {230 if (devmap_device_register("bd/initrd", &dev_handle) != EOK) { 231 231 devmap_hangup_phone(DEVMAP_DRIVER); 232 232 printf(NAME ": Unable to register device\n"); -
uspace/srv/console/console.c
rfc6dd18 r1313ee9 57 57 #include "screenbuffer.h" 58 58 59 #define NAME "console" 60 61 #define MAX_DEVICE_NAME 32 59 #define NAME "console" 60 #define NAMESPACE "term" 62 61 63 62 /** Phone to the keyboard driver. */ … … 69 68 ipcarg_t cols; /**< Framebuffer columns */ 70 69 ipcarg_t rows; /**< Framebuffer rows */ 71 int color_cap; 70 int color_cap; /**< Color capabilities (FB_CCAP_xxx) */ 72 71 } fb_info; 73 72 … … 740 739 consoles[i].refcount = 0; 741 740 742 char vc[ MAX_DEVICE_NAME];743 snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);741 char vc[DEVMAP_NAME_MAXLEN + 1]; 742 snprintf(vc, DEVMAP_NAME_MAXLEN, "%s/vc%u", NAMESPACE, i); 744 743 745 744 if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) { -
uspace/srv/devmap/devmap.c
rfc6dd18 r1313ee9 68 68 } devmap_driver_t; 69 69 70 /** Info about registered namespaces 71 * 72 */ 73 typedef struct { 74 /** Pointer to the previous and next device in the list of all namespaces */ 75 link_t namespaces; 76 /** Unique namespace identifier */ 77 dev_handle_t handle; 78 /** Namespace name */ 79 char *name; 80 /** Reference count */ 81 size_t refcnt; 82 } devmap_namespace_t; 83 70 84 /** Info about registered device 71 85 * … … 77 91 owned by one driver */ 78 92 link_t driver_devices; 79 /** Unique device identifier 93 /** Unique device identifier */ 80 94 dev_handle_t handle; 95 /** Device namespace */ 96 devmap_namespace_t *namespace; 81 97 /** Device name */ 82 98 char *name; … … 86 102 87 103 LIST_INITIALIZE(devices_list); 104 LIST_INITIALIZE(namespaces_list); 88 105 LIST_INITIALIZE(drivers_list); 89 106 … … 117 134 } 118 135 136 /** Convert fully qualified device name to namespace and device name. 137 * 138 * A fully qualified device name can be either a plain device name 139 * (then the namespace is considered to be an empty string) or consist 140 * of two components separated by a slash. No more than one slash 141 * is allowed. 142 * 143 */ 144 static bool devmap_fqdn_split(const char *fqdn, char **ns_name, char **name) 145 { 146 size_t cnt = 0; 147 size_t slash_offset = 0; 148 size_t slash_after = 0; 149 150 size_t offset = 0; 151 size_t offset_prev = 0; 152 wchar_t c; 153 154 while ((c = str_decode(fqdn, &offset, STR_NO_LIMIT)) != 0) { 155 if (c == '/') { 156 cnt++; 157 slash_offset = offset_prev; 158 slash_after = offset; 159 } 160 offset_prev = offset; 161 } 162 163 /* More than one slash */ 164 if (cnt > 1) 165 return false; 166 167 /* No slash -> namespace is empty */ 168 if (cnt == 0) { 169 *ns_name = str_dup(""); 170 if (*ns_name == NULL) 171 return false; 172 173 *name = str_dup(fqdn); 174 if ((*name == NULL) || (str_cmp(*name, "") == 0)) { 175 free(*ns_name); 176 return false; 177 } 178 179 return true; 180 } 181 182 /* Exactly one slash */ 183 *ns_name = str_ndup(fqdn, slash_offset); 184 if (*ns_name == NULL) 185 return false; 186 187 *name = str_dup(fqdn + slash_after); 188 if ((*name == NULL) || (str_cmp(*name, "") == 0)) { 189 free(*ns_name); 190 return false; 191 } 192 193 return true; 194 } 195 196 /** Find namespace with given name. 197 * 198 * The devices_list_mutex should be already held when 199 * calling this function. 200 * 201 */ 202 static devmap_namespace_t *devmap_namespace_find_name(const char *name) 203 { 204 link_t *item = namespaces_list.next; 205 206 while (item != &namespaces_list) { 207 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 208 if (str_cmp(namespace->name, name) == 0) 209 return namespace; 210 item = item->next; 211 } 212 213 return NULL; 214 } 215 216 /** Find namespace with given handle. 217 * 218 * The devices_list_mutex should be already held when 219 * calling this function. 220 * 221 * @todo: use hash table 222 * 223 */ 224 static devmap_namespace_t *devmap_namespace_find_handle(dev_handle_t handle) 225 { 226 link_t *item = namespaces_list.next; 227 228 while (item != &namespaces_list) { 229 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 230 if (namespace->handle == handle) 231 return namespace; 232 233 item = item->next; 234 } 235 236 return NULL; 237 } 238 119 239 /** Find device with given name. 120 240 * 121 */ 122 static devmap_device_t *devmap_device_find_name(const char *name) 241 * The devices_list_mutex should be already held when 242 * calling this function. 243 * 244 */ 245 static devmap_device_t *devmap_device_find_name(const char *ns_name, 246 const char *name) 123 247 { 124 248 link_t *item = devices_list.next; 125 devmap_device_t *device = NULL;126 249 127 250 while (item != &devices_list) { 128 dev ice = list_get_instance(item, devmap_device_t, devices);129 if ( str_cmp(device->name, name) == 0)130 break;251 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 252 if ((str_cmp(device->namespace->name, ns_name) == 0) && (str_cmp(device->name, name) == 0)) 253 return device; 131 254 item = item->next; 132 255 } 133 256 134 if (item == &devices_list) 257 return NULL; 258 } 259 260 /** Find device with given handle. 261 * 262 * The devices_list_mutex should be already held when 263 * calling this function. 264 * 265 * @todo: use hash table 266 * 267 */ 268 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle) 269 { 270 link_t *item = devices_list.next; 271 272 while (item != &devices_list) { 273 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 274 if (device->handle == handle) 275 return device; 276 277 item = item->next; 278 } 279 280 return NULL; 281 } 282 283 /** Create a namespace (if not already present) 284 * 285 * The devices_list_mutex should be already held when 286 * calling this function. 287 * 288 */ 289 static devmap_namespace_t *devmap_namespace_create(const char *ns_name) 290 { 291 devmap_namespace_t *namespace = devmap_namespace_find_name(ns_name); 292 if (namespace != NULL) 293 return namespace; 294 295 namespace = (devmap_namespace_t *) malloc(sizeof(devmap_namespace_t)); 296 if (namespace == NULL) 135 297 return NULL; 136 298 137 device = list_get_instance(item, devmap_device_t, devices); 138 return device; 139 } 140 141 /** Find device with given handle. 142 * 143 * @todo: use hash table 144 * 145 */ 146 static devmap_device_t *devmap_device_find_handle(dev_handle_t handle) 147 { 148 fibril_mutex_lock(&devices_list_mutex); 149 150 link_t *item = (&devices_list)->next; 151 devmap_device_t *device = NULL; 152 153 while (item != &devices_list) { 154 device = list_get_instance(item, devmap_device_t, devices); 155 if (device->handle == handle) 156 break; 157 item = item->next; 158 } 159 160 if (item == &devices_list) { 161 fibril_mutex_unlock(&devices_list_mutex); 299 namespace->name = str_dup(ns_name); 300 if (namespace->name == NULL) { 301 free(namespace); 162 302 return NULL; 163 303 } 164 304 165 device = list_get_instance(item, devmap_device_t, devices); 166 167 fibril_mutex_unlock(&devices_list_mutex); 168 169 return device; 170 } 171 172 /** 173 * Unregister device and free it. It's assumed that driver's device list is 174 * already locked. 175 */ 176 static int devmap_device_unregister_core(devmap_device_t *device) 177 { 305 namespace->handle = devmap_create_handle(); 306 namespace->refcnt = 0; 307 308 /* 309 * Insert new namespace into list of registered namespaces 310 */ 311 list_append(&(namespace->namespaces), &namespaces_list); 312 313 return namespace; 314 } 315 316 /** Destroy a namespace (if it is no longer needed) 317 * 318 * The devices_list_mutex should be already held when 319 * calling this function. 320 * 321 */ 322 static void devmap_namespace_destroy(devmap_namespace_t *namespace) 323 { 324 if (namespace->refcnt == 0) { 325 list_remove(&(namespace->namespaces)); 326 327 free(namespace->name); 328 free(namespace); 329 } 330 } 331 332 /** Increase namespace reference count by including device 333 * 334 * The devices_list_mutex should be already held when 335 * calling this function. 336 * 337 */ 338 static void devmap_namespace_addref(devmap_namespace_t *namespace, 339 devmap_device_t *device) 340 { 341 device->namespace = namespace; 342 namespace->refcnt++; 343 } 344 345 /** Decrease namespace reference count 346 * 347 * The devices_list_mutex should be already held when 348 * calling this function. 349 * 350 */ 351 static void devmap_namespace_delref(devmap_namespace_t *namespace) 352 { 353 namespace->refcnt--; 354 devmap_namespace_destroy(namespace); 355 } 356 357 /** Unregister device and free it 358 * 359 * The devices_list_mutex should be already held when 360 * calling this function. 361 * 362 */ 363 static void devmap_device_unregister_core(devmap_device_t *device) 364 { 365 devmap_namespace_delref(device->namespace); 178 366 list_remove(&(device->devices)); 179 367 list_remove(&(device->driver_devices)); 180 368 369 free(device->namespace); 181 370 free(device->name); 182 371 free(device); 183 184 return EOK;185 372 } 186 373 … … 189 376 * drivers. 190 377 */ 191 static void devmap_driver_register(devmap_driver_t **odriver) 192 { 193 *odriver = NULL; 194 378 static devmap_driver_t *devmap_driver_register(void) 379 { 195 380 ipc_call_t icall; 196 381 ipc_callid_t iid = async_get_call(&icall); … … 198 383 if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) { 199 384 ipc_answer_0(iid, EREFUSED); 200 return ;385 return NULL; 201 386 } 202 387 … … 205 390 if (driver == NULL) { 206 391 ipc_answer_0(iid, ENOMEM); 207 return ;392 return NULL; 208 393 } 209 394 … … 211 396 * Get driver name 212 397 */ 213 ipc_callid_t callid; 214 size_t name_size; 215 if (!async_data_write_receive(&callid, &name_size)) { 398 int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN); 399 if (rc != EOK) { 216 400 free(driver); 217 ipc_answer_0(callid, EREFUSED); 218 ipc_answer_0(iid, EREFUSED); 219 return; 220 } 221 222 if (name_size > DEVMAP_NAME_MAXLEN) { 223 free(driver); 224 ipc_answer_0(callid, EINVAL); 225 ipc_answer_0(iid, EREFUSED); 226 return; 227 } 228 229 /* 230 * Allocate buffer for device name. 231 */ 232 driver->name = (char *) malloc(name_size + 1); 233 if (driver->name == NULL) { 234 free(driver); 235 ipc_answer_0(callid, ENOMEM); 236 ipc_answer_0(iid, EREFUSED); 237 return; 238 } 239 240 /* 241 * Send confirmation to sender and get data into buffer. 242 */ 243 if (async_data_write_finalize(callid, driver->name, name_size) != EOK) { 244 free(driver->name); 245 free(driver); 246 ipc_answer_0(iid, EREFUSED); 247 return; 248 } 249 250 driver->name[name_size] = 0; 401 ipc_answer_0(iid, rc); 402 return NULL; 403 } 251 404 252 405 /* Initialize mutex for list of devices owned by this driver */ … … 262 415 */ 263 416 ipc_call_t call; 264 callid = async_get_call(&call);417 ipc_callid_t callid = async_get_call(&call); 265 418 266 419 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { … … 270 423 free(driver); 271 424 ipc_answer_0(iid, ENOTSUP); 272 return ;425 return NULL; 273 426 } 274 427 … … 293 446 ipc_answer_0(iid, EOK); 294 447 295 *odriver =driver;448 return driver; 296 449 } 297 450 … … 355 508 } 356 509 357 /* Get device name*/358 ipc_callid_t callid;359 size_t size;360 if ( !async_data_write_receive(&callid, &size)) {510 /* Get fqdn */ 511 char *fqdn; 512 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 513 if (rc != EOK) { 361 514 free(device); 362 ipc_answer_0(iid, EREFUSED); 363 return; 364 } 365 366 if (size > DEVMAP_NAME_MAXLEN) { 515 ipc_answer_0(iid, rc); 516 return; 517 } 518 519 char *ns_name; 520 if (!devmap_fqdn_split(fqdn, &ns_name, &device->name)) { 521 free(fqdn); 367 522 free(device); 368 ipc_answer_0(callid, EINVAL); 369 ipc_answer_0(iid, EREFUSED); 370 return; 371 } 372 373 /* +1 for terminating \0 */ 374 device->name = (char *) malloc(size + 1); 375 376 if (device->name == NULL) { 523 ipc_answer_0(iid, EINVAL); 524 return; 525 } 526 527 free(fqdn); 528 529 fibril_mutex_lock(&devices_list_mutex); 530 531 devmap_namespace_t *namespace = devmap_namespace_create(ns_name); 532 free(ns_name); 533 if (!namespace) { 534 fibril_mutex_unlock(&devices_list_mutex); 377 535 free(device); 378 ipc_answer_0(callid, ENOMEM); 379 ipc_answer_0(iid, EREFUSED); 380 return; 381 } 382 383 async_data_write_finalize(callid, device->name, size); 384 device->name[size] = 0; 536 ipc_answer_0(iid, ENOMEM); 537 return; 538 } 385 539 386 540 list_initialize(&(device->devices)); 387 541 list_initialize(&(device->driver_devices)); 388 542 389 fibril_mutex_lock(&devices_list_mutex); 390 391 /* Check that device with such name is not already registered */ 392 if (NULL != devmap_device_find_name(device->name)) { 393 printf(NAME ": Device '%s' already registered\n", device->name); 543 /* Check that device is not already registered */ 544 if (devmap_device_find_name(namespace->name, device->name) != NULL) { 545 printf(NAME ": Device '%s/%s' already registered\n", device->namespace, device->name); 546 devmap_namespace_destroy(namespace); 394 547 fibril_mutex_unlock(&devices_list_mutex); 548 free(device->namespace); 395 549 free(device->name); 396 550 free(device); … … 402 556 device->handle = devmap_create_handle(); 403 557 558 devmap_namespace_addref(namespace, device); 404 559 device->driver = driver; 405 560 … … 437 592 static void devmap_forward(ipc_callid_t callid, ipc_call_t *call) 438 593 { 594 fibril_mutex_lock(&devices_list_mutex); 595 439 596 /* 440 597 * Get handle from request … … 450 607 ipc_forward_fast(callid, dev->driver->phone, dev->handle, 451 608 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 609 610 fibril_mutex_unlock(&devices_list_mutex); 452 611 } 453 612 … … 458 617 * 459 618 */ 460 static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall) 461 { 462 /* 463 * Wait for incoming message with device name (but do not 464 * read the name itself until the buffer is allocated). 465 */ 466 ipc_callid_t callid; 467 size_t size; 468 if (!async_data_write_receive(&callid, &size)) { 469 ipc_answer_0(callid, EREFUSED); 470 ipc_answer_0(iid, EREFUSED); 471 return; 472 } 473 474 if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) { 475 ipc_answer_0(callid, EINVAL); 476 ipc_answer_0(iid, EREFUSED); 477 return; 478 } 479 480 /* 481 * Allocate buffer for device name. 482 */ 483 char *name = (char *) malloc(size + 1); 484 if (name == NULL) { 485 ipc_answer_0(callid, ENOMEM); 486 ipc_answer_0(iid, EREFUSED); 487 return; 488 } 489 490 /* 491 * Send confirmation to sender and get data into buffer. 492 */ 493 ipcarg_t retval = async_data_write_finalize(callid, name, size); 494 if (retval != EOK) { 495 ipc_answer_0(iid, EREFUSED); 496 free(name); 497 return; 498 } 499 name[size] = '\0'; 619 static void devmap_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 620 { 621 char *fqdn; 622 623 /* Get fqdn */ 624 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 625 if (rc != EOK) { 626 ipc_answer_0(iid, rc); 627 return; 628 } 629 630 char *ns_name; 631 char *name; 632 if (!devmap_fqdn_split(fqdn, &ns_name, &name)) { 633 free(fqdn); 634 ipc_answer_0(iid, EINVAL); 635 return; 636 } 637 638 free(fqdn); 500 639 501 640 fibril_mutex_lock(&devices_list_mutex); 502 641 const devmap_device_t *dev; 642 503 643 recheck: 504 644 505 645 /* 506 646 * Find device name in the list of known devices. 507 647 */ 508 dev = devmap_device_find_name(n ame);648 dev = devmap_device_find_name(ns_name, name); 509 649 510 650 /* … … 520 660 521 661 ipc_answer_0(iid, ENOENT); 662 free(ns_name); 522 663 free(name); 523 664 fibril_mutex_unlock(&devices_list_mutex); … … 527 668 528 669 ipc_answer_1(iid, EOK, dev->handle); 670 free(ns_name); 529 671 free(name); 530 672 } 531 673 532 /** Find name of device identified by id and send it to caller. 533 * 534 */ 535 static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) 536 { 537 const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall)); 674 /** Find handle for namespace identified by name. 675 * 676 * In answer will be send EOK and device handle in arg1 or a error 677 * code from errno.h. 678 * 679 */ 680 static void devmap_namespace_get_handle(ipc_callid_t iid, ipc_call_t *icall) 681 { 682 char *name; 683 684 /* Get device name */ 685 int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN); 686 if (rc != EOK) { 687 ipc_answer_0(iid, rc); 688 return; 689 } 690 691 fibril_mutex_lock(&devices_list_mutex); 692 const devmap_namespace_t *namespace; 693 694 recheck: 538 695 539 696 /* 540 * Device not found.697 * Find namespace name in the list of known namespaces. 541 698 */ 542 if (device == NULL) { 699 namespace = devmap_namespace_find_name(name); 700 701 /* 702 * Namespace was not found. 703 */ 704 if (namespace == NULL) { 705 if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { 706 /* Blocking lookup */ 707 fibril_condvar_wait(&devices_list_cv, 708 &devices_list_mutex); 709 goto recheck; 710 } 711 543 712 ipc_answer_0(iid, ENOENT); 544 return; 545 } 546 547 ipc_answer_0(iid, EOK); 548 549 /* FIXME: 550 * We have no channel from DEVMAP to client, therefore 551 * sending must be initiated by client. 552 * 553 * size_t name_size = str_size(device->name); 554 * 555 * int rc = async_data_write_send(phone, device->name, name_size); 556 * if (rc != EOK) { 557 * async_wait_for(req, NULL); 558 * return rc; 559 * } 560 */ 561 562 /* TODO: send name in response */ 563 } 564 565 static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall) 713 free(name); 714 fibril_mutex_unlock(&devices_list_mutex); 715 return; 716 } 717 fibril_mutex_unlock(&devices_list_mutex); 718 719 ipc_answer_1(iid, EOK, namespace->handle); 720 free(name); 721 } 722 723 static void devmap_handle_probe(ipc_callid_t iid, ipc_call_t *icall) 566 724 { 567 725 fibril_mutex_lock(&devices_list_mutex); 568 ipc_answer_1(iid, EOK, list_count(&devices_list)); 726 727 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 728 if (namespace == NULL) { 729 devmap_device_t *dev = devmap_device_find_handle(IPC_GET_ARG1(*icall)); 730 if (dev == NULL) 731 ipc_answer_1(iid, EOK, DEV_HANDLE_NONE); 732 else 733 ipc_answer_1(iid, EOK, DEV_HANDLE_DEVICE); 734 } else 735 ipc_answer_1(iid, EOK, DEV_HANDLE_NAMESPACE); 736 569 737 fibril_mutex_unlock(&devices_list_mutex); 570 738 } 571 739 572 static void devmap_get_ devices(ipc_callid_t iid, ipc_call_t *icall)740 static void devmap_get_namespace_count(ipc_callid_t iid, ipc_call_t *icall) 573 741 { 574 742 fibril_mutex_lock(&devices_list_mutex); 575 743 ipc_answer_1(iid, EOK, list_count(&namespaces_list)); 744 fibril_mutex_unlock(&devices_list_mutex); 745 } 746 747 static void devmap_get_device_count(ipc_callid_t iid, ipc_call_t *icall) 748 { 749 fibril_mutex_lock(&devices_list_mutex); 750 751 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 752 if (namespace == NULL) 753 ipc_answer_0(iid, EEXISTS); 754 else 755 ipc_answer_1(iid, EOK, namespace->refcnt); 756 757 fibril_mutex_unlock(&devices_list_mutex); 758 } 759 760 static void devmap_get_namespaces(ipc_callid_t iid, ipc_call_t *icall) 761 { 576 762 ipc_callid_t callid; 577 763 size_t size; … … 584 770 if ((size % sizeof(dev_desc_t)) != 0) { 585 771 ipc_answer_0(callid, EINVAL); 772 ipc_answer_0(iid, EINVAL); 773 return; 774 } 775 776 fibril_mutex_lock(&devices_list_mutex); 777 778 size_t count = size / sizeof(dev_desc_t); 779 if (count != list_count(&namespaces_list)) { 780 ipc_answer_0(callid, EOVERFLOW); 781 ipc_answer_0(iid, EOVERFLOW); 782 return; 783 } 784 785 dev_desc_t *desc = (dev_desc_t *) malloc(size); 786 if (desc == NULL) { 787 ipc_answer_0(callid, ENOMEM); 788 ipc_answer_0(iid, ENOMEM); 789 return; 790 } 791 792 link_t *item = namespaces_list.next; 793 size_t pos = 0; 794 while (item != &namespaces_list) { 795 devmap_namespace_t *namespace = list_get_instance(item, devmap_namespace_t, namespaces); 796 797 desc[pos].handle = namespace->handle; 798 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, namespace->name); 799 pos++; 800 801 item = item->next; 802 } 803 804 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 805 806 free(desc); 807 fibril_mutex_unlock(&devices_list_mutex); 808 809 ipc_answer_0(iid, retval); 810 } 811 812 static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall) 813 { 814 /* FIXME: Use faster algorithm which can make better use 815 of namespaces */ 816 817 ipc_callid_t callid; 818 size_t size; 819 if (!async_data_read_receive(&callid, &size)) { 820 ipc_answer_0(callid, EREFUSED); 586 821 ipc_answer_0(iid, EREFUSED); 587 822 return; 588 823 } 589 824 825 if ((size % sizeof(dev_desc_t)) != 0) { 826 ipc_answer_0(callid, EINVAL); 827 ipc_answer_0(iid, EINVAL); 828 return; 829 } 830 831 fibril_mutex_lock(&devices_list_mutex); 832 833 devmap_namespace_t *namespace = devmap_namespace_find_handle(IPC_GET_ARG1(*icall)); 834 if (namespace == NULL) { 835 fibril_mutex_unlock(&devices_list_mutex); 836 ipc_answer_0(callid, ENOENT); 837 ipc_answer_0(iid, ENOENT); 838 return; 839 } 840 590 841 size_t count = size / sizeof(dev_desc_t); 842 if (count != namespace->refcnt) { 843 ipc_answer_0(callid, EOVERFLOW); 844 ipc_answer_0(iid, EOVERFLOW); 845 return; 846 } 847 591 848 dev_desc_t *desc = (dev_desc_t *) malloc(size); 592 849 if (desc == NULL) { … … 596 853 } 597 854 855 link_t *item = devices_list.next; 598 856 size_t pos = 0; 599 link_t *item = devices_list.next; 600 601 while ((item != &devices_list) && (pos < count)) { 857 while (item != &devices_list) { 602 858 devmap_device_t *device = list_get_instance(item, devmap_device_t, devices); 603 859 604 desc[pos].handle = device->handle; 605 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 606 pos++; 860 if (device->namespace == namespace) { 861 desc[pos].handle = device->handle; 862 str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name); 863 pos++; 864 } 865 607 866 item = item->next; 608 867 } 609 868 610 ipcarg_t retval = async_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t)); 611 if (retval != EOK) { 612 ipc_answer_0(iid, EREFUSED); 613 free(desc); 614 return; 615 } 869 ipcarg_t retval = async_data_read_finalize(callid, desc, size); 616 870 617 871 free(desc); 618 619 872 fibril_mutex_unlock(&devices_list_mutex); 620 873 621 ipc_answer_ 1(iid, EOK, pos);874 ipc_answer_0(iid, retval); 622 875 } 623 876 … … 642 895 } 643 896 644 /* Create NULL device entry */ 897 char null[DEVMAP_NAME_MAXLEN]; 898 snprintf(null, DEVMAP_NAME_MAXLEN, "%u", i); 899 900 char *dev_name = str_dup(null); 901 if (dev_name == NULL) { 902 fibril_mutex_unlock(&null_devices_mutex); 903 ipc_answer_0(iid, ENOMEM); 904 return; 905 } 906 645 907 devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); 646 908 if (device == NULL) { … … 650 912 } 651 913 652 char null[DEVMAP_NAME_MAXLEN];653 snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);654 655 device->name = str_dup(null);656 if (device->name == NULL) {914 fibril_mutex_lock(&devices_list_mutex); 915 916 devmap_namespace_t *namespace = devmap_namespace_create("null"); 917 if (!namespace) { 918 fibril_mutex_lock(&devices_list_mutex); 657 919 fibril_mutex_unlock(&null_devices_mutex); 658 free(device);659 920 ipc_answer_0(iid, ENOMEM); 660 921 return; … … 663 924 list_initialize(&(device->devices)); 664 925 list_initialize(&(device->driver_devices)); 665 666 fibril_mutex_lock(&devices_list_mutex);667 926 668 927 /* Get unique device handle */ 669 928 device->handle = devmap_create_handle(); 670 929 device->driver = NULL; 930 931 devmap_namespace_addref(namespace, device); 932 device->name = dev_name; 671 933 672 934 /* Insert device into list of all devices … … 692 954 } 693 955 956 fibril_mutex_lock(&devices_list_mutex); 694 957 devmap_device_unregister_core(null_devices[i]); 958 fibril_mutex_unlock(&devices_list_mutex); 959 695 960 null_devices[i] = NULL; 696 961 … … 725 990 ipc_answer_0(iid, EOK); 726 991 727 devmap_driver_t *driver = NULL; 728 devmap_driver_register(&driver); 729 730 if (NULL == driver) 992 devmap_driver_t *driver = devmap_driver_register(); 993 if (driver == NULL) 731 994 return; 732 995 … … 755 1018 break; 756 1019 case DEVMAP_DEVICE_GET_HANDLE: 757 devmap_ get_handle(callid, &call);758 break; 759 case DEVMAP_ DEVICE_GET_NAME:760 devmap_ get_name(callid, &call);1020 devmap_device_get_handle(callid, &call); 1021 break; 1022 case DEVMAP_NAMESPACE_GET_HANDLE: 1023 devmap_namespace_get_handle(callid, &call); 761 1024 break; 762 1025 default: … … 793 1056 continue; 794 1057 case DEVMAP_DEVICE_GET_HANDLE: 795 devmap_get_handle(callid, &call); 796 break; 797 case DEVMAP_DEVICE_GET_NAME: 798 devmap_get_name(callid, &call); 799 break; 800 case DEVMAP_DEVICE_NULL_CREATE: 1058 devmap_device_get_handle(callid, &call); 1059 break; 1060 case DEVMAP_NAMESPACE_GET_HANDLE: 1061 devmap_namespace_get_handle(callid, &call); 1062 break; 1063 case DEVMAP_HANDLE_PROBE: 1064 devmap_handle_probe(callid, &call); 1065 break; 1066 case DEVMAP_NULL_CREATE: 801 1067 devmap_null_create(callid, &call); 802 1068 break; 803 case DEVMAP_ DEVICE_NULL_DESTROY:1069 case DEVMAP_NULL_DESTROY: 804 1070 devmap_null_destroy(callid, &call); 805 1071 break; 806 case DEVMAP_DEVICE_GET_COUNT: 807 devmap_get_count(callid, &call); 808 break; 809 case DEVMAP_DEVICE_GET_DEVICES: 1072 case DEVMAP_GET_NAMESPACE_COUNT: 1073 devmap_get_namespace_count(callid, &call); 1074 break; 1075 case DEVMAP_GET_DEVICE_COUNT: 1076 devmap_get_device_count(callid, &call); 1077 break; 1078 case DEVMAP_GET_NAMESPACES: 1079 devmap_get_namespaces(callid, &call); 1080 break; 1081 case DEVMAP_GET_DEVICES: 810 1082 devmap_get_devices(callid, &call); 811 1083 break; -
uspace/srv/fs/devfs/devfs_ops.c
rfc6dd18 r1313ee9 44 44 #include <fibril_synch.h> 45 45 #include <adt/hash_table.h> 46 #include <ipc/devmap.h> 46 47 #include <sys/stat.h> 48 #include <libfs.h> 49 #include <assert.h> 47 50 #include "devfs.h" 48 51 #include "devfs_ops.h" 49 52 50 #define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE]) 53 typedef struct { 54 devmap_handle_type_t type; 55 dev_handle_t handle; 56 } devfs_node_t; 51 57 52 58 /** Opened devices structure */ … … 91 97 }; 92 98 99 static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type, 100 dev_handle_t handle) 101 { 102 devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t)); 103 if (node == NULL) { 104 *rfn = NULL; 105 return ENOMEM; 106 } 107 108 *rfn = (fs_node_t *) malloc(sizeof(fs_node_t)); 109 if (*rfn == NULL) { 110 free(node); 111 *rfn = NULL; 112 return ENOMEM; 113 } 114 115 fs_node_initialize(*rfn); 116 node->type = type; 117 node->handle = handle; 118 119 (*rfn)->data = node; 120 return EOK; 121 } 122 123 static int devfs_root_get(fs_node_t **rfn, dev_handle_t dev_handle) 124 { 125 return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0); 126 } 127 128 static int devfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 129 { 130 devfs_node_t *node = (devfs_node_t *) pfn->data; 131 132 if (node->handle == 0) { 133 /* Root directory */ 134 135 dev_desc_t *devs; 136 size_t count = devmap_get_namespaces(&devs); 137 138 if (count > 0) { 139 size_t pos; 140 for (pos = 0; pos < count; pos++) { 141 /* Ignore root namespace */ 142 if (str_cmp(devs[pos].name, "") == 0) 143 continue; 144 145 if (str_cmp(devs[pos].name, component) == 0) { 146 free(devs); 147 return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle); 148 } 149 } 150 151 free(devs); 152 } 153 154 /* Search root namespace */ 155 dev_handle_t namespace; 156 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 157 count = devmap_get_devices(namespace, &devs); 158 159 if (count > 0) { 160 size_t pos; 161 for (pos = 0; pos < count; pos++) { 162 if (str_cmp(devs[pos].name, component) == 0) { 163 free(devs); 164 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 165 } 166 } 167 168 free(devs); 169 } 170 } 171 172 *rfn = NULL; 173 return EOK; 174 } 175 176 if (node->type == DEV_HANDLE_NAMESPACE) { 177 /* Namespace directory */ 178 179 dev_desc_t *devs; 180 size_t count = devmap_get_devices(node->handle, &devs); 181 if (count > 0) { 182 size_t pos; 183 for (pos = 0; pos < count; pos++) { 184 if (str_cmp(devs[pos].name, component) == 0) { 185 free(devs); 186 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 187 } 188 } 189 190 free(devs); 191 } 192 193 *rfn = NULL; 194 return EOK; 195 } 196 197 *rfn = NULL; 198 return EOK; 199 } 200 201 static int devfs_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index) 202 { 203 return devfs_node_get_internal(rfn, devmap_handle_probe(index), index); 204 } 205 206 static int devfs_node_open(fs_node_t *fn) 207 { 208 devfs_node_t *node = (devfs_node_t *) fn->data; 209 210 if (node->handle == 0) { 211 /* Root directory */ 212 return EOK; 213 } 214 215 devmap_handle_type_t type = devmap_handle_probe(node->handle); 216 217 if (type == DEV_HANDLE_NAMESPACE) { 218 /* Namespace directory */ 219 return EOK; 220 } 221 222 if (type == DEV_HANDLE_DEVICE) { 223 /* Device node */ 224 225 unsigned long key[] = { 226 [DEVICES_KEY_HANDLE] = (unsigned long) node->handle 227 }; 228 229 fibril_mutex_lock(&devices_mutex); 230 link_t *lnk = hash_table_find(&devices, key); 231 if (lnk == NULL) { 232 device_t *dev = (device_t *) malloc(sizeof(device_t)); 233 if (dev == NULL) { 234 fibril_mutex_unlock(&devices_mutex); 235 return ENOMEM; 236 } 237 238 int phone = devmap_device_connect(node->handle, 0); 239 if (phone < 0) { 240 fibril_mutex_unlock(&devices_mutex); 241 free(dev); 242 return ENOENT; 243 } 244 245 dev->handle = node->handle; 246 dev->phone = phone; 247 dev->refcount = 1; 248 249 hash_table_insert(&devices, key, &dev->link); 250 } else { 251 device_t *dev = hash_table_get_instance(lnk, device_t, link); 252 dev->refcount++; 253 } 254 255 fibril_mutex_unlock(&devices_mutex); 256 257 return EOK; 258 } 259 260 return ENOENT; 261 } 262 263 static int devfs_node_put(fs_node_t *fn) 264 { 265 free(fn->data); 266 free(fn); 267 return EOK; 268 } 269 270 static int devfs_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int lflag) 271 { 272 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); 273 274 *rfn = NULL; 275 return ENOTSUP; 276 } 277 278 static int devfs_destroy_node(fs_node_t *fn) 279 { 280 return ENOTSUP; 281 } 282 283 static int devfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm) 284 { 285 return ENOTSUP; 286 } 287 288 static int devfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm) 289 { 290 return ENOTSUP; 291 } 292 293 static int devfs_has_children(bool *has_children, fs_node_t *fn) 294 { 295 devfs_node_t *node = (devfs_node_t *) fn->data; 296 297 if (node->handle == 0) { 298 size_t count = devmap_count_namespaces(); 299 if (count > 0) { 300 *has_children = true; 301 return EOK; 302 } 303 304 /* Root namespace */ 305 dev_handle_t namespace; 306 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 307 count = devmap_count_devices(namespace); 308 if (count > 0) { 309 *has_children = true; 310 return EOK; 311 } 312 } 313 314 *has_children = false; 315 return EOK; 316 } 317 318 if (node->type == DEV_HANDLE_NAMESPACE) { 319 size_t count = devmap_count_devices(node->handle); 320 if (count > 0) { 321 *has_children = true; 322 return EOK; 323 } 324 325 *has_children = false; 326 return EOK; 327 } 328 329 *has_children = false; 330 return EOK; 331 } 332 333 static fs_index_t devfs_index_get(fs_node_t *fn) 334 { 335 devfs_node_t *node = (devfs_node_t *) fn->data; 336 return node->handle; 337 } 338 339 static size_t devfs_size_get(fs_node_t *fn) 340 { 341 return 0; 342 } 343 344 static unsigned int devfs_lnkcnt_get(fs_node_t *fn) 345 { 346 devfs_node_t *node = (devfs_node_t *) fn->data; 347 348 if (node->handle == 0) 349 return 0; 350 351 return 1; 352 } 353 354 static char devfs_plb_get_char(unsigned pos) 355 { 356 return devfs_reg.plb_ro[pos % PLB_SIZE]; 357 } 358 359 static bool devfs_is_directory(fs_node_t *fn) 360 { 361 devfs_node_t *node = (devfs_node_t *) fn->data; 362 363 return ((node->type == DEV_HANDLE_NONE) || (node->type == DEV_HANDLE_NAMESPACE)); 364 } 365 366 static bool devfs_is_file(fs_node_t *fn) 367 { 368 devfs_node_t *node = (devfs_node_t *) fn->data; 369 370 return (node->type == DEV_HANDLE_DEVICE); 371 } 372 373 static dev_handle_t devfs_device_get(fs_node_t *fn) 374 { 375 devfs_node_t *node = (devfs_node_t *) fn->data; 376 377 if (node->type == DEV_HANDLE_DEVICE) 378 return node->handle; 379 380 return 0; 381 } 382 383 /** libfs operations */ 384 libfs_ops_t devfs_libfs_ops = { 385 .root_get = devfs_root_get, 386 .match = devfs_match, 387 .node_get = devfs_node_get, 388 .node_open = devfs_node_open, 389 .node_put = devfs_node_put, 390 .create = devfs_create_node, 391 .destroy = devfs_destroy_node, 392 .link = devfs_link_node, 393 .unlink = devfs_unlink_node, 394 .has_children = devfs_has_children, 395 .index_get = devfs_index_get, 396 .size_get = devfs_size_get, 397 .lnkcnt_get = devfs_lnkcnt_get, 398 .plb_get_char = devfs_plb_get_char, 399 .is_directory = devfs_is_directory, 400 .is_file = devfs_is_file, 401 .device_get = devfs_device_get 402 }; 403 93 404 bool devfs_init(void) 94 405 { … … 105 416 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 106 417 { 418 char *opts; 419 107 420 /* Accept the mount options */ 108 ipc_callid_t callid; 109 size_t size; 110 if (!async_data_write_receive(&callid, &size)) { 111 ipc_answer_0(callid, EINVAL); 112 ipc_answer_0(rid, EINVAL); 113 return; 114 } 115 116 char *opts = malloc(size + 1); 117 if (!opts) { 118 ipc_answer_0(callid, ENOMEM); 119 ipc_answer_0(rid, ENOMEM); 120 return; 121 } 122 123 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 421 ipcarg_t retval = async_data_string_receive(&opts, 0); 124 422 if (retval != EOK) { 125 423 ipc_answer_0(rid, retval); 126 free(opts);127 424 return; 128 425 } 129 426 130 427 free(opts); 131 132 428 ipc_answer_3(rid, EOK, 0, 0, 0); 133 429 } … … 135 431 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 136 432 { 137 ipc_answer_0(rid, ENOTSUP);433 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 138 434 } 139 435 140 436 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 141 437 { 142 ipcarg_t first = IPC_GET_ARG1(*request); 143 ipcarg_t last = IPC_GET_ARG2(*request); 144 dev_handle_t dev_handle = IPC_GET_ARG3(*request); 145 ipcarg_t lflag = IPC_GET_ARG4(*request); 146 fs_index_t index = IPC_GET_ARG5(*request); 147 148 /* Hierarchy is flat, no altroot is supported */ 149 if (index != 0) { 150 ipc_answer_0(rid, ENOENT); 151 return; 152 } 153 154 if ((lflag & L_LINK) || (lflag & L_UNLINK)) { 155 ipc_answer_0(rid, ENOTSUP); 156 return; 157 } 158 159 /* Eat slash */ 160 if (PLB_GET_CHAR(first) == '/') { 161 first++; 162 first %= PLB_SIZE; 163 } 164 165 if (first >= last) { 166 /* Root entry */ 167 if (!(lflag & L_FILE)) 168 ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0); 169 else 170 ipc_answer_0(rid, ENOENT); 171 } else { 172 if (!(lflag & L_DIRECTORY)) { 173 size_t len; 174 if (last >= first) 175 len = last - first + 1; 176 else 177 len = first + PLB_SIZE - last + 1; 438 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 439 } 440 441 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 442 { 443 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 444 } 445 446 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 447 { 448 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 449 } 450 451 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 452 { 453 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 454 off_t pos = (off_t) IPC_GET_ARG3(*request); 455 456 if (index == 0) { 457 ipc_callid_t callid; 458 size_t size; 459 if (!async_data_read_receive(&callid, &size)) { 460 ipc_answer_0(callid, EINVAL); 461 ipc_answer_0(rid, EINVAL); 462 return; 463 } 464 465 dev_desc_t *desc; 466 size_t count = devmap_get_namespaces(&desc); 467 468 /* Get rid of root namespace */ 469 size_t i; 470 for (i = 0; i < count; i++) { 471 if (str_cmp(desc[i].name, "") == 0) { 472 if (pos >= i) 473 pos++; 474 475 break; 476 } 477 } 478 479 if (pos < count) { 480 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 481 free(desc); 482 ipc_answer_1(rid, EOK, 1); 483 return; 484 } 485 486 free(desc); 487 pos -= count; 488 489 /* Search root namespace */ 490 dev_handle_t namespace; 491 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 492 count = devmap_get_devices(namespace, &desc); 178 493 179 char *name = (char *) malloc(len + 1); 180 if (name == NULL) { 181 ipc_answer_0(rid, ENOMEM); 494 if (pos < count) { 495 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 496 free(desc); 497 ipc_answer_1(rid, EOK, 1); 182 498 return; 183 499 } 184 500 185 size_t i; 186 for (i = 0; i < len; i++) 187 name[i] = PLB_GET_CHAR(first + i); 188 189 name[len] = 0; 190 191 dev_handle_t handle; 192 if (devmap_device_get_handle(name, &handle, 0) != EOK) { 193 free(name); 194 ipc_answer_0(rid, ENOENT); 195 return; 196 } 197 198 if (lflag & L_OPEN) { 199 unsigned long key[] = { 200 [DEVICES_KEY_HANDLE] = (unsigned long) handle 201 }; 202 203 fibril_mutex_lock(&devices_mutex); 204 link_t *lnk = hash_table_find(&devices, key); 205 if (lnk == NULL) { 206 int phone = devmap_device_connect(handle, 0); 207 if (phone < 0) { 208 fibril_mutex_unlock(&devices_mutex); 209 free(name); 210 ipc_answer_0(rid, ENOENT); 211 return; 212 } 213 214 device_t *dev = (device_t *) malloc(sizeof(device_t)); 215 if (dev == NULL) { 216 fibril_mutex_unlock(&devices_mutex); 217 free(name); 218 ipc_answer_0(rid, ENOMEM); 219 return; 220 } 221 222 dev->handle = handle; 223 dev->phone = phone; 224 dev->refcount = 1; 225 226 hash_table_insert(&devices, key, &dev->link); 227 } else { 228 device_t *dev = hash_table_get_instance(lnk, device_t, link); 229 dev->refcount++; 230 } 231 fibril_mutex_unlock(&devices_mutex); 232 } 233 234 free(name); 235 236 ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1); 237 } else 238 ipc_answer_0(rid, ENOENT); 239 } 240 } 241 242 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 243 { 244 dev_handle_t handle = IPC_GET_ARG2(*request); 245 246 unsigned long key[] = { 247 [DEVICES_KEY_HANDLE] = (unsigned long) handle 248 }; 249 250 fibril_mutex_lock(&devices_mutex); 251 link_t *lnk = hash_table_find(&devices, key); 252 if (lnk == NULL) { 253 int phone = devmap_device_connect(handle, 0); 254 if (phone < 0) { 255 fibril_mutex_unlock(&devices_mutex); 256 ipc_answer_0(rid, ENOENT); 257 return; 258 } 259 260 device_t *dev = (device_t *) malloc(sizeof(device_t)); 261 if (dev == NULL) { 262 fibril_mutex_unlock(&devices_mutex); 263 ipc_answer_0(rid, ENOMEM); 264 return; 265 } 266 267 dev->handle = handle; 268 dev->phone = phone; 269 dev->refcount = 1; 270 271 hash_table_insert(&devices, key, &dev->link); 272 } else { 273 device_t *dev = hash_table_get_instance(lnk, device_t, link); 274 dev->refcount++; 275 } 276 fibril_mutex_unlock(&devices_mutex); 277 278 ipc_answer_3(rid, EOK, 0, 1, L_FILE); 279 } 280 281 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 282 { 283 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 284 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 285 286 ipc_callid_t callid; 287 size_t size; 288 if (!async_data_read_receive(&callid, &size) || 289 size != sizeof(struct stat)) { 290 ipc_answer_0(callid, EINVAL); 291 ipc_answer_0(rid, EINVAL); 292 return; 293 } 294 295 struct stat stat; 296 memset(&stat, 0, sizeof(struct stat)); 297 298 stat.fs_handle = devfs_reg.fs_handle; 299 stat.dev_handle = dev_handle; 300 stat.index = index; 301 stat.lnkcnt = 1; 302 stat.is_file = (index != 0); 303 stat.size = 0; 304 305 if (index != 0) { 306 unsigned long key[] = { 307 [DEVICES_KEY_HANDLE] = (unsigned long) index 308 }; 309 310 fibril_mutex_lock(&devices_mutex); 311 link_t *lnk = hash_table_find(&devices, key); 312 if (lnk != NULL) 313 stat.devfs_stat.device = (dev_handle_t)index; 314 fibril_mutex_unlock(&devices_mutex); 315 } 316 317 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 318 ipc_answer_0(rid, EOK); 319 } 320 321 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 322 { 323 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 324 off_t pos = (off_t) IPC_GET_ARG3(*request); 325 326 if (index != 0) { 501 free(desc); 502 } 503 504 ipc_answer_0(callid, ENOENT); 505 ipc_answer_1(rid, ENOENT, 0); 506 return; 507 } 508 509 devmap_handle_type_t type = devmap_handle_probe(index); 510 511 if (type == DEV_HANDLE_NAMESPACE) { 512 /* Namespace directory */ 513 ipc_callid_t callid; 514 size_t size; 515 if (!async_data_read_receive(&callid, &size)) { 516 ipc_answer_0(callid, EINVAL); 517 ipc_answer_0(rid, EINVAL); 518 return; 519 } 520 521 dev_desc_t *desc; 522 size_t count = devmap_get_devices(index, &desc); 523 524 if (pos < count) { 525 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 526 free(desc); 527 ipc_answer_1(rid, EOK, 1); 528 return; 529 } 530 531 free(desc); 532 ipc_answer_0(callid, ENOENT); 533 ipc_answer_1(rid, ENOENT, 0); 534 return; 535 } 536 537 if (type == DEV_HANDLE_DEVICE) { 538 /* Device node */ 539 327 540 unsigned long key[] = { 328 541 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 364 577 /* Driver reply is the final result of the whole operation */ 365 578 ipc_answer_1(rid, rc, bytes); 366 } else { 367 ipc_callid_t callid; 368 size_t size; 369 if (!async_data_read_receive(&callid, &size)) { 370 ipc_answer_0(callid, EINVAL); 371 ipc_answer_0(rid, EINVAL); 372 return; 373 } 374 375 size_t count = devmap_device_get_count(); 376 dev_desc_t *desc = malloc(count * sizeof(dev_desc_t)); 377 if (desc == NULL) { 378 ipc_answer_0(callid, ENOMEM); 379 ipc_answer_1(rid, ENOMEM, 0); 380 return; 381 } 382 383 size_t max = devmap_device_get_devices(count, desc); 384 385 if (pos < max) { 386 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 387 } else { 388 ipc_answer_0(callid, ENOENT); 389 ipc_answer_1(rid, ENOENT, 0); 390 return; 391 } 392 393 free(desc); 394 395 ipc_answer_1(rid, EOK, 1); 396 } 579 return; 580 } 581 582 ipc_answer_0(rid, ENOENT); 397 583 } 398 584 … … 402 588 off_t pos = (off_t) IPC_GET_ARG3(*request); 403 589 404 if (index != 0) { 590 if (index == 0) { 591 ipc_answer_0(rid, ENOTSUP); 592 return; 593 } 594 595 devmap_handle_type_t type = devmap_handle_probe(index); 596 597 if (type == DEV_HANDLE_NAMESPACE) { 598 /* Namespace directory */ 599 ipc_answer_0(rid, ENOTSUP); 600 return; 601 } 602 603 if (type == DEV_HANDLE_DEVICE) { 604 /* Device node */ 405 605 unsigned long key[] = { 406 606 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 443 643 /* Driver reply is the final result of the whole operation */ 444 644 ipc_answer_1(rid, rc, bytes); 445 } else {446 /* Read-only filesystem */447 ipc_answer_0(rid, ENOTSUP);448 }645 return; 646 } 647 648 ipc_answer_0(rid, ENOENT); 449 649 } 450 650 … … 458 658 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 459 659 460 if (index != 0) { 660 if (index == 0) { 661 ipc_answer_0(rid, EOK); 662 return; 663 } 664 665 devmap_handle_type_t type = devmap_handle_probe(index); 666 667 if (type == DEV_HANDLE_NAMESPACE) { 668 /* Namespace directory */ 669 ipc_answer_0(rid, EOK); 670 return; 671 } 672 673 if (type == DEV_HANDLE_DEVICE) { 461 674 unsigned long key[] = { 462 675 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 482 695 483 696 ipc_answer_0(rid, EOK); 484 } else 485 ipc_answer_0(rid, ENOTSUP); 697 return; 698 } 699 700 ipc_answer_0(rid, ENOENT); 486 701 } 487 702 … … 490 705 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 491 706 492 if (index != 0) { 707 if (index == 0) { 708 ipc_answer_0(rid, EOK); 709 return; 710 } 711 712 devmap_handle_type_t type = devmap_handle_probe(index); 713 714 if (type == DEV_HANDLE_NAMESPACE) { 715 /* Namespace directory */ 716 ipc_answer_0(rid, EOK); 717 return; 718 } 719 720 if (type == DEV_HANDLE_DEVICE) { 493 721 unsigned long key[] = { 494 722 [DEVICES_KEY_HANDLE] = (unsigned long) index … … 518 746 /* Driver reply is the final result of the whole operation */ 519 747 ipc_answer_0(rid, rc); 520 } else 521 ipc_answer_0(rid, ENOTSUP); 748 return; 749 } 750 751 ipc_answer_0(rid, ENOENT); 522 752 } 523 753 -
uspace/srv/fs/fat/fat_ops.c
rfc6dd18 r1313ee9 71 71 static int fat_match(fs_node_t **, fs_node_t *, const char *); 72 72 static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t); 73 static int fat_node_open(fs_node_t *); 73 74 static int fat_node_put(fs_node_t *); 74 75 static int fat_create_node(fs_node_t **, dev_handle_t, int); … … 83 84 static bool fat_is_directory(fs_node_t *); 84 85 static bool fat_is_file(fs_node_t *node); 86 static dev_handle_t fat_device_get(fs_node_t *node); 85 87 86 88 /* … … 407 409 } 408 410 411 int fat_node_open(fs_node_t *fn) 412 { 413 /* 414 * Opening a file is stateless, nothing 415 * to be done here. 416 */ 417 return EOK; 418 } 419 409 420 int fat_node_put(fs_node_t *fn) 410 421 { … … 867 878 } 868 879 880 dev_handle_t fat_device_get(fs_node_t *node) 881 { 882 return 0; 883 } 884 869 885 /** libfs operations */ 870 886 libfs_ops_t fat_libfs_ops = { … … 872 888 .match = fat_match, 873 889 .node_get = fat_node_get, 890 .node_open = fat_node_open, 874 891 .node_put = fat_node_put, 875 892 .create = fat_create_node, … … 881 898 .size_get = fat_size_get, 882 899 .lnkcnt_get = fat_lnkcnt_get, 883 .plb_get_char = 900 .plb_get_char = fat_plb_get_char, 884 901 .is_directory = fat_is_directory, 885 .is_file = fat_is_file 902 .is_file = fat_is_file, 903 .device_get = fat_device_get 886 904 }; 887 905 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
rfc6dd18 r1313ee9 69 69 static int tmpfs_match(fs_node_t **, fs_node_t *, const char *); 70 70 static int tmpfs_node_get(fs_node_t **, dev_handle_t, fs_index_t); 71 static int tmpfs_node_open(fs_node_t *); 71 72 static int tmpfs_node_put(fs_node_t *); 72 73 static int tmpfs_create_node(fs_node_t **, dev_handle_t, int); … … 117 118 } 118 119 120 static dev_handle_t tmpfs_device_get(fs_node_t *fn) 121 { 122 return 0; 123 } 124 119 125 /** libfs operations */ 120 126 libfs_ops_t tmpfs_libfs_ops = { … … 122 128 .match = tmpfs_match, 123 129 .node_get = tmpfs_node_get, 130 .node_open = tmpfs_node_open, 124 131 .node_put = tmpfs_node_put, 125 132 .create = tmpfs_create_node, … … 133 140 .plb_get_char = tmpfs_plb_get_char, 134 141 .is_directory = tmpfs_is_directory, 135 .is_file = tmpfs_is_file 142 .is_file = tmpfs_is_file, 143 .device_get = tmpfs_device_get 136 144 }; 137 145 … … 241 249 } 242 250 return EOK; 251 } 252 253 int tmpfs_node_open(fs_node_t *fn) 254 { 255 /* nothing to do */ 256 return EOK; 243 257 } 244 258
Note:
See TracChangeset
for help on using the changeset viewer.