Changeset a33f0a6 in mainline for uspace/srv/fs
- Timestamp:
- 2011-08-03T17:34:57Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1940326
- Parents:
- 52a79081 (diff), 3fab770 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/srv/fs
- Files:
-
- 3 added
- 15 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/Makefile
r52a79081 ra33f0a6 32 32 EXTRA_CFLAGS += -I$(LIBFS_PREFIX) 33 33 BINARY = devfs 34 STATIC_NEEDED = y 34 35 35 36 SOURCES = \ -
uspace/srv/fs/devfs/devfs.c
r52a79081 ra33f0a6 41 41 #include <stdio.h> 42 42 #include <ipc/services.h> 43 #include < ipc/ns.h>43 #include <ns.h> 44 44 #include <async.h> 45 45 #include <errno.h> … … 57 57 }; 58 58 59 fs_reg_t devfs_reg;60 61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall)62 {63 if (iid)64 async_answer_0(iid, EOK);65 66 while (true) {67 ipc_call_t call;68 ipc_callid_t callid = async_get_call(&call);69 70 switch (IPC_GET_IMETHOD(call)) {71 case IPC_M_PHONE_HUNGUP:72 return;73 case VFS_OUT_MOUNTED:74 devfs_mounted(callid, &call);75 break;76 case VFS_OUT_MOUNT:77 devfs_mount(callid, &call);78 break;79 case VFS_OUT_UNMOUNTED:80 devfs_unmounted(callid, &call);81 break;82 case VFS_OUT_UNMOUNT:83 devfs_unmount(callid, &call);84 break;85 case VFS_OUT_LOOKUP:86 devfs_lookup(callid, &call);87 break;88 case VFS_OUT_OPEN_NODE:89 devfs_open_node(callid, &call);90 break;91 case VFS_OUT_STAT:92 devfs_stat(callid, &call);93 break;94 case VFS_OUT_READ:95 devfs_read(callid, &call);96 break;97 case VFS_OUT_WRITE:98 devfs_write(callid, &call);99 break;100 case VFS_OUT_TRUNCATE:101 devfs_truncate(callid, &call);102 break;103 case VFS_OUT_CLOSE:104 devfs_close(callid, &call);105 break;106 case VFS_OUT_SYNC:107 devfs_sync(callid, &call);108 break;109 case VFS_OUT_DESTROY:110 devfs_destroy(callid, &call);111 break;112 default:113 async_answer_0(callid, ENOTSUP);114 break;115 }116 }117 }118 119 59 int main(int argc, char *argv[]) 120 60 { 121 printf( NAME ": HelenOS Device Filesystem\n");61 printf("%s: HelenOS Device Filesystem\n", NAME); 122 62 123 63 if (!devfs_init()) { 124 printf( NAME ": failed to initialize devfs\n");64 printf("%s: failed to initialize devfs\n", NAME); 125 65 return -1; 126 66 } 127 67 128 int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 129 if (vfs_phone < EOK) { 130 printf(NAME ": Unable to connect to VFS\n"); 68 async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 69 SERVICE_VFS, 0, 0); 70 if (!vfs_sess) { 71 printf("%s: Unable to connect to VFS\n", NAME); 131 72 return -1; 132 73 } 133 74 134 int rc = fs_register(vfs_ phone, &devfs_reg, &devfs_vfs_info,135 devfs_connection);75 int rc = fs_register(vfs_sess, &devfs_vfs_info, &devfs_ops, 76 &devfs_libfs_ops); 136 77 if (rc != EOK) { 137 printf( NAME ": Failed to register file system (%d)\n", rc);78 printf("%s: Failed to register file system (%d)\n", NAME, rc); 138 79 return rc; 139 80 } 140 81 141 printf( NAME ": Accepting connections\n");82 printf("%s: Accepting connections\n", NAME); 142 83 task_retval(0); 143 84 async_manager(); … … 150 91 * @} 151 92 */ 93 -
uspace/srv/fs/devfs/devfs.h
r52a79081 ra33f0a6 36 36 #include <libfs.h> 37 37 38 extern fs_reg_t devfs_reg; 38 extern vfs_out_ops_t devfs_ops; 39 extern libfs_ops_t devfs_libfs_ops; 39 40 40 41 #endif -
uspace/srv/fs/devfs/devfs_ops.c
r52a79081 ra33f0a6 59 59 typedef struct { 60 60 devmap_handle_t handle; 61 int phone; /**< When < 0, the structure is incomplete. */61 async_sess_t *sess; /**< If NULL, the structure is incomplete. */ 62 62 size_t refcount; 63 63 link_t link; 64 fibril_condvar_t cv; 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } device_t; 66 66 … … 232 232 }; 233 233 link_t *lnk; 234 234 235 235 fibril_mutex_lock(&devices_mutex); 236 236 restart: … … 244 244 245 245 dev->handle = node->handle; 246 dev->phone = -1; /* mark as incomplete */ 246 247 /* Mark as incomplete */ 248 dev->sess = NULL; 247 249 dev->refcount = 1; 248 250 fibril_condvar_initialize(&dev->cv); 249 251 250 252 /* 251 253 * Insert the incomplete device structure so that other … … 254 256 */ 255 257 hash_table_insert(&devices, key, &dev->link); 256 258 257 259 /* 258 260 * Drop the mutex to allow recursive devfs requests. 259 261 */ 260 262 fibril_mutex_unlock(&devices_mutex); 261 262 int phone = devmap_device_connect(node->handle, 0); 263 263 264 async_sess_t *sess = devmap_device_connect(EXCHANGE_SERIALIZE, 265 node->handle, 0); 266 264 267 fibril_mutex_lock(&devices_mutex); 265 268 266 269 /* 267 270 * Notify possible waiters about this device structure … … 269 272 */ 270 273 fibril_condvar_broadcast(&dev->cv); 271 272 if ( phone < 0) {274 275 if (!sess) { 273 276 /* 274 277 * Connecting failed, need to remove the … … 277 280 hash_table_remove(&devices, key, DEVICES_KEYS); 278 281 fibril_mutex_unlock(&devices_mutex); 279 282 280 283 return ENOENT; 281 284 } 282 285 283 /* Set the correct phone. */284 dev-> phone = phone;286 /* Set the correct session. */ 287 dev->sess = sess; 285 288 } else { 286 289 device_t *dev = hash_table_get_instance(lnk, device_t, link); 287 288 if ( dev->phone < 0) {290 291 if (!dev->sess) { 289 292 /* 290 293 * Wait until the device structure is completed … … 398 401 399 402 return 1; 400 }401 402 static char devfs_plb_get_char(unsigned pos)403 {404 return devfs_reg.plb_ro[pos % PLB_SIZE];405 403 } 406 404 … … 444 442 .size_get = devfs_size_get, 445 443 .lnkcnt_get = devfs_lnkcnt_get, 446 .plb_get_char = devfs_plb_get_char,447 444 .is_directory = devfs_is_directory, 448 445 .is_file = devfs_is_file, … … 459 456 } 460 457 461 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 462 { 463 char *opts; 464 465 /* Accept the mount options */ 466 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 467 0, NULL); 468 if (retval != EOK) { 469 async_answer_0(rid, retval); 470 return; 471 } 472 473 free(opts); 474 async_answer_3(rid, EOK, 0, 0, 0); 475 } 476 477 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 478 { 479 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 480 } 481 482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 483 { 484 async_answer_0(rid, ENOTSUP); 485 } 486 487 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 488 { 489 libfs_unmount(&devfs_libfs_ops, rid, request); 490 } 491 492 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 493 { 494 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 495 } 496 497 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 498 { 499 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 500 } 501 502 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 503 { 504 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 505 } 506 507 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 508 { 509 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 510 aoff64_t pos = 511 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 512 458 static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts, 459 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 460 { 461 *index = 0; 462 *size = 0; 463 *lnkcnt = 0; 464 return EOK; 465 } 466 467 static int devfs_unmounted(devmap_handle_t devmap_handle) 468 { 469 return ENOTSUP; 470 } 471 472 static int 473 devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 474 size_t *rbytes) 475 { 513 476 if (index == 0) { 514 477 ipc_callid_t callid; … … 516 479 if (!async_data_read_receive(&callid, &size)) { 517 480 async_answer_0(callid, EINVAL); 518 async_answer_0(rid, EINVAL); 519 return; 481 return EINVAL; 520 482 } 521 483 … … 537 499 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 538 500 free(desc); 539 async_answer_1(rid, EOK, 1);540 return ;501 *rbytes = 1; 502 return EOK; 541 503 } 542 504 … … 552 514 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 553 515 free(desc); 554 async_answer_1(rid, EOK, 1);555 return ;516 *rbytes = 1; 517 return EOK; 556 518 } 557 519 … … 560 522 561 523 async_answer_0(callid, ENOENT); 562 async_answer_1(rid, ENOENT, 0); 563 return; 524 return ENOENT; 564 525 } 565 526 … … 572 533 if (!async_data_read_receive(&callid, &size)) { 573 534 async_answer_0(callid, EINVAL); 574 async_answer_0(rid, EINVAL); 575 return; 535 return EINVAL; 576 536 } 577 537 … … 582 542 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 583 543 free(desc); 584 async_answer_1(rid, EOK, 1);585 return ;544 *rbytes = 1; 545 return EOK; 586 546 } 587 547 588 548 free(desc); 589 549 async_answer_0(callid, ENOENT); 590 async_answer_1(rid, ENOENT, 0); 591 return; 550 return ENOENT; 592 551 } 593 552 … … 603 562 if (lnk == NULL) { 604 563 fibril_mutex_unlock(&devices_mutex); 605 async_answer_0(rid, ENOENT); 606 return; 564 return ENOENT; 607 565 } 608 566 609 567 device_t *dev = hash_table_get_instance(lnk, device_t, link); 610 assert(dev-> phone >= 0);568 assert(dev->sess); 611 569 612 570 ipc_callid_t callid; … … 614 572 fibril_mutex_unlock(&devices_mutex); 615 573 async_answer_0(callid, EINVAL); 616 async_answer_0(rid, EINVAL); 617 return; 574 return EINVAL; 618 575 } 619 576 620 577 /* Make a request at the driver */ 578 async_exch_t *exch = async_exchange_begin(dev->sess); 579 621 580 ipc_call_t answer; 622 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 623 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 624 IPC_GET_ARG3(*request), &answer); 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle, 582 index, LOWER32(pos), UPPER32(pos), &answer); 625 583 626 584 /* Forward the IPC_M_DATA_READ request to the driver */ 627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 585 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 586 587 async_exchange_end(exch); 588 628 589 fibril_mutex_unlock(&devices_mutex); 629 590 … … 631 592 sysarg_t rc; 632 593 async_wait_for(msg, &rc); 633 size_t bytes = IPC_GET_ARG1(answer); 634 635 /* Driver reply is the final result of the whole operation */ 636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 641 } 642 643 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 644 { 645 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 646 if (index == 0) { 647 async_answer_0(rid, ENOTSUP); 648 return; 649 } 594 595 *rbytes = IPC_GET_ARG1(answer); 596 return rc; 597 } 598 599 return ENOENT; 600 } 601 602 static int 603 devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 604 size_t *wbytes, aoff64_t *nsize) 605 { 606 if (index == 0) 607 return ENOTSUP; 650 608 651 609 devmap_handle_type_t type = devmap_handle_probe(index); … … 653 611 if (type == DEV_HANDLE_NAMESPACE) { 654 612 /* Namespace directory */ 655 async_answer_0(rid, ENOTSUP); 656 return; 613 return ENOTSUP; 657 614 } 658 615 … … 667 624 if (lnk == NULL) { 668 625 fibril_mutex_unlock(&devices_mutex); 669 async_answer_0(rid, ENOENT); 670 return; 626 return ENOENT; 671 627 } 672 628 673 629 device_t *dev = hash_table_get_instance(lnk, device_t, link); 674 assert(dev-> phone >= 0);630 assert(dev->sess); 675 631 676 632 ipc_callid_t callid; … … 678 634 fibril_mutex_unlock(&devices_mutex); 679 635 async_answer_0(callid, EINVAL); 680 async_answer_0(rid, EINVAL); 681 return; 636 return EINVAL; 682 637 } 683 638 684 639 /* Make a request at the driver */ 640 async_exch_t *exch = async_exchange_begin(dev->sess); 641 685 642 ipc_call_t answer; 686 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 687 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 688 IPC_GET_ARG3(*request), &answer); 643 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle, 644 index, LOWER32(pos), UPPER32(pos), &answer); 689 645 690 646 /* Forward the IPC_M_DATA_WRITE request to the driver */ 691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 647 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 648 649 async_exchange_end(exch); 692 650 693 651 fibril_mutex_unlock(&devices_mutex); … … 696 654 sysarg_t rc; 697 655 async_wait_for(msg, &rc); 698 size_t bytes = IPC_GET_ARG1(answer); 699 700 /* Driver reply is the final result of the whole operation */ 701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 706 } 707 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 709 { 710 async_answer_0(rid, ENOTSUP); 711 } 712 713 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 714 { 715 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 716 717 if (index == 0) { 718 async_answer_0(rid, EOK); 719 return; 720 } 656 657 *wbytes = IPC_GET_ARG1(answer); 658 *nsize = 0; 659 return rc; 660 } 661 662 return ENOENT; 663 } 664 665 static int 666 devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 667 { 668 return ENOTSUP; 669 } 670 671 static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index) 672 { 673 if (index == 0) 674 return EOK; 721 675 722 676 devmap_handle_type_t type = devmap_handle_probe(index); … … 724 678 if (type == DEV_HANDLE_NAMESPACE) { 725 679 /* Namespace directory */ 726 async_answer_0(rid, EOK); 727 return; 680 return EOK; 728 681 } 729 682 … … 737 690 if (lnk == NULL) { 738 691 fibril_mutex_unlock(&devices_mutex); 739 async_answer_0(rid, ENOENT); 740 return; 692 return ENOENT; 741 693 } 742 694 743 695 device_t *dev = hash_table_get_instance(lnk, device_t, link); 744 assert(dev-> phone >= 0);696 assert(dev->sess); 745 697 dev->refcount--; 746 698 747 699 if (dev->refcount == 0) { 748 async_hangup(dev-> phone);700 async_hangup(dev->sess); 749 701 hash_table_remove(&devices, key, DEVICES_KEYS); 750 702 } … … 752 704 fibril_mutex_unlock(&devices_mutex); 753 705 754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 759 } 760 761 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 762 { 763 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 764 765 if (index == 0) { 766 async_answer_0(rid, EOK); 767 return; 768 } 706 return EOK; 707 } 708 709 return ENOENT; 710 } 711 712 static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 713 { 714 if (index == 0) 715 return EOK; 769 716 770 717 devmap_handle_type_t type = devmap_handle_probe(index); … … 772 719 if (type == DEV_HANDLE_NAMESPACE) { 773 720 /* Namespace directory */ 774 async_answer_0(rid, EOK); 775 return; 721 return EOK; 776 722 } 777 723 … … 785 731 if (lnk == NULL) { 786 732 fibril_mutex_unlock(&devices_mutex); 787 async_answer_0(rid, ENOENT); 788 return; 733 return ENOENT; 789 734 } 790 735 791 736 device_t *dev = hash_table_get_instance(lnk, device_t, link); 792 assert(dev-> phone >= 0);737 assert(dev->sess); 793 738 794 739 /* Make a request at the driver */ 740 async_exch_t *exch = async_exchange_begin(dev->sess); 741 795 742 ipc_call_t answer; 796 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request), 797 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 743 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle, 744 index, &answer); 745 746 async_exchange_end(exch); 798 747 799 748 fibril_mutex_unlock(&devices_mutex); … … 803 752 async_wait_for(msg, &rc); 804 753 805 /* Driver reply is the final result of the whole operation */ 806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 811 } 812 813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 814 { 815 async_answer_0(rid, ENOTSUP); 816 } 754 return rc; 755 } 756 757 return ENOENT; 758 } 759 760 static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 761 { 762 return ENOTSUP; 763 } 764 765 vfs_out_ops_t devfs_ops = { 766 .mounted = devfs_mounted, 767 .unmounted = devfs_unmounted, 768 .read = devfs_read, 769 .write = devfs_write, 770 .truncate = devfs_truncate, 771 .close = devfs_close, 772 .destroy = devfs_destroy, 773 .sync = devfs_sync, 774 }; 817 775 818 776 /** -
uspace/srv/fs/devfs/devfs_ops.h
r52a79081 ra33f0a6 34 34 #define DEVFS_DEVFS_OPS_H_ 35 35 36 #include <ipc/common.h>37 36 #include <bool.h> 38 37 39 38 extern bool devfs_init(void); 40 41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *);42 extern void devfs_mount(ipc_callid_t, ipc_call_t *);43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *);45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *);46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *);47 extern void devfs_stat(ipc_callid_t, ipc_call_t *);48 extern void devfs_sync(ipc_callid_t, ipc_call_t *);49 extern void devfs_read(ipc_callid_t, ipc_call_t *);50 extern void devfs_write(ipc_callid_t, ipc_call_t *);51 extern void devfs_truncate(ipc_callid_t, ipc_call_t *);52 extern void devfs_close(ipc_callid_t, ipc_call_t *);53 extern void devfs_destroy(ipc_callid_t, ipc_call_t *);54 39 55 40 #endif -
uspace/srv/fs/ext2fs/ext2fs.h
r52a79081 ra33f0a6 1 1 /* 2 * Copyright (c) 20 09 Jiri Svoboda2 * Copyright (c) 2011 Martin Sucha 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup kbdgen generic 30 * @brief HelenOS generic uspace keyboard handler. 31 * @ingroup kbd 29 /** @addtogroup fs 32 30 * @{ 33 31 */ 34 /** @file35 */36 32 37 #ifndef KBD_PORT_H_38 #define KBD_PORT_H_33 #ifndef EXT2FS_EXT2FS_H_ 34 #define EXT2FS_EXT2FS_H_ 39 35 36 #include <libext2.h> 37 #include <libfs.h> 40 38 #include <sys/types.h> 41 39 42 extern int kbd_port_init(void); 43 extern void kbd_port_yield(void); 44 extern void kbd_port_reclaim(void); 45 extern void kbd_port_write(uint8_t); 40 #define min(a, b) ((a) < (b) ? (a) : (b)) 41 42 extern vfs_out_ops_t ext2fs_ops; 43 extern libfs_ops_t ext2fs_libfs_ops; 44 45 extern int ext2fs_global_init(void); 46 extern int ext2fs_global_fini(void); 46 47 47 48 #endif … … 49 50 /** 50 51 * @} 51 */ 52 52 */ -
uspace/srv/fs/fat/Makefile
r52a79081 ra33f0a6 32 32 EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) 33 33 BINARY = fat 34 STATIC_NEEDED = y 34 35 35 36 SOURCES = \ -
uspace/srv/fs/fat/fat.c
r52a79081 ra33f0a6 40 40 #include "fat.h" 41 41 #include <ipc/services.h> 42 #include < ipc/ns.h>42 #include <ns.h> 43 43 #include <async.h> 44 44 #include <errno.h> … … 57 57 }; 58 58 59 fs_reg_t fat_reg;60 61 /**62 * This connection fibril processes VFS requests from VFS.63 *64 * In order to support simultaneous VFS requests, our design is as follows.65 * The connection fibril accepts VFS requests from VFS. If there is only one66 * instance of the fibril, VFS will need to serialize all VFS requests it sends67 * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO68 * call. In that case, a new connection fibril will be created, which in turn69 * will accept the call. Thus, a new phone will be opened for VFS.70 *71 * There are few issues with this arrangement. First, VFS can run out of72 * available phones. In that case, VFS can close some other phones or use one73 * phone for more serialized requests. Similarily, FAT can refuse to duplicate74 * the connection. VFS should then just make use of already existing phones and75 * route its requests through them. To avoid paying the fibril creation price76 * upon each request, FAT might want to keep the connections open after the77 * request has been completed.78 */79 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall)80 {81 if (iid) {82 /*83 * This only happens for connections opened by84 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections85 * created by IPC_M_CONNECT_TO_ME.86 */87 async_answer_0(iid, EOK);88 }89 90 dprintf(NAME ": connection opened\n");91 while (1) {92 ipc_callid_t callid;93 ipc_call_t call;94 95 callid = async_get_call(&call);96 switch (IPC_GET_IMETHOD(call)) {97 case IPC_M_PHONE_HUNGUP:98 return;99 case VFS_OUT_MOUNTED:100 fat_mounted(callid, &call);101 break;102 case VFS_OUT_MOUNT:103 fat_mount(callid, &call);104 break;105 case VFS_OUT_UNMOUNTED:106 fat_unmounted(callid, &call);107 break;108 case VFS_OUT_UNMOUNT:109 fat_unmount(callid, &call);110 break;111 case VFS_OUT_LOOKUP:112 fat_lookup(callid, &call);113 break;114 case VFS_OUT_READ:115 fat_read(callid, &call);116 break;117 case VFS_OUT_WRITE:118 fat_write(callid, &call);119 break;120 case VFS_OUT_TRUNCATE:121 fat_truncate(callid, &call);122 break;123 case VFS_OUT_STAT:124 fat_stat(callid, &call);125 break;126 case VFS_OUT_CLOSE:127 fat_close(callid, &call);128 break;129 case VFS_OUT_DESTROY:130 fat_destroy(callid, &call);131 break;132 case VFS_OUT_OPEN_NODE:133 fat_open_node(callid, &call);134 break;135 case VFS_OUT_SYNC:136 fat_sync(callid, &call);137 break;138 default:139 async_answer_0(callid, ENOTSUP);140 break;141 }142 }143 }144 145 59 int main(int argc, char **argv) 146 60 { 147 int vfs_phone;148 int rc;149 150 61 printf(NAME ": HelenOS FAT file system server\n"); 151 152 rc = fat_idx_init();62 63 int rc = fat_idx_init(); 153 64 if (rc != EOK) 154 65 goto err; 155 156 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 157 if (vfs_phone < EOK) { 66 67 async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 68 SERVICE_VFS, 0, 0); 69 if (!vfs_sess) { 158 70 printf(NAME ": failed to connect to VFS\n"); 159 71 return -1; 160 72 } 161 73 162 rc = fs_register(vfs_ phone, &fat_reg, &fat_vfs_info, fat_connection);74 rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops); 163 75 if (rc != EOK) { 164 76 fat_idx_fini(); … … 169 81 task_retval(0); 170 82 async_manager(); 171 /* not reached */ 83 84 /* Not reached */ 172 85 return 0; 173 86 174 87 err: 175 88 printf(NAME ": Failed to register file system (%d)\n", rc); … … 179 92 /** 180 93 * @} 181 */ 94 */ -
uspace/srv/fs/fat/fat.h
r52a79081 ra33f0a6 227 227 } fat_node_t; 228 228 229 extern fs_reg_t fat_reg; 230 231 extern void fat_mounted(ipc_callid_t, ipc_call_t *); 232 extern void fat_mount(ipc_callid_t, ipc_call_t *); 233 extern void fat_unmounted(ipc_callid_t, ipc_call_t *); 234 extern void fat_unmount(ipc_callid_t, ipc_call_t *); 235 extern void fat_lookup(ipc_callid_t, ipc_call_t *); 236 extern void fat_read(ipc_callid_t, ipc_call_t *); 237 extern void fat_write(ipc_callid_t, ipc_call_t *); 238 extern void fat_truncate(ipc_callid_t, ipc_call_t *); 239 extern void fat_stat(ipc_callid_t, ipc_call_t *); 240 extern void fat_close(ipc_callid_t, ipc_call_t *); 241 extern void fat_destroy(ipc_callid_t, ipc_call_t *); 242 extern void fat_open_node(ipc_callid_t, ipc_call_t *); 243 extern void fat_stat(ipc_callid_t, ipc_call_t *); 244 extern void fat_sync(ipc_callid_t, ipc_call_t *); 229 extern vfs_out_ops_t fat_ops; 230 extern libfs_ops_t fat_libfs_ops; 245 231 246 232 extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t); -
uspace/srv/fs/fat/fat_idx.c
r52a79081 ra33f0a6 59 59 typedef struct { 60 60 link_t link; 61 devmap_handle_t 61 devmap_handle_t devmap_handle; 62 62 63 63 /** Next unassigned index. */ 64 fs_index_t 64 fs_index_t next; 65 65 /** Number of remaining unassigned indices. */ 66 uint64_t 66 uint64_t remaining; 67 67 68 68 /** Sorted list of intervals of freed indices. */ 69 li nk_t freed_head;69 list_t freed_list; 70 70 } unused_t; 71 71 … … 74 74 75 75 /** List of unused structures. */ 76 static LIST_INITIALIZE(unused_ head);76 static LIST_INITIALIZE(unused_list); 77 77 78 78 static void unused_initialize(unused_t *u, devmap_handle_t devmap_handle) … … 82 82 u->next = 0; 83 83 u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; 84 list_initialize(&u->freed_ head);84 list_initialize(&u->freed_list); 85 85 } 86 86 … … 88 88 { 89 89 unused_t *u; 90 link_t *l;91 90 92 91 if (lock) 93 92 fibril_mutex_lock(&unused_lock); 94 for (l = unused_head.next; l != &unused_head; l = l->next) { 93 94 list_foreach(unused_list, l) { 95 95 u = list_get_instance(l, unused_t, link); 96 96 if (u->devmap_handle == devmap_handle) 97 97 return u; 98 98 } 99 99 100 if (lock) 100 101 fibril_mutex_unlock(&unused_lock); … … 249 250 return false; 250 251 251 if (list_empty(&u->freed_ head)) {252 if (list_empty(&u->freed_list)) { 252 253 if (u->remaining) { 253 254 /* … … 262 263 } else { 263 264 /* There are some freed indices which we can reuse. */ 264 freed_t *f = list_get_instance( u->freed_head.next, freed_t,265 link);265 freed_t *f = list_get_instance(list_first(&u->freed_list), 266 freed_t, link); 266 267 *index = f->first; 267 268 if (f->first++ == f->last) { … … 320 321 link_t *lnk; 321 322 freed_t *n; 322 for (lnk = u->freed_ head.next; lnk != &u->freed_head;323 for (lnk = u->freed_list.head.next; lnk != &u->freed_list.head; 323 324 lnk = lnk->next) { 324 325 freed_t *f = list_get_instance(lnk, freed_t, link); 325 326 if (f->first == index + 1) { 326 327 f->first--; 327 if (lnk->prev != &u->freed_ head)328 if (lnk->prev != &u->freed_list.head) 328 329 try_coalesce_intervals(lnk->prev, lnk, 329 330 lnk); … … 333 334 if (f->last == index - 1) { 334 335 f->last++; 335 if (lnk->next != &u->freed_ head)336 if (lnk->next != &u->freed_list.head) 336 337 try_coalesce_intervals(lnk, lnk->next, 337 338 lnk); … … 359 360 n->first = index; 360 361 n->last = index; 361 list_append(&n->link, &u->freed_ head);362 list_append(&n->link, &u->freed_list); 362 363 } 363 364 fibril_mutex_unlock(&unused_lock); … … 558 559 fibril_mutex_lock(&unused_lock); 559 560 if (!unused_find(devmap_handle, false)) { 560 list_append(&u->link, &unused_ head);561 list_append(&u->link, &unused_list); 561 562 } else { 562 563 free(u); … … 594 595 fibril_mutex_unlock(&unused_lock); 595 596 596 while (!list_empty(&u->freed_ head)) {597 while (!list_empty(&u->freed_list)) { 597 598 freed_t *f; 598 f = list_get_instance( u->freed_head.next, freed_t, link);599 f = list_get_instance(list_first(&u->freed_list), freed_t, link); 599 600 list_remove(&f->link); 600 601 free(f); -
uspace/srv/fs/fat/fat_ops.c
r52a79081 ra33f0a6 70 70 71 71 /** List of cached free FAT nodes. */ 72 static LIST_INITIALIZE(ffn_ head);72 static LIST_INITIALIZE(ffn_list); 73 73 74 74 /* … … 88 88 static aoff64_t fat_size_get(fs_node_t *); 89 89 static unsigned fat_lnkcnt_get(fs_node_t *); 90 static char fat_plb_get_char(unsigned);91 90 static bool fat_is_directory(fs_node_t *); 92 91 static bool fat_is_file(fs_node_t *node); … … 150 149 static int fat_node_fini_by_devmap_handle(devmap_handle_t devmap_handle) 151 150 { 152 link_t *lnk;153 151 fat_node_t *nodep; 154 152 int rc; … … 162 160 restart: 163 161 fibril_mutex_lock(&ffn_mutex); 164 for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) {162 list_foreach(ffn_list, lnk) { 165 163 nodep = list_get_instance(lnk, fat_node_t, ffn_link); 166 164 if (!fibril_mutex_trylock(&nodep->lock)) { … … 199 197 free(nodep); 200 198 201 /* Need to restart because we changed the ffn_headlist. */199 /* Need to restart because we changed ffn_list. */ 202 200 goto restart; 203 201 } … … 214 212 215 213 fibril_mutex_lock(&ffn_mutex); 216 if (!list_empty(&ffn_ head)) {214 if (!list_empty(&ffn_list)) { 217 215 /* Try to use a cached free node structure. */ 218 216 fat_idx_t *idxp_tmp; 219 nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link); 217 nodep = list_get_instance(list_first(&ffn_list), fat_node_t, 218 ffn_link); 220 219 if (!fibril_mutex_trylock(&nodep->lock)) 221 220 goto skip_cache; … … 464 463 if (nodep->idx) { 465 464 fibril_mutex_lock(&ffn_mutex); 466 list_append(&nodep->ffn_link, &ffn_ head);465 list_append(&nodep->ffn_link, &ffn_list); 467 466 fibril_mutex_unlock(&ffn_mutex); 468 467 } else { … … 823 822 } 824 823 825 char fat_plb_get_char(unsigned pos)826 {827 return fat_reg.plb_ro[pos % PLB_SIZE];828 }829 830 824 bool fat_is_directory(fs_node_t *fn) 831 825 { … … 858 852 .size_get = fat_size_get, 859 853 .lnkcnt_get = fat_lnkcnt_get, 860 .plb_get_char = fat_plb_get_char,861 854 .is_directory = fat_is_directory, 862 855 .is_file = fat_is_file, … … 865 858 866 859 /* 867 * VFSoperations.860 * FAT VFS_OUT operations. 868 861 */ 869 862 870 void fat_mounted(ipc_callid_t rid, ipc_call_t *request) 871 { 872 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 863 static int 864 fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index, 865 aoff64_t *size, unsigned *linkcnt) 866 { 873 867 enum cache_mode cmode; 874 868 fat_bs_t *bs; 875 876 /* Accept the mount options */ 877 char *opts; 878 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 879 880 if (rc != EOK) { 881 async_answer_0(rid, rc); 882 return; 883 } 869 int rc; 884 870 885 871 /* Check for option enabling write through. */ … … 889 875 cmode = CACHE_MODE_WB; 890 876 891 free(opts);892 893 877 /* initialize libblock */ 894 rc = block_init(devmap_handle, BS_SIZE); 895 if (rc != EOK) { 896 async_answer_0(rid, rc); 897 return; 898 } 878 rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE); 879 if (rc != EOK) 880 return rc; 899 881 900 882 /* prepare the boot block */ … … 902 884 if (rc != EOK) { 903 885 block_fini(devmap_handle); 904 async_answer_0(rid, rc); 905 return; 886 return rc; 906 887 } 907 888 … … 911 892 if (BPS(bs) != BS_SIZE) { 912 893 block_fini(devmap_handle); 913 async_answer_0(rid, ENOTSUP); 914 return; 894 return ENOTSUP; 915 895 } 916 896 … … 919 899 if (rc != EOK) { 920 900 block_fini(devmap_handle); 921 async_answer_0(rid, rc); 922 return; 901 return rc; 923 902 } 924 903 … … 928 907 (void) block_cache_fini(devmap_handle); 929 908 block_fini(devmap_handle); 930 async_answer_0(rid, rc); 931 return; 909 return rc; 932 910 } 933 911 … … 936 914 (void) block_cache_fini(devmap_handle); 937 915 block_fini(devmap_handle); 938 async_answer_0(rid, rc); 939 return; 916 return rc; 940 917 } 941 918 … … 946 923 block_fini(devmap_handle); 947 924 fat_idx_fini_by_devmap_handle(devmap_handle); 948 async_answer_0(rid, ENOMEM); 949 return; 925 return ENOMEM; 950 926 } 951 927 … … 957 933 block_fini(devmap_handle); 958 934 fat_idx_fini_by_devmap_handle(devmap_handle); 959 async_answer_0(rid, ENOMEM); 960 return; 935 return ENOMEM; 961 936 } 962 937 fat_node_initialize(rootp); … … 969 944 block_fini(devmap_handle); 970 945 fat_idx_fini_by_devmap_handle(devmap_handle); 971 async_answer_0(rid, ENOMEM); 972 return; 946 return ENOMEM; 973 947 } 974 948 assert(ridxp->index == 0); … … 1004 978 fibril_mutex_unlock(&ridxp->lock); 1005 979 1006 async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt); 1007 } 1008 1009 void fat_mount(ipc_callid_t rid, ipc_call_t *request) 1010 { 1011 libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1012 } 1013 1014 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1015 { 1016 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 980 *index = ridxp->index; 981 *size = rootp->size; 982 *linkcnt = rootp->lnkcnt; 983 984 return EOK; 985 } 986 987 static int fat_unmounted(devmap_handle_t devmap_handle) 988 { 1017 989 fs_node_t *fn; 1018 990 fat_node_t *nodep; … … 1020 992 1021 993 rc = fat_root_get(&fn, devmap_handle); 1022 if (rc != EOK) { 1023 async_answer_0(rid, rc); 1024 return; 1025 } 994 if (rc != EOK) 995 return rc; 1026 996 nodep = FAT_NODE(fn); 1027 997 … … 1032 1002 if (nodep->refcnt != 2) { 1033 1003 (void) fat_node_put(fn); 1034 async_answer_0(rid, EBUSY); 1035 return; 1004 return EBUSY; 1036 1005 } 1037 1006 … … 1052 1021 block_fini(devmap_handle); 1053 1022 1054 async_answer_0(rid, EOK); 1055 } 1056 1057 void fat_unmount(ipc_callid_t rid, ipc_call_t *request) 1058 { 1059 libfs_unmount(&fat_libfs_ops, rid, request); 1060 } 1061 1062 void fat_lookup(ipc_callid_t rid, ipc_call_t *request) 1063 { 1064 libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1065 } 1066 1067 void fat_read(ipc_callid_t rid, ipc_call_t *request) 1068 { 1069 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1070 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1071 aoff64_t pos = 1072 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1023 return EOK; 1024 } 1025 1026 static int 1027 fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1028 size_t *rbytes) 1029 { 1073 1030 fs_node_t *fn; 1074 1031 fat_node_t *nodep; … … 1079 1036 1080 1037 rc = fat_node_get(&fn, devmap_handle, index); 1081 if (rc != EOK) { 1082 async_answer_0(rid, rc); 1083 return; 1084 } 1085 if (!fn) { 1086 async_answer_0(rid, ENOENT); 1087 return; 1088 } 1038 if (rc != EOK) 1039 return rc; 1040 if (!fn) 1041 return ENOENT; 1089 1042 nodep = FAT_NODE(fn); 1090 1043 … … 1094 1047 fat_node_put(fn); 1095 1048 async_answer_0(callid, EINVAL); 1096 async_answer_0(rid, EINVAL); 1097 return; 1049 return EINVAL; 1098 1050 } 1099 1051 … … 1118 1070 fat_node_put(fn); 1119 1071 async_answer_0(callid, rc); 1120 async_answer_0(rid, rc); 1121 return; 1072 return rc; 1122 1073 } 1123 1074 (void) async_data_read_finalize(callid, … … 1126 1077 if (rc != EOK) { 1127 1078 fat_node_put(fn); 1128 async_answer_0(rid, rc); 1129 return; 1079 return rc; 1130 1080 } 1131 1081 } … … 1155 1105 (void) fat_node_put(fn); 1156 1106 async_answer_0(callid, rc); 1157 async_answer_0(rid, rc); 1158 return; 1107 return rc; 1159 1108 1160 1109 miss: … … 1164 1113 rc = fat_node_put(fn); 1165 1114 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1166 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);1167 return ;1115 *rbytes = 0; 1116 return rc != EOK ? rc : ENOENT; 1168 1117 1169 1118 hit: … … 1177 1126 1178 1127 rc = fat_node_put(fn); 1179 async_answer_1(rid, rc, (sysarg_t)bytes); 1180 } 1181 1182 void fat_write(ipc_callid_t rid, ipc_call_t *request) 1183 { 1184 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1185 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1186 aoff64_t pos = 1187 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1128 *rbytes = bytes; 1129 return rc; 1130 } 1131 1132 static int 1133 fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1134 size_t *wbytes, aoff64_t *nsize) 1135 { 1188 1136 fs_node_t *fn; 1189 1137 fat_node_t *nodep; 1190 1138 fat_bs_t *bs; 1191 size_t bytes , size;1139 size_t bytes; 1192 1140 block_t *b; 1193 1141 aoff64_t boundary; … … 1196 1144 1197 1145 rc = fat_node_get(&fn, devmap_handle, index); 1198 if (rc != EOK) { 1199 async_answer_0(rid, rc); 1200 return; 1201 } 1202 if (!fn) { 1203 async_answer_0(rid, ENOENT); 1204 return; 1205 } 1146 if (rc != EOK) 1147 return rc; 1148 if (!fn) 1149 return ENOENT; 1206 1150 nodep = FAT_NODE(fn); 1207 1151 … … 1211 1155 (void) fat_node_put(fn); 1212 1156 async_answer_0(callid, EINVAL); 1213 async_answer_0(rid, EINVAL); 1214 return; 1157 return EINVAL; 1215 1158 } 1216 1159 … … 1240 1183 (void) fat_node_put(fn); 1241 1184 async_answer_0(callid, rc); 1242 async_answer_0(rid, rc); 1243 return; 1185 return rc; 1244 1186 } 1245 1187 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags); … … 1247 1189 (void) fat_node_put(fn); 1248 1190 async_answer_0(callid, rc); 1249 async_answer_0(rid, rc); 1250 return; 1191 return rc; 1251 1192 } 1252 1193 (void) async_data_write_finalize(callid, … … 1256 1197 if (rc != EOK) { 1257 1198 (void) fat_node_put(fn); 1258 async_answer_0(rid, rc); 1259 return; 1199 return rc; 1260 1200 } 1261 1201 if (pos + bytes > nodep->size) { … … 1263 1203 nodep->dirty = true; /* need to sync node */ 1264 1204 } 1265 size = nodep->size; 1205 *wbytes = bytes; 1206 *nsize = nodep->size; 1266 1207 rc = fat_node_put(fn); 1267 async_answer_2(rid, rc, bytes, nodep->size); 1268 return; 1208 return rc; 1269 1209 } else { 1270 1210 /* … … 1282 1222 (void) fat_node_put(fn); 1283 1223 async_answer_0(callid, rc); 1284 async_answer_0(rid, rc); 1285 return; 1224 return rc; 1286 1225 } 1287 1226 /* zero fill any gaps */ … … 1291 1230 (void) fat_node_put(fn); 1292 1231 async_answer_0(callid, rc); 1293 async_answer_0(rid, rc); 1294 return; 1232 return rc; 1295 1233 } 1296 1234 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL, … … 1300 1238 (void) fat_node_put(fn); 1301 1239 async_answer_0(callid, rc); 1302 async_answer_0(rid, rc); 1303 return; 1240 return rc; 1304 1241 } 1305 1242 (void) async_data_write_finalize(callid, … … 1310 1247 (void) fat_free_clusters(bs, devmap_handle, mcl); 1311 1248 (void) fat_node_put(fn); 1312 async_answer_0(rid, rc); 1313 return; 1249 return rc; 1314 1250 } 1315 1251 /* … … 1321 1257 (void) fat_free_clusters(bs, devmap_handle, mcl); 1322 1258 (void) fat_node_put(fn); 1323 async_answer_0(rid, rc);1324 return;1325 }1326 nodep->size = size = pos + bytes;1259 return rc; 1260 } 1261 *nsize = nodep->size = pos + bytes; 1262 rc = fat_node_put(fn); 1327 1263 nodep->dirty = true; /* need to sync node */ 1328 rc = fat_node_put(fn); 1329 async_answer_2(rid, rc, bytes, size); 1330 return; 1331 } 1332 } 1333 1334 void fat_truncate(ipc_callid_t rid, ipc_call_t *request) 1335 { 1336 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1337 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1338 aoff64_t size = 1339 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1264 *wbytes = bytes; 1265 return rc; 1266 } 1267 } 1268 1269 static int 1270 fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 1271 { 1340 1272 fs_node_t *fn; 1341 1273 fat_node_t *nodep; … … 1344 1276 1345 1277 rc = fat_node_get(&fn, devmap_handle, index); 1346 if (rc != EOK) { 1347 async_answer_0(rid, rc); 1348 return; 1349 } 1350 if (!fn) { 1351 async_answer_0(rid, ENOENT); 1352 return; 1353 } 1278 if (rc != EOK) 1279 return rc; 1280 if (!fn) 1281 return ENOENT; 1354 1282 nodep = FAT_NODE(fn); 1355 1283 … … 1395 1323 out: 1396 1324 fat_node_put(fn); 1397 async_answer_0(rid, rc); 1398 return; 1399 } 1400 1401 void fat_close(ipc_callid_t rid, ipc_call_t *request) 1402 { 1403 async_answer_0(rid, EOK); 1404 } 1405 1406 void fat_destroy(ipc_callid_t rid, ipc_call_t *request) 1407 { 1408 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 1409 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1325 return rc; 1326 } 1327 1328 static int fat_close(devmap_handle_t devmap_handle, fs_index_t index) 1329 { 1330 return EOK; 1331 } 1332 1333 static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index) 1334 { 1410 1335 fs_node_t *fn; 1411 1336 fat_node_t *nodep; … … 1413 1338 1414 1339 rc = fat_node_get(&fn, devmap_handle, index); 1415 if (rc != EOK) { 1416 async_answer_0(rid, rc); 1417 return; 1418 } 1419 if (!fn) { 1420 async_answer_0(rid, ENOENT); 1421 return; 1422 } 1340 if (rc != EOK) 1341 return rc; 1342 if (!fn) 1343 return ENOENT; 1423 1344 1424 1345 nodep = FAT_NODE(fn); … … 1430 1351 1431 1352 rc = fat_destroy_node(fn); 1432 async_answer_0(rid, rc); 1433 } 1434 1435 void fat_open_node(ipc_callid_t rid, ipc_call_t *request) 1436 { 1437 libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1438 } 1439 1440 void fat_stat(ipc_callid_t rid, ipc_call_t *request) 1441 { 1442 libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1443 } 1444 1445 void fat_sync(ipc_callid_t rid, ipc_call_t *request) 1446 { 1447 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1448 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1449 1353 return rc; 1354 } 1355 1356 static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index) 1357 { 1450 1358 fs_node_t *fn; 1451 1359 int rc = fat_node_get(&fn, devmap_handle, index); 1452 if (rc != EOK) { 1453 async_answer_0(rid, rc); 1454 return; 1455 } 1456 if (!fn) { 1457 async_answer_0(rid, ENOENT); 1458 return; 1459 } 1360 if (rc != EOK) 1361 return rc; 1362 if (!fn) 1363 return ENOENT; 1460 1364 1461 1365 fat_node_t *nodep = FAT_NODE(fn); … … 1465 1369 1466 1370 fat_node_put(fn); 1467 async_answer_0(rid, rc); 1468 } 1371 return rc; 1372 } 1373 1374 vfs_out_ops_t fat_ops = { 1375 .mounted = fat_mounted, 1376 .unmounted = fat_unmounted, 1377 .read = fat_read, 1378 .write = fat_write, 1379 .truncate = fat_truncate, 1380 .close = fat_close, 1381 .destroy = fat_destroy, 1382 .sync = fat_sync, 1383 }; 1469 1384 1470 1385 /** -
uspace/srv/fs/tmpfs/Makefile
r52a79081 ra33f0a6 32 32 EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) 33 33 BINARY = tmpfs 34 STATIC_NEEDED = y 34 35 35 36 SOURCES = \ -
uspace/srv/fs/tmpfs/tmpfs.c
r52a79081 ra33f0a6 30 30 /** @addtogroup fs 31 31 * @{ 32 */ 32 */ 33 33 34 34 /** … … 43 43 #include "tmpfs.h" 44 44 #include <ipc/services.h> 45 #include < ipc/ns.h>45 #include <ns.h> 46 46 #include <async.h> 47 47 #include <errno.h> … … 61 61 }; 62 62 63 fs_reg_t tmpfs_reg;64 65 /**66 * This connection fibril processes VFS requests from VFS.67 *68 * In order to support simultaneous VFS requests, our design is as follows.69 * The connection fibril accepts VFS requests from VFS. If there is only one70 * instance of the fibril, VFS will need to serialize all VFS requests it sends71 * to FAT. To overcome this bottleneck, VFS can send TMPFS the72 * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be73 * created, which in turn will accept the call. Thus, a new phone will be74 * opened for VFS.75 *76 * There are few issues with this arrangement. First, VFS can run out of77 * available phones. In that case, VFS can close some other phones or use one78 * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate79 * the connection. VFS should then just make use of already existing phones and80 * route its requests through them. To avoid paying the fibril creation price81 * upon each request, TMPFS might want to keep the connections open after the82 * request has been completed.83 */84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall)85 {86 if (iid) {87 /*88 * This only happens for connections opened by89 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections90 * created by IPC_M_CONNECT_TO_ME.91 */92 async_answer_0(iid, EOK);93 }94 95 dprintf(NAME ": connection opened\n");96 while (1) {97 ipc_callid_t callid;98 ipc_call_t call;99 100 callid = async_get_call(&call);101 switch (IPC_GET_IMETHOD(call)) {102 case IPC_M_PHONE_HUNGUP:103 return;104 case VFS_OUT_MOUNTED:105 tmpfs_mounted(callid, &call);106 break;107 case VFS_OUT_MOUNT:108 tmpfs_mount(callid, &call);109 break;110 case VFS_OUT_UNMOUNTED:111 tmpfs_unmounted(callid, &call);112 break;113 case VFS_OUT_UNMOUNT:114 tmpfs_unmount(callid, &call);115 break;116 case VFS_OUT_LOOKUP:117 tmpfs_lookup(callid, &call);118 break;119 case VFS_OUT_READ:120 tmpfs_read(callid, &call);121 break;122 case VFS_OUT_WRITE:123 tmpfs_write(callid, &call);124 break;125 case VFS_OUT_TRUNCATE:126 tmpfs_truncate(callid, &call);127 break;128 case VFS_OUT_CLOSE:129 tmpfs_close(callid, &call);130 break;131 case VFS_OUT_DESTROY:132 tmpfs_destroy(callid, &call);133 break;134 case VFS_OUT_OPEN_NODE:135 tmpfs_open_node(callid, &call);136 break;137 case VFS_OUT_STAT:138 tmpfs_stat(callid, &call);139 break;140 case VFS_OUT_SYNC:141 tmpfs_sync(callid, &call);142 break;143 default:144 async_answer_0(callid, ENOTSUP);145 break;146 }147 }148 }149 150 63 int main(int argc, char **argv) 151 64 { 152 65 printf(NAME ": HelenOS TMPFS file system server\n"); 153 66 154 67 if (!tmpfs_init()) { 155 68 printf(NAME ": failed to initialize TMPFS\n"); 156 69 return -1; 157 70 } 158 159 int vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 160 if (vfs_phone < EOK) { 71 72 async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 73 SERVICE_VFS, 0, 0); 74 if (!vfs_sess) { 161 75 printf(NAME ": Unable to connect to VFS\n"); 162 76 return -1; 163 77 } 164 165 int rc = fs_register(vfs_ phone, &tmpfs_reg, &tmpfs_vfs_info,166 tmpfs_connection);78 79 int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops, 80 &tmpfs_libfs_ops); 167 81 if (rc != EOK) { 168 82 printf(NAME ": Failed to register file system (%d)\n", rc); 169 83 return rc; 170 84 } 171 85 172 86 printf(NAME ": Accepting connections\n"); 173 87 task_retval(0); 174 88 async_manager(); 175 /* not reached */ 89 90 /* Not reached */ 176 91 return 0; 177 92 } … … 179 94 /** 180 95 * @} 181 */ 96 */ -
uspace/srv/fs/tmpfs/tmpfs.h
r52a79081 ra33f0a6 67 67 size_t size; /**< File size if type is TMPFS_FILE. */ 68 68 void *data; /**< File content's if type is TMPFS_FILE. */ 69 li nk_t cs_head; /**< Head of child's siblings list. */69 list_t cs_list; /**< Child's siblings list. */ 70 70 } tmpfs_node_t; 71 71 72 extern fs_reg_t tmpfs_reg; 73 72 extern vfs_out_ops_t tmpfs_ops; 74 73 extern libfs_ops_t tmpfs_libfs_ops; 75 74 76 75 extern bool tmpfs_init(void); 77 78 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);79 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);80 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);81 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);82 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);83 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);84 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);85 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);86 extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);87 extern void tmpfs_close(ipc_callid_t, ipc_call_t *);88 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);89 extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);90 extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);91 92 76 extern bool tmpfs_restore(devmap_handle_t); 93 77 -
uspace/srv/fs/tmpfs/tmpfs_dump.c
r52a79081 ra33f0a6 167 167 int rc; 168 168 169 rc = block_init( dev, TMPFS_COMM_SIZE);169 rc = block_init(EXCHANGE_SERIALIZE, dev, TMPFS_COMM_SIZE); 170 170 if (rc != EOK) 171 171 return false; -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r52a79081 ra33f0a6 85 85 static int tmpfs_has_children(bool *has_children, fs_node_t *fn) 86 86 { 87 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_ head);87 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_list); 88 88 return EOK; 89 89 } … … 102 102 { 103 103 return TMPFS_NODE(fn)->lnkcnt; 104 }105 106 static char tmpfs_plb_get_char(unsigned pos)107 {108 return tmpfs_reg.plb_ro[pos % PLB_SIZE];109 104 } 110 105 … … 139 134 .size_get = tmpfs_size_get, 140 135 .lnkcnt_get = tmpfs_lnkcnt_get, 141 .plb_get_char = tmpfs_plb_get_char,142 136 .is_directory = tmpfs_is_directory, 143 137 .is_file = tmpfs_is_file, … … 180 174 nh_link); 181 175 182 while (!list_empty(&nodep->cs_ head)) {183 tmpfs_dentry_t *dentryp = list_get_instance( nodep->cs_head.next,184 tmpfs_dentry_t, link);176 while (!list_empty(&nodep->cs_list)) { 177 tmpfs_dentry_t *dentryp = list_get_instance( 178 list_first(&nodep->cs_list), tmpfs_dentry_t, link); 185 179 186 180 assert(nodep->type == TMPFS_DIRECTORY); … … 214 208 nodep->data = NULL; 215 209 link_initialize(&nodep->nh_link); 216 list_initialize(&nodep->cs_ head);210 list_initialize(&nodep->cs_list); 217 211 } 218 212 … … 262 256 { 263 257 tmpfs_node_t *parentp = TMPFS_NODE(pfn); 264 link_t *lnk; 265 266 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 267 lnk = lnk->next) { 258 259 list_foreach(parentp->cs_list, lnk) { 268 260 tmpfs_dentry_t *dentryp; 269 261 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); … … 353 345 354 346 assert(!nodep->lnkcnt); 355 assert(list_empty(&nodep->cs_ head));347 assert(list_empty(&nodep->cs_list)); 356 348 357 349 unsigned long key[] = { … … 373 365 tmpfs_node_t *childp = TMPFS_NODE(cfn); 374 366 tmpfs_dentry_t *dentryp; 375 link_t *lnk;376 367 377 368 assert(parentp->type == TMPFS_DIRECTORY); 378 369 379 370 /* Check for duplicit entries. */ 380 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 381 lnk = lnk->next) { 371 list_foreach(parentp->cs_list, lnk) { 382 372 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 383 373 if (!str_cmp(dentryp->name, nm)) … … 401 391 dentryp->node = childp; 402 392 childp->lnkcnt++; 403 list_append(&dentryp->link, &parentp->cs_ head);393 list_append(&dentryp->link, &parentp->cs_list); 404 394 405 395 return EOK; … … 411 401 tmpfs_node_t *childp = NULL; 412 402 tmpfs_dentry_t *dentryp; 413 link_t *lnk;414 403 415 404 if (!parentp) 416 405 return EBUSY; 417 406 418 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 419 lnk = lnk->next) { 407 list_foreach(parentp->cs_list, lnk) { 420 408 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 421 409 if (!str_cmp(dentryp->name, nm)) { … … 423 411 assert(FS_NODE(childp) == cfn); 424 412 break; 425 } 413 } 426 414 } 427 415 … … 429 417 return ENOENT; 430 418 431 if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_ head))419 if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_list)) 432 420 return ENOTEMPTY; 433 421 … … 439 427 } 440 428 441 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 442 { 443 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 429 /* 430 * Implementation of the VFS_OUT interface. 431 */ 432 433 static int 434 tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts, 435 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 436 { 444 437 fs_node_t *rootfn; 445 438 int rc; 446 439 447 /* Accept the mount options. */448 char *opts;449 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);450 if (rc != EOK) {451 async_answer_0(rid, rc);452 return;453 }454 455 440 /* Check if this device is not already mounted. */ 456 441 rc = tmpfs_root_get(&rootfn, devmap_handle); 457 442 if ((rc == EOK) && (rootfn)) { 458 443 (void) tmpfs_node_put(rootfn); 459 free(opts); 460 async_answer_0(rid, EEXIST); 461 return; 444 return EEXIST; 462 445 } 463 446 464 447 /* Initialize TMPFS instance. */ 465 if (!tmpfs_instance_init(devmap_handle)) { 466 free(opts); 467 async_answer_0(rid, ENOMEM); 468 return; 469 } 448 if (!tmpfs_instance_init(devmap_handle)) 449 return ENOMEM; 470 450 471 451 rc = tmpfs_root_get(&rootfn, devmap_handle); … … 473 453 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 474 454 if (str_cmp(opts, "restore") == 0) { 475 if (tmpfs_restore(devmap_handle)) 476 async_answer_3(rid, EOK, rootp->index, rootp->size, 477 rootp->lnkcnt); 478 else 479 async_answer_0(rid, ELIMIT); 480 } else { 481 async_answer_3(rid, EOK, rootp->index, rootp->size, 482 rootp->lnkcnt); 483 } 484 free(opts); 485 } 486 487 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) 488 { 489 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 490 } 491 492 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 493 { 494 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 495 455 if (!tmpfs_restore(devmap_handle)) 456 return ELIMIT; 457 } 458 459 *index = rootp->index; 460 *size = rootp->size; 461 *lnkcnt = rootp->lnkcnt; 462 463 return EOK; 464 } 465 466 static int tmpfs_unmounted(devmap_handle_t devmap_handle) 467 { 496 468 tmpfs_instance_done(devmap_handle); 497 async_answer_0(rid, EOK); 498 } 499 500 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 501 { 502 libfs_unmount(&tmpfs_libfs_ops, rid, request); 503 } 504 505 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 506 { 507 libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 508 } 509 510 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 511 { 512 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 513 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 514 aoff64_t pos = 515 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 516 469 return EOK; 470 } 471 472 static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 473 size_t *rbytes) 474 { 517 475 /* 518 476 * Lookup the respective TMPFS node. … … 524 482 }; 525 483 hlp = hash_table_find(&nodes, key); 526 if (!hlp) { 527 async_answer_0(rid, ENOENT); 528 return; 529 } 484 if (!hlp) 485 return ENOENT; 530 486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 531 487 nh_link); … … 538 494 if (!async_data_read_receive(&callid, &size)) { 539 495 async_answer_0(callid, EINVAL); 540 async_answer_0(rid, EINVAL); 541 return; 496 return EINVAL; 542 497 } 543 498 … … 550 505 tmpfs_dentry_t *dentryp; 551 506 link_t *lnk; 552 aoff64_t i;553 507 554 508 assert(nodep->type == TMPFS_DIRECTORY); … … 559 513 * hash table. 560 514 */ 561 for (i = 0, lnk = nodep->cs_head.next; 562 (i < pos) && (lnk != &nodep->cs_head); 563 i++, lnk = lnk->next) 564 ; 565 566 if (lnk == &nodep->cs_head) { 515 lnk = list_nth(&nodep->cs_list, pos); 516 517 if (lnk == NULL) { 567 518 async_answer_0(callid, ENOENT); 568 async_answer_1(rid, ENOENT, 0); 569 return; 519 return ENOENT; 570 520 } 571 521 … … 577 527 } 578 528 579 /* 580 * Answer the VFS_READ call. 581 */ 582 async_answer_1(rid, EOK, bytes); 583 } 584 585 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 586 { 587 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 588 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 589 aoff64_t pos = 590 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 591 529 *rbytes = bytes; 530 return EOK; 531 } 532 533 static int 534 tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 535 size_t *wbytes, aoff64_t *nsize) 536 { 592 537 /* 593 538 * Lookup the respective TMPFS node. … … 599 544 }; 600 545 hlp = hash_table_find(&nodes, key); 601 if (!hlp) { 602 async_answer_0(rid, ENOENT); 603 return; 604 } 546 if (!hlp) 547 return ENOENT; 605 548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 606 549 nh_link); … … 613 556 if (!async_data_write_receive(&callid, &size)) { 614 557 async_answer_0(callid, EINVAL); 615 async_answer_0(rid, EINVAL); 616 return; 558 return EINVAL; 617 559 } 618 560 … … 622 564 if (pos + size <= nodep->size) { 623 565 /* The file size is not changing. */ 624 (void) async_data_write_finalize(callid, nodep->data + pos, size);625 async_answer_2(rid, EOK, size, nodep->size);626 return;566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 size); 568 goto out; 627 569 } 628 570 size_t delta = (pos + size) - nodep->size; … … 637 579 if (!newdata) { 638 580 async_answer_0(callid, ENOMEM); 639 async_answer_2(rid, EOK, 0, nodep->size);640 return;581 size = 0; 582 goto out; 641 583 } 642 584 /* Clear any newly allocated memory in order to emulate gaps. */ … … 645 587 nodep->data = newdata; 646 588 (void) async_data_write_finalize(callid, nodep->data + pos, size); 647 async_answer_2(rid, EOK, size, nodep->size); 648 } 649 650 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 651 { 652 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 653 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 654 aoff64_t size = 655 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 656 589 590 out: 591 *wbytes = size; 592 *nsize = nodep->size; 593 return EOK; 594 } 595 596 static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, 597 aoff64_t size) 598 { 657 599 /* 658 600 * Lookup the respective TMPFS node. … … 663 605 }; 664 606 link_t *hlp = hash_table_find(&nodes, key); 665 if (!hlp) { 666 async_answer_0(rid, ENOENT); 667 return; 668 } 669 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 670 nh_link); 671 672 if (size == nodep->size) { 673 async_answer_0(rid, EOK); 674 return; 675 } 676 677 if (size > SIZE_MAX) { 678 async_answer_0(rid, ENOMEM); 679 return; 680 } 607 if (!hlp) 608 return ENOENT; 609 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link); 610 611 if (size == nodep->size) 612 return EOK; 613 614 if (size > SIZE_MAX) 615 return ENOMEM; 681 616 682 617 void *newdata = realloc(nodep->data, size); 683 if (!newdata) { 684 async_answer_0(rid, ENOMEM); 685 return; 686 } 618 if (!newdata) 619 return ENOMEM; 687 620 688 621 if (size > nodep->size) { … … 693 626 nodep->size = size; 694 627 nodep->data = newdata; 695 async_answer_0(rid, EOK); 696 } 697 698 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 699 { 700 async_answer_0(rid, EOK); 701 } 702 703 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 704 { 705 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 706 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 707 int rc; 708 628 return EOK; 629 } 630 631 static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index) 632 { 633 return EOK; 634 } 635 636 static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 637 { 709 638 link_t *hlp; 710 639 unsigned long key[] = { … … 713 642 }; 714 643 hlp = hash_table_find(&nodes, key); 715 if (!hlp) { 716 async_answer_0(rid, ENOENT); 717 return; 718 } 644 if (!hlp) 645 return ENOENT; 719 646 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 720 647 nh_link); 721 rc = tmpfs_destroy_node(FS_NODE(nodep)); 722 async_answer_0(rid, rc); 723 } 724 725 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request) 726 { 727 libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 728 } 729 730 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request) 731 { 732 libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 733 } 734 735 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request) 648 return tmpfs_destroy_node(FS_NODE(nodep)); 649 } 650 651 static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 736 652 { 737 653 /* … … 739 655 * thus the sync operation is a no-op. 740 656 */ 741 async_answer_0(rid, EOK); 742 } 657 return EOK; 658 } 659 660 vfs_out_ops_t tmpfs_ops = { 661 .mounted = tmpfs_mounted, 662 .unmounted = tmpfs_unmounted, 663 .read = tmpfs_read, 664 .write = tmpfs_write, 665 .truncate = tmpfs_truncate, 666 .close = tmpfs_close, 667 .destroy = tmpfs_destroy, 668 .sync = tmpfs_sync, 669 }; 743 670 744 671 /** 745 672 * @} 746 673 */ 674
Note:
See TracChangeset
for help on using the changeset viewer.