Changes in uspace/srv/fs/tmpfs/tmpfs_ops.c [1313ee9:ed903174] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
r1313ee9 red903174 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 40 40 #include "../../vfs/vfs.h" 41 41 #include <ipc/ipc.h> 42 #include <macros.h> 43 #include <limits.h> 42 44 #include <async.h> 43 45 #include <errno.h> … … 93 95 } 94 96 95 static size_t tmpfs_size_get(fs_node_t *fn)97 static aoff64_t tmpfs_size_get(fs_node_t *fn) 96 98 { 97 99 return TMPFS_NODE(fn)->size; … … 147 149 hash_table_t nodes; 148 150 149 #define NODES_KEY_ INDEX 0150 #define NODES_KEY_ DEV1151 #define NODES_KEY_DEV 0 152 #define NODES_KEY_INDEX 1 151 153 152 154 /* Implementation of hash table interface for the nodes hash table. */ … … 160 162 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 161 163 nh_link); 162 return (nodep->index == key[NODES_KEY_INDEX] && 163 nodep->dev_handle == key[NODES_KEY_DEV]); 164 165 switch (keys) { 166 case 1: 167 return (nodep->dev_handle == key[NODES_KEY_DEV]); 168 case 2: 169 return ((nodep->dev_handle == key[NODES_KEY_DEV]) && 170 (nodep->index == key[NODES_KEY_INDEX])); 171 default: 172 assert((keys == 1) || (keys == 2)); 173 } 174 175 return 0; 164 176 } 165 177 166 178 static void nodes_remove_callback(link_t *item) 167 179 { 180 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 181 nh_link); 182 183 while (!list_empty(&nodep->cs_head)) { 184 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next, 185 tmpfs_dentry_t, link); 186 187 assert(nodep->type == TMPFS_DIRECTORY); 188 list_remove(&dentryp->link); 189 free(dentryp); 190 } 191 192 if (nodep->data) { 193 assert(nodep->type == TMPFS_FILE); 194 free(nodep->data); 195 } 196 free(nodep->bp); 197 free(nodep); 168 198 } 169 199 … … 215 245 } 216 246 247 static void tmpfs_instance_done(dev_handle_t dev_handle) 248 { 249 unsigned long key[] = { 250 [NODES_KEY_DEV] = dev_handle 251 }; 252 /* 253 * Here we are making use of one special feature of our hash table 254 * implementation, which allows to remove more items based on a partial 255 * key match. In the following, we are going to remove all nodes 256 * matching our device handle. The nodes_remove_callback() function will 257 * take care of resource deallocation. 258 */ 259 hash_table_remove(&nodes, key, 1); 260 } 261 217 262 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 218 263 { … … 237 282 { 238 283 unsigned long key[] = { 239 [NODES_KEY_ INDEX] = index,240 [NODES_KEY_ DEV] = dev_handle284 [NODES_KEY_DEV] = dev_handle, 285 [NODES_KEY_INDEX] = index 241 286 }; 242 287 link_t *lnk = hash_table_find(&nodes, key); … … 296 341 /* Insert the new node into the nodes hash table. */ 297 342 unsigned long key[] = { 298 [NODES_KEY_ INDEX] = nodep->index,299 [NODES_KEY_ DEV] = nodep->dev_handle343 [NODES_KEY_DEV] = nodep->dev_handle, 344 [NODES_KEY_INDEX] = nodep->index 300 345 }; 301 346 hash_table_insert(&nodes, key, &nodep->nh_link); … … 312 357 313 358 unsigned long key[] = { 314 [NODES_KEY_ INDEX] = nodep->index,315 [NODES_KEY_ DEV] = nodep->dev_handle359 [NODES_KEY_DEV] = nodep->dev_handle, 360 [NODES_KEY_INDEX] = nodep->index 316 361 }; 317 362 hash_table_remove(&nodes, key, 2); 318 363 319 if (nodep->type == TMPFS_FILE)320 free(nodep->data);321 free(nodep->bp);322 free(nodep);364 /* 365 * The nodes_remove_callback() function takes care of the actual 366 * resource deallocation. 367 */ 323 368 return EOK; 324 369 } … … 398 443 { 399 444 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 445 fs_node_t *rootfn; 400 446 int rc; 401 402 /* accept the mount options */ 403 ipc_callid_t callid; 404 size_t size; 405 if (!async_data_write_receive(&callid, &size)) { 406 ipc_answer_0(callid, EINVAL); 407 ipc_answer_0(rid, EINVAL); 408 return; 409 } 410 char *opts = malloc(size + 1); 411 if (!opts) { 412 ipc_answer_0(callid, ENOMEM); 413 ipc_answer_0(rid, ENOMEM); 414 return; 415 } 416 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 417 if (retval != EOK) { 418 ipc_answer_0(rid, retval); 447 448 /* Accept the mount options. */ 449 char *opts; 450 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 451 if (rc != EOK) { 452 ipc_answer_0(rid, rc); 453 return; 454 } 455 456 /* Check if this device is not already mounted. */ 457 rc = tmpfs_root_get(&rootfn, dev_handle); 458 if ((rc == EOK) && (rootfn)) { 459 (void) tmpfs_node_put(rootfn); 419 460 free(opts); 420 return;421 }422 opts[size] = '\0';461 ipc_answer_0(rid, EEXIST); 462 return; 463 } 423 464 424 465 /* Initialize TMPFS instance. */ 425 466 if (!tmpfs_instance_init(dev_handle)) { 467 free(opts); 426 468 ipc_answer_0(rid, ENOMEM); 427 469 return; 428 470 } 429 471 430 fs_node_t *rootfn;431 472 rc = tmpfs_root_get(&rootfn, dev_handle); 432 473 assert(rc == EOK); … … 442 483 rootp->lnkcnt); 443 484 } 485 free(opts); 444 486 } 445 487 … … 449 491 } 450 492 493 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 494 { 495 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 496 497 tmpfs_instance_done(dev_handle); 498 ipc_answer_0(rid, EOK); 499 } 500 501 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 502 { 503 libfs_unmount(&tmpfs_libfs_ops, rid, request); 504 } 505 451 506 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 452 507 { … … 456 511 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 457 512 { 458 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 459 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 460 off_t pos = (off_t)IPC_GET_ARG3(*request); 461 513 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 514 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 515 aoff64_t pos = 516 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 517 462 518 /* 463 519 * Lookup the respective TMPFS node. … … 465 521 link_t *hlp; 466 522 unsigned long key[] = { 467 [NODES_KEY_INDEX] = index,468 523 [NODES_KEY_DEV] = dev_handle, 524 [NODES_KEY_INDEX] = index 469 525 }; 470 526 hlp = hash_table_find(&nodes, key); … … 475 531 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 476 532 nh_link); 477 533 478 534 /* 479 535 * Receive the read request. … … 482 538 size_t size; 483 539 if (!async_data_read_receive(&callid, &size)) { 484 ipc_answer_0(callid, EINVAL); 540 ipc_answer_0(callid, EINVAL); 485 541 ipc_answer_0(rid, EINVAL); 486 542 return; … … 489 545 size_t bytes; 490 546 if (nodep->type == TMPFS_FILE) { 491 bytes = m ax(0, min(nodep->size - pos, size));547 bytes = min(nodep->size - pos, size); 492 548 (void) async_data_read_finalize(callid, nodep->data + pos, 493 549 bytes); … … 495 551 tmpfs_dentry_t *dentryp; 496 552 link_t *lnk; 497 int i;553 aoff64_t i; 498 554 499 555 assert(nodep->type == TMPFS_DIRECTORY); … … 505 561 */ 506 562 for (i = 0, lnk = nodep->cs_head.next; 507 i < pos && lnk != &nodep->cs_head;563 (i < pos) && (lnk != &nodep->cs_head); 508 564 i++, lnk = lnk->next) 509 565 ; … … 530 586 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 531 587 { 532 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 533 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 534 off_t pos = (off_t)IPC_GET_ARG3(*request); 535 588 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 589 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 590 aoff64_t pos = 591 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 592 536 593 /* 537 594 * Lookup the respective TMPFS node. … … 539 596 link_t *hlp; 540 597 unsigned long key[] = { 541 [NODES_KEY_ INDEX] = index,542 [NODES_KEY_ DEV] = dev_handle598 [NODES_KEY_DEV] = dev_handle, 599 [NODES_KEY_INDEX] = index 543 600 }; 544 601 hlp = hash_table_find(&nodes, key); … … 594 651 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 595 652 { 653 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 654 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 655 aoff64_t size = 656 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 657 658 /* 659 * Lookup the respective TMPFS node. 660 */ 661 unsigned long key[] = { 662 [NODES_KEY_DEV] = dev_handle, 663 [NODES_KEY_INDEX] = index 664 }; 665 link_t *hlp = hash_table_find(&nodes, key); 666 if (!hlp) { 667 ipc_answer_0(rid, ENOENT); 668 return; 669 } 670 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 671 nh_link); 672 673 if (size == nodep->size) { 674 ipc_answer_0(rid, EOK); 675 return; 676 } 677 678 if (size > SIZE_MAX) { 679 ipc_answer_0(rid, ENOMEM); 680 return; 681 } 682 683 void *newdata = realloc(nodep->data, size); 684 if (!newdata) { 685 ipc_answer_0(rid, ENOMEM); 686 return; 687 } 688 689 if (size > nodep->size) { 690 size_t delta = size - nodep->size; 691 memset(newdata + nodep->size, 0, delta); 692 } 693 694 nodep->size = size; 695 nodep->data = newdata; 696 ipc_answer_0(rid, EOK); 697 } 698 699 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 700 { 701 ipc_answer_0(rid, EOK); 702 } 703 704 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 705 { 596 706 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 597 707 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 598 size_t size = (off_t)IPC_GET_ARG3(*request); 599 600 /* 601 * Lookup the respective TMPFS node. 602 */ 708 int rc; 709 603 710 link_t *hlp; 604 711 unsigned long key[] = { 605 [NODES_KEY_ INDEX] = index,606 [NODES_KEY_ DEV] = dev_handle712 [NODES_KEY_DEV] = dev_handle, 713 [NODES_KEY_INDEX] = index 607 714 }; 608 715 hlp = hash_table_find(&nodes, key); … … 613 720 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 614 721 nh_link); 615 616 if (size == nodep->size) {617 ipc_answer_0(rid, EOK);618 return;619 }620 621 void *newdata = realloc(nodep->data, size);622 if (!newdata) {623 ipc_answer_0(rid, ENOMEM);624 return;625 }626 if (size > nodep->size) {627 size_t delta = size - nodep->size;628 memset(newdata + nodep->size, 0, delta);629 }630 nodep->size = size;631 nodep->data = newdata;632 ipc_answer_0(rid, EOK);633 }634 635 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)636 {637 ipc_answer_0(rid, EOK);638 }639 640 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)641 {642 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);643 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);644 int rc;645 646 link_t *hlp;647 unsigned long key[] = {648 [NODES_KEY_INDEX] = index,649 [NODES_KEY_DEV] = dev_handle650 };651 hlp = hash_table_find(&nodes, key);652 if (!hlp) {653 ipc_answer_0(rid, ENOENT);654 return;655 }656 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,657 nh_link);658 722 rc = tmpfs_destroy_node(FS_NODE(nodep)); 659 723 ipc_answer_0(rid, rc);
Note:
See TracChangeset
for help on using the changeset viewer.