Changes in uspace/srv/fs/devfs/devfs_ops.c [991f645:b366a1bc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
r991f645 rb366a1bc 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); 279 242 280 free(dev); 243 281 return ENOENT; 244 282 } 245 283 246 dev->handle = node->handle;284 /* Set the correct phone. */ 247 285 dev->phone = phone; 248 dev->refcount = 1;249 250 hash_table_insert(&devices, key, &dev->link);251 286 } else { 252 287 device_t *dev = hash_table_get_instance(lnk, device_t, link); 288 289 if (dev->phone < 0) { 290 /* 291 * Wait until the device structure is completed 292 * and start from the beginning as the device 293 * structure might have entirely disappeared 294 * while we were not holding the mutex in 295 * fibril_condvar_wait(). 296 */ 297 fibril_condvar_wait(&dev->cv, &devices_mutex); 298 goto restart; 299 } 300 253 301 dev->refcount++; 254 302 } … … 409 457 return false; 410 458 411 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)412 return false;413 414 459 return true; 415 460 } … … 420 465 421 466 /* Accept the mount options */ 422 ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,467 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 423 468 0, NULL); 424 469 if (retval != EOK) { 425 ipc_answer_0(rid, retval);470 async_answer_0(rid, retval); 426 471 return; 427 472 } 428 473 429 474 free(opts); 430 ipc_answer_3(rid, EOK, 0, 0, 0);475 async_answer_3(rid, EOK, 0, 0, 0); 431 476 } 432 477 … … 438 483 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 439 484 { 440 ipc_answer_0(rid, ENOTSUP);485 async_answer_0(rid, ENOTSUP); 441 486 } 442 487 … … 471 516 size_t size; 472 517 if (!async_data_read_receive(&callid, &size)) { 473 ipc_answer_0(callid, EINVAL);474 ipc_answer_0(rid, EINVAL);518 async_answer_0(callid, EINVAL); 519 async_answer_0(rid, EINVAL); 475 520 return; 476 521 } … … 493 538 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 494 539 free(desc); 495 ipc_answer_1(rid, EOK, 1);540 async_answer_1(rid, EOK, 1); 496 541 return; 497 542 } … … 508 553 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 509 554 free(desc); 510 ipc_answer_1(rid, EOK, 1);555 async_answer_1(rid, EOK, 1); 511 556 return; 512 557 } … … 515 560 } 516 561 517 ipc_answer_0(callid, ENOENT);518 ipc_answer_1(rid, ENOENT, 0);562 async_answer_0(callid, ENOENT); 563 async_answer_1(rid, ENOENT, 0); 519 564 return; 520 565 } … … 527 572 size_t size; 528 573 if (!async_data_read_receive(&callid, &size)) { 529 ipc_answer_0(callid, EINVAL);530 ipc_answer_0(rid, EINVAL);574 async_answer_0(callid, EINVAL); 575 async_answer_0(rid, EINVAL); 531 576 return; 532 577 } … … 538 583 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 539 584 free(desc); 540 ipc_answer_1(rid, EOK, 1);585 async_answer_1(rid, EOK, 1); 541 586 return; 542 587 } 543 588 544 589 free(desc); 545 ipc_answer_0(callid, ENOENT);546 ipc_answer_1(rid, ENOENT, 0);590 async_answer_0(callid, ENOENT); 591 async_answer_1(rid, ENOENT, 0); 547 592 return; 548 593 } … … 559 604 if (lnk == NULL) { 560 605 fibril_mutex_unlock(&devices_mutex); 561 ipc_answer_0(rid, ENOENT);606 async_answer_0(rid, ENOENT); 562 607 return; 563 608 } 564 609 565 610 device_t *dev = hash_table_get_instance(lnk, device_t, link); 611 assert(dev->phone >= 0); 566 612 567 613 ipc_callid_t callid; 568 614 if (!async_data_read_receive(&callid, NULL)) { 569 615 fibril_mutex_unlock(&devices_mutex); 570 ipc_answer_0(callid, EINVAL);571 ipc_answer_0(rid, EINVAL);616 async_answer_0(callid, EINVAL); 617 async_answer_0(rid, EINVAL); 572 618 return; 573 619 } … … 575 621 /* Make a request at the driver */ 576 622 ipc_call_t answer; 577 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),623 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 578 624 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 579 625 IPC_GET_ARG3(*request), &answer); 580 626 581 627 /* 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);628 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 583 629 fibril_mutex_unlock(&devices_mutex); 584 630 585 631 /* Wait for reply from the driver. */ 586 ipcarg_t rc;632 sysarg_t rc; 587 633 async_wait_for(msg, &rc); 588 634 size_t bytes = IPC_GET_ARG1(answer); 589 635 590 636 /* 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);637 async_answer_1(rid, rc, bytes); 638 return; 639 } 640 641 async_answer_0(rid, ENOENT); 596 642 } 597 643 … … 600 646 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 601 647 if (index == 0) { 602 ipc_answer_0(rid, ENOTSUP);648 async_answer_0(rid, ENOTSUP); 603 649 return; 604 650 } … … 608 654 if (type == DEV_HANDLE_NAMESPACE) { 609 655 /* Namespace directory */ 610 ipc_answer_0(rid, ENOTSUP);656 async_answer_0(rid, ENOTSUP); 611 657 return; 612 658 } … … 622 668 if (lnk == NULL) { 623 669 fibril_mutex_unlock(&devices_mutex); 624 ipc_answer_0(rid, ENOENT);670 async_answer_0(rid, ENOENT); 625 671 return; 626 672 } 627 673 628 674 device_t *dev = hash_table_get_instance(lnk, device_t, link); 675 assert(dev->phone >= 0); 629 676 630 677 ipc_callid_t callid; 631 678 if (!async_data_write_receive(&callid, NULL)) { 632 679 fibril_mutex_unlock(&devices_mutex); 633 ipc_answer_0(callid, EINVAL);634 ipc_answer_0(rid, EINVAL);680 async_answer_0(callid, EINVAL); 681 async_answer_0(rid, EINVAL); 635 682 return; 636 683 } … … 638 685 /* Make a request at the driver */ 639 686 ipc_call_t answer; 640 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),687 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 641 688 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 642 689 IPC_GET_ARG3(*request), &answer); 643 690 644 691 /* 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);692 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 646 693 647 694 fibril_mutex_unlock(&devices_mutex); 648 695 649 696 /* Wait for reply from the driver. */ 650 ipcarg_t rc;697 sysarg_t rc; 651 698 async_wait_for(msg, &rc); 652 699 size_t bytes = IPC_GET_ARG1(answer); 653 700 654 701 /* 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);702 async_answer_1(rid, rc, bytes); 703 return; 704 } 705 706 async_answer_0(rid, ENOENT); 660 707 } 661 708 662 709 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 663 710 { 664 ipc_answer_0(rid, ENOTSUP);711 async_answer_0(rid, ENOTSUP); 665 712 } 666 713 … … 670 717 671 718 if (index == 0) { 672 ipc_answer_0(rid, EOK);719 async_answer_0(rid, EOK); 673 720 return; 674 721 } … … 678 725 if (type == DEV_HANDLE_NAMESPACE) { 679 726 /* Namespace directory */ 680 ipc_answer_0(rid, EOK);727 async_answer_0(rid, EOK); 681 728 return; 682 729 } … … 691 738 if (lnk == NULL) { 692 739 fibril_mutex_unlock(&devices_mutex); 693 ipc_answer_0(rid, ENOENT);740 async_answer_0(rid, ENOENT); 694 741 return; 695 742 } 696 743 697 744 device_t *dev = hash_table_get_instance(lnk, device_t, link); 745 assert(dev->phone >= 0); 698 746 dev->refcount--; 699 747 700 748 if (dev->refcount == 0) { 701 ipc_hangup(dev->phone);749 async_hangup(dev->phone); 702 750 hash_table_remove(&devices, key, DEVICES_KEYS); 703 751 } … … 705 753 fibril_mutex_unlock(&devices_mutex); 706 754 707 ipc_answer_0(rid, EOK);708 return; 709 } 710 711 ipc_answer_0(rid, ENOENT);755 async_answer_0(rid, EOK); 756 return; 757 } 758 759 async_answer_0(rid, ENOENT); 712 760 } 713 761 … … 717 765 718 766 if (index == 0) { 719 ipc_answer_0(rid, EOK);767 async_answer_0(rid, EOK); 720 768 return; 721 769 } … … 725 773 if (type == DEV_HANDLE_NAMESPACE) { 726 774 /* Namespace directory */ 727 ipc_answer_0(rid, EOK);775 async_answer_0(rid, EOK); 728 776 return; 729 777 } … … 738 786 if (lnk == NULL) { 739 787 fibril_mutex_unlock(&devices_mutex); 740 ipc_answer_0(rid, ENOENT);788 async_answer_0(rid, ENOENT); 741 789 return; 742 790 } 743 791 744 792 device_t *dev = hash_table_get_instance(lnk, device_t, link); 793 assert(dev->phone >= 0); 745 794 746 795 /* Make a request at the driver */ 747 796 ipc_call_t answer; 748 aid_t msg = async_send_2(dev->phone, IPC_GET_ METHOD(*request),797 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request), 749 798 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 750 799 … … 752 801 753 802 /* Wait for reply from the driver */ 754 ipcarg_t rc;803 sysarg_t rc; 755 804 async_wait_for(msg, &rc); 756 805 757 806 /* 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);807 async_answer_0(rid, rc); 808 return; 809 } 810 811 async_answer_0(rid, ENOENT); 763 812 } 764 813 765 814 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 766 815 { 767 ipc_answer_0(rid, ENOTSUP);816 async_answer_0(rid, ENOTSUP); 768 817 } 769 818
Note:
See TracChangeset
for help on using the changeset viewer.