Changes in uspace/srv/fs/tmpfs/tmpfs_ops.c [ffa2c8ef:b33870b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
rffa2c8ef rb33870b 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 **, devmap_handle_t, fs_index_t);71 static int tmpfs_node_get(fs_node_t **, service_id_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 **, devmap_handle_t, int);74 static int tmpfs_create_node(fs_node_t **, service_id_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, devmap_handle_t devmap_handle)81 { 82 return tmpfs_node_get(rfn, devmap_handle, TMPFS_SOME_ROOT);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); 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_ head);87 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_list); 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 111 106 static bool tmpfs_is_directory(fs_node_t *fn) 112 107 { … … 119 114 } 120 115 121 static devmap_handle_t tmpfs_device_get(fs_node_t *fn)116 static service_id_t tmpfs_service_get(fs_node_t *fn) 122 117 { 123 118 return 0; … … 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, 144 . device_get = tmpfs_device_get138 .service_get = tmpfs_service_get 145 139 }; 146 140 … … 164 158 switch (keys) { 165 159 case 1: 166 return (nodep-> devmap_handle== key[NODES_KEY_DEV]);160 return (nodep->service_id == key[NODES_KEY_DEV]); 167 161 case 2: 168 return ((nodep-> devmap_handle== key[NODES_KEY_DEV]) &&162 return ((nodep->service_id == key[NODES_KEY_DEV]) && 169 163 (nodep->index == key[NODES_KEY_INDEX])); 170 164 default: … … 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); … … 208 202 nodep->bp = NULL; 209 203 nodep->index = 0; 210 nodep-> devmap_handle= 0;204 nodep->service_id = 0; 211 205 nodep->type = TMPFS_NONE; 212 206 nodep->lnkcnt = 0; … … 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 … … 232 226 } 233 227 234 static bool tmpfs_instance_init( devmap_handle_t devmap_handle)228 static bool tmpfs_instance_init(service_id_t service_id) 235 229 { 236 230 fs_node_t *rfn; 237 231 int rc; 238 232 239 rc = tmpfs_create_node(&rfn, devmap_handle, L_DIRECTORY);233 rc = tmpfs_create_node(&rfn, service_id, L_DIRECTORY); 240 234 if (rc != EOK || !rfn) 241 235 return false; … … 244 238 } 245 239 246 static void tmpfs_instance_done( devmap_handle_t devmap_handle)247 { 248 unsigned long key[] = { 249 [NODES_KEY_DEV] = devmap_handle240 static void tmpfs_instance_done(service_id_t service_id) 241 { 242 unsigned long key[] = { 243 [NODES_KEY_DEV] = service_id 250 244 }; 251 245 /* … … 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); … … 278 270 } 279 271 280 int tmpfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)281 { 282 unsigned long key[] = { 283 [NODES_KEY_DEV] = devmap_handle,272 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 273 { 274 unsigned long key[] = { 275 [NODES_KEY_DEV] = service_id, 284 276 [NODES_KEY_INDEX] = index 285 277 }; … … 307 299 } 308 300 309 int tmpfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag)301 int tmpfs_create_node(fs_node_t **rfn, service_id_t service_id, int lflag) 310 302 { 311 303 fs_node_t *rootfn; … … 326 318 nodep->bp->data = nodep; /* link the FS and TMPFS nodes */ 327 319 328 rc = tmpfs_root_get(&rootfn, devmap_handle);320 rc = tmpfs_root_get(&rootfn, service_id); 329 321 assert(rc == EOK); 330 322 if (!rootfn) … … 332 324 else 333 325 nodep->index = tmpfs_next_index++; 334 nodep-> devmap_handle = devmap_handle;326 nodep->service_id = service_id; 335 327 if (lflag & L_DIRECTORY) 336 328 nodep->type = TMPFS_DIRECTORY; … … 340 332 /* Insert the new node into the nodes hash table. */ 341 333 unsigned long key[] = { 342 [NODES_KEY_DEV] = nodep-> devmap_handle,334 [NODES_KEY_DEV] = nodep->service_id, 343 335 [NODES_KEY_INDEX] = nodep->index 344 336 }; … … 353 345 354 346 assert(!nodep->lnkcnt); 355 assert(list_empty(&nodep->cs_ head));356 357 unsigned long key[] = { 358 [NODES_KEY_DEV] = nodep-> devmap_handle,347 assert(list_empty(&nodep->cs_list)); 348 349 unsigned long key[] = { 350 [NODES_KEY_DEV] = nodep->service_id, 359 351 [NODES_KEY_INDEX] = nodep->index 360 352 }; … … 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(service_id_t service_id, 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 rc = tmpfs_root_get(&rootfn, devmap_handle);441 rc = tmpfs_root_get(&rootfn, service_id); 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 } 470 471 rc = tmpfs_root_get(&rootfn, devmap_handle); 448 if (!tmpfs_instance_init(service_id)) 449 return ENOMEM; 450 451 rc = tmpfs_root_get(&rootfn, service_id); 472 452 assert(rc == EOK); 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 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 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 { 517 475 /* 518 476 * Lookup the respective TMPFS node. … … 520 478 link_t *hlp; 521 479 unsigned long key[] = { 522 [NODES_KEY_DEV] = devmap_handle,480 [NODES_KEY_DEV] = service_id, 523 481 [NODES_KEY_INDEX] = index 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(service_id_t service_id, fs_index_t index, aoff64_t pos, 535 size_t *wbytes, aoff64_t *nsize) 536 { 592 537 /* 593 538 * Lookup the respective TMPFS node. … … 595 540 link_t *hlp; 596 541 unsigned long key[] = { 597 [NODES_KEY_DEV] = devmap_handle,542 [NODES_KEY_DEV] = service_id, 598 543 [NODES_KEY_INDEX] = index 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(service_id_t service_id, fs_index_t index, 597 aoff64_t size) 598 { 657 599 /* 658 600 * Lookup the respective TMPFS node. 659 601 */ 660 602 unsigned long key[] = { 661 [NODES_KEY_DEV] = devmap_handle,603 [NODES_KEY_DEV] = service_id, 662 604 [NODES_KEY_INDEX] = index 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(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 { 709 638 link_t *hlp; 710 639 unsigned long key[] = { 711 [NODES_KEY_DEV] = devmap_handle,640 [NODES_KEY_DEV] = service_id, 712 641 [NODES_KEY_INDEX] = index 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(service_id_t service_id, 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.