Changes in uspace/srv/fs/devfs/devfs_ops.c [228e490:cfd630af] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
r228e490 rcfd630af 36 36 */ 37 37 38 #include <ipc/ipc.h>39 38 #include <macros.h> 40 39 #include <bool.h> … … 60 59 typedef struct { 61 60 devmap_handle_t handle; 62 int phone; 61 int phone; /**< When < 0, the structure is incomplete. */ 63 62 size_t refcount; 64 63 link_t link; 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } device_t; 66 66 … … 130 130 { 131 131 devfs_node_t *node = (devfs_node_t *) pfn->data; 132 int ret; 132 133 133 134 if (node->handle == 0) { … … 145 146 146 147 if (str_cmp(devs[pos].name, component) == 0) { 148 ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle); 147 149 free(devs); 148 return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);150 return ret; 149 151 } 150 152 } … … 162 164 for (pos = 0; pos < count; pos++) { 163 165 if (str_cmp(devs[pos].name, component) == 0) { 166 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 164 167 free(devs); 165 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);168 return ret; 166 169 } 167 170 } … … 184 187 for (pos = 0; pos < count; pos++) { 185 188 if (str_cmp(devs[pos].name, component) == 0) { 189 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 186 190 free(devs); 187 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);191 return ret; 188 192 } 189 193 } … … 227 231 [DEVICES_KEY_HANDLE] = (unsigned long) node->handle 228 232 }; 229 233 link_t *lnk; 234 230 235 fibril_mutex_lock(&devices_mutex); 231 link_t *lnk = hash_table_find(&devices, key); 236 restart: 237 lnk = hash_table_find(&devices, key); 232 238 if (lnk == NULL) { 233 239 device_t *dev = (device_t *) malloc(sizeof(device_t)); … … 237 243 } 238 244 245 dev->handle = node->handle; 246 dev->phone = -1; /* mark as incomplete */ 247 dev->refcount = 1; 248 fibril_condvar_initialize(&dev->cv); 249 250 /* 251 * Insert the incomplete device structure so that other 252 * fibrils will not race with us when we drop the mutex 253 * below. 254 */ 255 hash_table_insert(&devices, key, &dev->link); 256 257 /* 258 * Drop the mutex to allow recursive devfs requests. 259 */ 260 fibril_mutex_unlock(&devices_mutex); 261 239 262 int phone = devmap_device_connect(node->handle, 0); 263 264 fibril_mutex_lock(&devices_mutex); 265 266 /* 267 * Notify possible waiters about this device structure 268 * being completed (or destroyed). 269 */ 270 fibril_condvar_broadcast(&dev->cv); 271 240 272 if (phone < 0) { 273 /* 274 * Connecting failed, need to remove the 275 * entry and free the device structure. 276 */ 277 hash_table_remove(&devices, key, DEVICES_KEYS); 241 278 fibril_mutex_unlock(&devices_mutex); 242 free(dev); 279 243 280 return ENOENT; 244 281 } 245 282 246 dev->handle = node->handle;283 /* Set the correct phone. */ 247 284 dev->phone = phone; 248 dev->refcount = 1;249 250 hash_table_insert(&devices, key, &dev->link);251 285 } else { 252 286 device_t *dev = hash_table_get_instance(lnk, device_t, link); 287 288 if (dev->phone < 0) { 289 /* 290 * Wait until the device structure is completed 291 * and start from the beginning as the device 292 * structure might have entirely disappeared 293 * while we were not holding the mutex in 294 * fibril_condvar_wait(). 295 */ 296 fibril_condvar_wait(&dev->cv, &devices_mutex); 297 goto restart; 298 } 299 253 300 dev->refcount++; 254 301 } … … 409 456 return false; 410 457 411 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)412 return false;413 414 458 return true; 415 459 } … … 423 467 0, NULL); 424 468 if (retval != EOK) { 425 ipc_answer_0(rid, retval);469 async_answer_0(rid, retval); 426 470 return; 427 471 } 428 472 429 473 free(opts); 430 ipc_answer_3(rid, EOK, 0, 0, 0);474 async_answer_3(rid, EOK, 0, 0, 0); 431 475 } 432 476 … … 438 482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 439 483 { 440 ipc_answer_0(rid, ENOTSUP);484 async_answer_0(rid, ENOTSUP); 441 485 } 442 486 … … 471 515 size_t size; 472 516 if (!async_data_read_receive(&callid, &size)) { 473 ipc_answer_0(callid, EINVAL);474 ipc_answer_0(rid, EINVAL);517 async_answer_0(callid, EINVAL); 518 async_answer_0(rid, EINVAL); 475 519 return; 476 520 } … … 493 537 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 494 538 free(desc); 495 ipc_answer_1(rid, EOK, 1);539 async_answer_1(rid, EOK, 1); 496 540 return; 497 541 } … … 508 552 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 509 553 free(desc); 510 ipc_answer_1(rid, EOK, 1);554 async_answer_1(rid, EOK, 1); 511 555 return; 512 556 } … … 515 559 } 516 560 517 ipc_answer_0(callid, ENOENT);518 ipc_answer_1(rid, ENOENT, 0);561 async_answer_0(callid, ENOENT); 562 async_answer_1(rid, ENOENT, 0); 519 563 return; 520 564 } … … 527 571 size_t size; 528 572 if (!async_data_read_receive(&callid, &size)) { 529 ipc_answer_0(callid, EINVAL);530 ipc_answer_0(rid, EINVAL);573 async_answer_0(callid, EINVAL); 574 async_answer_0(rid, EINVAL); 531 575 return; 532 576 } … … 538 582 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 539 583 free(desc); 540 ipc_answer_1(rid, EOK, 1);584 async_answer_1(rid, EOK, 1); 541 585 return; 542 586 } 543 587 544 588 free(desc); 545 ipc_answer_0(callid, ENOENT);546 ipc_answer_1(rid, ENOENT, 0);589 async_answer_0(callid, ENOENT); 590 async_answer_1(rid, ENOENT, 0); 547 591 return; 548 592 } … … 559 603 if (lnk == NULL) { 560 604 fibril_mutex_unlock(&devices_mutex); 561 ipc_answer_0(rid, ENOENT);605 async_answer_0(rid, ENOENT); 562 606 return; 563 607 } 564 608 565 609 device_t *dev = hash_table_get_instance(lnk, device_t, link); 610 assert(dev->phone >= 0); 566 611 567 612 ipc_callid_t callid; 568 613 if (!async_data_read_receive(&callid, NULL)) { 569 614 fibril_mutex_unlock(&devices_mutex); 570 ipc_answer_0(callid, EINVAL);571 ipc_answer_0(rid, EINVAL);615 async_answer_0(callid, EINVAL); 616 async_answer_0(rid, EINVAL); 572 617 return; 573 618 } … … 580 625 581 626 /* Forward the IPC_M_DATA_READ request to the driver */ 582 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 583 628 fibril_mutex_unlock(&devices_mutex); 584 629 … … 589 634 590 635 /* Driver reply is the final result of the whole operation */ 591 ipc_answer_1(rid, rc, bytes);592 return; 593 } 594 595 ipc_answer_0(rid, ENOENT);636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 596 641 } 597 642 … … 600 645 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 601 646 if (index == 0) { 602 ipc_answer_0(rid, ENOTSUP);647 async_answer_0(rid, ENOTSUP); 603 648 return; 604 649 } … … 608 653 if (type == DEV_HANDLE_NAMESPACE) { 609 654 /* Namespace directory */ 610 ipc_answer_0(rid, ENOTSUP);655 async_answer_0(rid, ENOTSUP); 611 656 return; 612 657 } … … 622 667 if (lnk == NULL) { 623 668 fibril_mutex_unlock(&devices_mutex); 624 ipc_answer_0(rid, ENOENT);669 async_answer_0(rid, ENOENT); 625 670 return; 626 671 } 627 672 628 673 device_t *dev = hash_table_get_instance(lnk, device_t, link); 674 assert(dev->phone >= 0); 629 675 630 676 ipc_callid_t callid; 631 677 if (!async_data_write_receive(&callid, NULL)) { 632 678 fibril_mutex_unlock(&devices_mutex); 633 ipc_answer_0(callid, EINVAL);634 ipc_answer_0(rid, EINVAL);679 async_answer_0(callid, EINVAL); 680 async_answer_0(rid, EINVAL); 635 681 return; 636 682 } … … 643 689 644 690 /* Forward the IPC_M_DATA_WRITE request to the driver */ 645 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 646 692 647 693 fibril_mutex_unlock(&devices_mutex); … … 653 699 654 700 /* Driver reply is the final result of the whole operation */ 655 ipc_answer_1(rid, rc, bytes);656 return; 657 } 658 659 ipc_answer_0(rid, ENOENT);701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 660 706 } 661 707 662 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 663 709 { 664 ipc_answer_0(rid, ENOTSUP);710 async_answer_0(rid, ENOTSUP); 665 711 } 666 712 … … 670 716 671 717 if (index == 0) { 672 ipc_answer_0(rid, EOK);718 async_answer_0(rid, EOK); 673 719 return; 674 720 } … … 678 724 if (type == DEV_HANDLE_NAMESPACE) { 679 725 /* Namespace directory */ 680 ipc_answer_0(rid, EOK);726 async_answer_0(rid, EOK); 681 727 return; 682 728 } … … 691 737 if (lnk == NULL) { 692 738 fibril_mutex_unlock(&devices_mutex); 693 ipc_answer_0(rid, ENOENT);739 async_answer_0(rid, ENOENT); 694 740 return; 695 741 } 696 742 697 743 device_t *dev = hash_table_get_instance(lnk, device_t, link); 744 assert(dev->phone >= 0); 698 745 dev->refcount--; 699 746 700 747 if (dev->refcount == 0) { 701 ipc_hangup(dev->phone);748 async_hangup(dev->phone); 702 749 hash_table_remove(&devices, key, DEVICES_KEYS); 703 750 } … … 705 752 fibril_mutex_unlock(&devices_mutex); 706 753 707 ipc_answer_0(rid, EOK);708 return; 709 } 710 711 ipc_answer_0(rid, ENOENT);754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 712 759 } 713 760 … … 717 764 718 765 if (index == 0) { 719 ipc_answer_0(rid, EOK);766 async_answer_0(rid, EOK); 720 767 return; 721 768 } … … 725 772 if (type == DEV_HANDLE_NAMESPACE) { 726 773 /* Namespace directory */ 727 ipc_answer_0(rid, EOK);774 async_answer_0(rid, EOK); 728 775 return; 729 776 } … … 738 785 if (lnk == NULL) { 739 786 fibril_mutex_unlock(&devices_mutex); 740 ipc_answer_0(rid, ENOENT);787 async_answer_0(rid, ENOENT); 741 788 return; 742 789 } 743 790 744 791 device_t *dev = hash_table_get_instance(lnk, device_t, link); 792 assert(dev->phone >= 0); 745 793 746 794 /* Make a request at the driver */ … … 756 804 757 805 /* Driver reply is the final result of the whole operation */ 758 ipc_answer_0(rid, rc);759 return; 760 } 761 762 ipc_answer_0(rid, ENOENT);806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 763 811 } 764 812 765 813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 766 814 { 767 ipc_answer_0(rid, ENOTSUP);815 async_answer_0(rid, ENOTSUP); 768 816 } 769 817
Note:
See TracChangeset
for help on using the changeset viewer.