Changes in uspace/srv/fs/tmpfs/tmpfs_ops.c [b33870b:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
rb33870b rffa2c8ef 69 69 /* Forward declarations of static functions. */ 70 70 static int tmpfs_match(fs_node_t **, fs_node_t *, const char *); 71 static int tmpfs_node_get(fs_node_t **, service_id_t, fs_index_t);71 static int tmpfs_node_get(fs_node_t **, devmap_handle_t, fs_index_t); 72 72 static int tmpfs_node_open(fs_node_t *); 73 73 static int tmpfs_node_put(fs_node_t *); 74 static int tmpfs_create_node(fs_node_t **, service_id_t, int);74 static int tmpfs_create_node(fs_node_t **, devmap_handle_t, int); 75 75 static int tmpfs_destroy_node(fs_node_t *); 76 76 static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *); … … 78 78 79 79 /* Implementation of helper functions. */ 80 static int tmpfs_root_get(fs_node_t **rfn, service_id_t service_id)81 { 82 return tmpfs_node_get(rfn, service_id, TMPFS_SOME_ROOT);80 static int tmpfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle) 81 { 82 return tmpfs_node_get(rfn, devmap_handle, TMPFS_SOME_ROOT); 83 83 } 84 84 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_ list);87 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_head); 88 88 return EOK; 89 89 } … … 104 104 } 105 105 106 static char tmpfs_plb_get_char(unsigned pos) 107 { 108 return tmpfs_reg.plb_ro[pos % PLB_SIZE]; 109 } 110 106 111 static bool tmpfs_is_directory(fs_node_t *fn) 107 112 { … … 114 119 } 115 120 116 static service_id_t tmpfs_service_get(fs_node_t *fn)121 static devmap_handle_t tmpfs_device_get(fs_node_t *fn) 117 122 { 118 123 return 0; … … 134 139 .size_get = tmpfs_size_get, 135 140 .lnkcnt_get = tmpfs_lnkcnt_get, 141 .plb_get_char = tmpfs_plb_get_char, 136 142 .is_directory = tmpfs_is_directory, 137 143 .is_file = tmpfs_is_file, 138 . service_get = tmpfs_service_get144 .device_get = tmpfs_device_get 139 145 }; 140 146 … … 158 164 switch (keys) { 159 165 case 1: 160 return (nodep-> service_id== key[NODES_KEY_DEV]);166 return (nodep->devmap_handle == key[NODES_KEY_DEV]); 161 167 case 2: 162 return ((nodep-> service_id== key[NODES_KEY_DEV]) &&168 return ((nodep->devmap_handle == key[NODES_KEY_DEV]) && 163 169 (nodep->index == key[NODES_KEY_INDEX])); 164 170 default: … … 174 180 nh_link); 175 181 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);182 while (!list_empty(&nodep->cs_head)) { 183 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next, 184 tmpfs_dentry_t, link); 179 185 180 186 assert(nodep->type == TMPFS_DIRECTORY); … … 202 208 nodep->bp = NULL; 203 209 nodep->index = 0; 204 nodep-> service_id= 0;210 nodep->devmap_handle = 0; 205 211 nodep->type = TMPFS_NONE; 206 212 nodep->lnkcnt = 0; … … 208 214 nodep->data = NULL; 209 215 link_initialize(&nodep->nh_link); 210 list_initialize(&nodep->cs_ list);216 list_initialize(&nodep->cs_head); 211 217 } 212 218 … … 226 232 } 227 233 228 static bool tmpfs_instance_init( service_id_t service_id)234 static bool tmpfs_instance_init(devmap_handle_t devmap_handle) 229 235 { 230 236 fs_node_t *rfn; 231 237 int rc; 232 238 233 rc = tmpfs_create_node(&rfn, service_id, L_DIRECTORY);239 rc = tmpfs_create_node(&rfn, devmap_handle, L_DIRECTORY); 234 240 if (rc != EOK || !rfn) 235 241 return false; … … 238 244 } 239 245 240 static void tmpfs_instance_done( service_id_t service_id)246 static void tmpfs_instance_done(devmap_handle_t devmap_handle) 241 247 { 242 248 unsigned long key[] = { 243 [NODES_KEY_DEV] = service_id249 [NODES_KEY_DEV] = devmap_handle 244 250 }; 245 251 /* … … 256 262 { 257 263 tmpfs_node_t *parentp = TMPFS_NODE(pfn); 258 259 list_foreach(parentp->cs_list, lnk) { 264 link_t *lnk; 265 266 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 267 lnk = lnk->next) { 260 268 tmpfs_dentry_t *dentryp; 261 269 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); … … 270 278 } 271 279 272 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)280 int tmpfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index) 273 281 { 274 282 unsigned long key[] = { 275 [NODES_KEY_DEV] = service_id,283 [NODES_KEY_DEV] = devmap_handle, 276 284 [NODES_KEY_INDEX] = index 277 285 }; … … 299 307 } 300 308 301 int tmpfs_create_node(fs_node_t **rfn, service_id_t service_id, int lflag)309 int tmpfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag) 302 310 { 303 311 fs_node_t *rootfn; … … 318 326 nodep->bp->data = nodep; /* link the FS and TMPFS nodes */ 319 327 320 rc = tmpfs_root_get(&rootfn, service_id);328 rc = tmpfs_root_get(&rootfn, devmap_handle); 321 329 assert(rc == EOK); 322 330 if (!rootfn) … … 324 332 else 325 333 nodep->index = tmpfs_next_index++; 326 nodep-> service_id = service_id;334 nodep->devmap_handle = devmap_handle; 327 335 if (lflag & L_DIRECTORY) 328 336 nodep->type = TMPFS_DIRECTORY; … … 332 340 /* Insert the new node into the nodes hash table. */ 333 341 unsigned long key[] = { 334 [NODES_KEY_DEV] = nodep-> service_id,342 [NODES_KEY_DEV] = nodep->devmap_handle, 335 343 [NODES_KEY_INDEX] = nodep->index 336 344 }; … … 345 353 346 354 assert(!nodep->lnkcnt); 347 assert(list_empty(&nodep->cs_ list));355 assert(list_empty(&nodep->cs_head)); 348 356 349 357 unsigned long key[] = { 350 [NODES_KEY_DEV] = nodep-> service_id,358 [NODES_KEY_DEV] = nodep->devmap_handle, 351 359 [NODES_KEY_INDEX] = nodep->index 352 360 }; … … 365 373 tmpfs_node_t *childp = TMPFS_NODE(cfn); 366 374 tmpfs_dentry_t *dentryp; 375 link_t *lnk; 367 376 368 377 assert(parentp->type == TMPFS_DIRECTORY); 369 378 370 379 /* Check for duplicit entries. */ 371 list_foreach(parentp->cs_list, lnk) { 380 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 381 lnk = lnk->next) { 372 382 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 373 383 if (!str_cmp(dentryp->name, nm)) … … 391 401 dentryp->node = childp; 392 402 childp->lnkcnt++; 393 list_append(&dentryp->link, &parentp->cs_ list);403 list_append(&dentryp->link, &parentp->cs_head); 394 404 395 405 return EOK; … … 401 411 tmpfs_node_t *childp = NULL; 402 412 tmpfs_dentry_t *dentryp; 413 link_t *lnk; 403 414 404 415 if (!parentp) 405 416 return EBUSY; 406 417 407 list_foreach(parentp->cs_list, lnk) { 418 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 419 lnk = lnk->next) { 408 420 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 409 421 if (!str_cmp(dentryp->name, nm)) { … … 411 423 assert(FS_NODE(childp) == cfn); 412 424 break; 413 } 425 } 414 426 } 415 427 … … 417 429 return ENOENT; 418 430 419 if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_ list))431 if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_head)) 420 432 return ENOTEMPTY; 421 433 … … 427 439 } 428 440 429 /* 430 * Implementation of the VFS_OUT interface. 431 */ 432 433 static int 434 tmpfs_mounted(service_id_t service_id, const char *opts, 435 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 436 { 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); 437 444 fs_node_t *rootfn; 438 445 int rc; 439 446 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 440 455 /* Check if this device is not already mounted. */ 441 rc = tmpfs_root_get(&rootfn, service_id);456 rc = tmpfs_root_get(&rootfn, devmap_handle); 442 457 if ((rc == EOK) && (rootfn)) { 443 458 (void) tmpfs_node_put(rootfn); 444 return EEXIST; 459 free(opts); 460 async_answer_0(rid, EEXIST); 461 return; 445 462 } 446 463 447 464 /* Initialize TMPFS instance. */ 448 if (!tmpfs_instance_init(service_id)) 449 return ENOMEM; 450 451 rc = tmpfs_root_get(&rootfn, service_id); 465 if (!tmpfs_instance_init(devmap_handle)) { 466 free(opts); 467 async_answer_0(rid, ENOMEM); 468 return; 469 } 470 471 rc = tmpfs_root_get(&rootfn, devmap_handle); 452 472 assert(rc == EOK); 453 473 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 454 474 if (str_cmp(opts, "restore") == 0) { 455 if (!tmpfs_restore(service_id)) 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(service_id_t service_id) 467 { 468 tmpfs_instance_done(service_id); 469 return EOK; 470 } 471 472 static int tmpfs_read(service_id_t service_id, fs_index_t index, aoff64_t pos, 473 size_t *rbytes) 474 { 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 496 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 475 517 /* 476 518 * Lookup the respective TMPFS node. … … 478 520 link_t *hlp; 479 521 unsigned long key[] = { 480 [NODES_KEY_DEV] = service_id,522 [NODES_KEY_DEV] = devmap_handle, 481 523 [NODES_KEY_INDEX] = index 482 524 }; 483 525 hlp = hash_table_find(&nodes, key); 484 if (!hlp) 485 return ENOENT; 526 if (!hlp) { 527 async_answer_0(rid, ENOENT); 528 return; 529 } 486 530 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 487 531 nh_link); … … 494 538 if (!async_data_read_receive(&callid, &size)) { 495 539 async_answer_0(callid, EINVAL); 496 return EINVAL; 540 async_answer_0(rid, EINVAL); 541 return; 497 542 } 498 543 … … 505 550 tmpfs_dentry_t *dentryp; 506 551 link_t *lnk; 552 aoff64_t i; 507 553 508 554 assert(nodep->type == TMPFS_DIRECTORY); … … 513 559 * hash table. 514 560 */ 515 lnk = list_nth(&nodep->cs_list, pos); 516 517 if (lnk == NULL) { 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) { 518 567 async_answer_0(callid, ENOENT); 519 return ENOENT; 568 async_answer_1(rid, ENOENT, 0); 569 return; 520 570 } 521 571 … … 527 577 } 528 578 529 *rbytes = bytes; 530 return EOK; 531 } 532 533 static int 534 tmpfs_write(service_id_t service_id, fs_index_t index, aoff64_t pos, 535 size_t *wbytes, aoff64_t *nsize) 536 { 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 537 592 /* 538 593 * Lookup the respective TMPFS node. … … 540 595 link_t *hlp; 541 596 unsigned long key[] = { 542 [NODES_KEY_DEV] = service_id,597 [NODES_KEY_DEV] = devmap_handle, 543 598 [NODES_KEY_INDEX] = index 544 599 }; 545 600 hlp = hash_table_find(&nodes, key); 546 if (!hlp) 547 return ENOENT; 601 if (!hlp) { 602 async_answer_0(rid, ENOENT); 603 return; 604 } 548 605 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 549 606 nh_link); … … 556 613 if (!async_data_write_receive(&callid, &size)) { 557 614 async_answer_0(callid, EINVAL); 558 return EINVAL; 615 async_answer_0(rid, EINVAL); 616 return; 559 617 } 560 618 … … 564 622 if (pos + size <= nodep->size) { 565 623 /* The file size is not changing. */ 566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 568 goto out;624 (void) async_data_write_finalize(callid, nodep->data + pos, size); 625 async_answer_2(rid, EOK, size, nodep->size); 626 return; 569 627 } 570 628 size_t delta = (pos + size) - nodep->size; … … 579 637 if (!newdata) { 580 638 async_answer_0(callid, ENOMEM); 581 size = 0;582 goto out;639 async_answer_2(rid, EOK, 0, nodep->size); 640 return; 583 641 } 584 642 /* Clear any newly allocated memory in order to emulate gaps. */ … … 587 645 nodep->data = newdata; 588 646 (void) async_data_write_finalize(callid, nodep->data + pos, size); 589 590 out: 591 *wbytes = size; 592 *nsize = nodep->size; 593 return EOK; 594 } 595 596 static int tmpfs_truncate(service_id_t service_id, fs_index_t index, 597 aoff64_t size) 598 { 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 599 657 /* 600 658 * Lookup the respective TMPFS node. 601 659 */ 602 660 unsigned long key[] = { 603 [NODES_KEY_DEV] = service_id,661 [NODES_KEY_DEV] = devmap_handle, 604 662 [NODES_KEY_INDEX] = index 605 663 }; 606 664 link_t *hlp = hash_table_find(&nodes, key); 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; 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 } 616 681 617 682 void *newdata = realloc(nodep->data, size); 618 if (!newdata) 619 return ENOMEM; 683 if (!newdata) { 684 async_answer_0(rid, ENOMEM); 685 return; 686 } 620 687 621 688 if (size > nodep->size) { … … 626 693 nodep->size = size; 627 694 nodep->data = newdata; 628 return EOK; 629 } 630 631 static int tmpfs_close(service_id_t service_id, fs_index_t index) 632 { 633 return EOK; 634 } 635 636 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 637 { 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 638 709 link_t *hlp; 639 710 unsigned long key[] = { 640 [NODES_KEY_DEV] = service_id,711 [NODES_KEY_DEV] = devmap_handle, 641 712 [NODES_KEY_INDEX] = index 642 713 }; 643 714 hlp = hash_table_find(&nodes, key); 644 if (!hlp) 645 return ENOENT; 715 if (!hlp) { 716 async_answer_0(rid, ENOENT); 717 return; 718 } 646 719 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 647 720 nh_link); 648 return tmpfs_destroy_node(FS_NODE(nodep)); 649 } 650 651 static int tmpfs_sync(service_id_t service_id, fs_index_t index) 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) 652 736 { 653 737 /* … … 655 739 * thus the sync operation is a no-op. 656 740 */ 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 }; 741 async_answer_0(rid, EOK); 742 } 670 743 671 744 /** 672 745 * @} 673 746 */ 674
Note:
See TracChangeset
for help on using the changeset viewer.