Changeset bd5f3b7 in mainline for uspace/srv/fs/tmpfs
- Timestamp:
- 2011-08-21T13:07:35Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00aece0, f1a9e87
- Parents:
- 86a34d3e (diff), a6480d5 (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/tmpfs
- Files:
-
- 4 edited
-
tmpfs.c (modified) (2 diffs)
-
tmpfs.h (modified) (2 diffs)
-
tmpfs_dump.c (modified) (13 diffs)
-
tmpfs_ops.c (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs.c
r86a34d3e rbd5f3b7 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, void *arg)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 97 while (true) {98 ipc_call_t call;99 ipc_callid_t callid = async_get_call(&call);100 101 if (!IPC_GET_IMETHOD(call))102 return;103 104 switch (IPC_GET_IMETHOD(call)) {105 case VFS_OUT_MOUNTED:106 tmpfs_mounted(callid, &call);107 break;108 case VFS_OUT_MOUNT:109 tmpfs_mount(callid, &call);110 break;111 case VFS_OUT_UNMOUNTED:112 tmpfs_unmounted(callid, &call);113 break;114 case VFS_OUT_UNMOUNT:115 tmpfs_unmount(callid, &call);116 break;117 case VFS_OUT_LOOKUP:118 tmpfs_lookup(callid, &call);119 break;120 case VFS_OUT_READ:121 tmpfs_read(callid, &call);122 break;123 case VFS_OUT_WRITE:124 tmpfs_write(callid, &call);125 break;126 case VFS_OUT_TRUNCATE:127 tmpfs_truncate(callid, &call);128 break;129 case VFS_OUT_CLOSE:130 tmpfs_close(callid, &call);131 break;132 case VFS_OUT_DESTROY:133 tmpfs_destroy(callid, &call);134 break;135 case VFS_OUT_OPEN_NODE:136 tmpfs_open_node(callid, &call);137 break;138 case VFS_OUT_STAT:139 tmpfs_stat(callid, &call);140 break;141 case VFS_OUT_SYNC:142 tmpfs_sync(callid, &call);143 break;144 default:145 async_answer_0(callid, ENOTSUP);146 break;147 }148 }149 }150 151 63 int main(int argc, char **argv) 152 64 { … … 165 77 } 166 78 167 int rc = fs_register(vfs_sess, &tmpfs_ reg, &tmpfs_vfs_info,168 tmpfs_connection);79 int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops, 80 &tmpfs_libfs_ops); 169 81 if (rc != EOK) { 170 82 printf(NAME ": Failed to register file system (%d)\n", rc); -
uspace/srv/fs/tmpfs/tmpfs.h
r86a34d3e rbd5f3b7 61 61 fs_node_t *bp; /**< Back pointer to the FS node. */ 62 62 fs_index_t index; /**< TMPFS node index. */ 63 devmap_handle_t devmap_handle;/**< Device handle. */63 service_id_t service_id;/**< Service ID of block device. */ 64 64 link_t nh_link; /**< Nodes hash table link. */ 65 65 tmpfs_dentry_type_t type; … … 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 extern bool tmpfs_restore(devmap_handle_t); 76 extern bool tmpfs_restore(service_id_t); 93 77 94 78 #endif -
uspace/srv/fs/tmpfs/tmpfs_dump.c
r86a34d3e rbd5f3b7 55 55 56 56 static bool 57 tmpfs_restore_recursion( devmap_handle_t dev, size_t *bufpos, size_t *buflen,57 tmpfs_restore_recursion(service_id_t dsid, size_t *bufpos, size_t *buflen, 58 58 aoff64_t *pos, fs_node_t *pfn) 59 59 { … … 68 68 uint32_t size; 69 69 70 if (block_seqread(d ev, bufpos, buflen, pos, &entry,70 if (block_seqread(dsid, bufpos, buflen, pos, &entry, 71 71 sizeof(entry)) != EOK) 72 72 return false; … … 82 82 return false; 83 83 84 rc = ops->create(&fn, d ev, L_FILE);84 rc = ops->create(&fn, dsid, L_FILE); 85 85 if (rc != EOK || fn == NULL) { 86 86 free(fname); … … 88 88 } 89 89 90 if (block_seqread(d ev, bufpos, buflen, pos, fname,90 if (block_seqread(dsid, bufpos, buflen, pos, fname, 91 91 entry.len) != EOK) { 92 92 (void) ops->destroy(fn); … … 104 104 free(fname); 105 105 106 if (block_seqread(d ev, bufpos, buflen, pos, &size,106 if (block_seqread(dsid, bufpos, buflen, pos, &size, 107 107 sizeof(size)) != EOK) 108 108 return false; … … 116 116 117 117 nodep->size = size; 118 if (block_seqread(d ev, bufpos, buflen, pos, nodep->data,118 if (block_seqread(dsid, bufpos, buflen, pos, nodep->data, 119 119 size) != EOK) 120 120 return false; … … 126 126 return false; 127 127 128 rc = ops->create(&fn, d ev, L_DIRECTORY);128 rc = ops->create(&fn, dsid, L_DIRECTORY); 129 129 if (rc != EOK || fn == NULL) { 130 130 free(fname); … … 132 132 } 133 133 134 if (block_seqread(d ev, bufpos, buflen, pos, fname,134 if (block_seqread(dsid, bufpos, buflen, pos, fname, 135 135 entry.len) != EOK) { 136 136 (void) ops->destroy(fn); … … 148 148 free(fname); 149 149 150 if (!tmpfs_restore_recursion(d ev, bufpos, buflen, pos,150 if (!tmpfs_restore_recursion(dsid, bufpos, buflen, pos, 151 151 fn)) 152 152 return false; … … 161 161 } 162 162 163 bool tmpfs_restore( devmap_handle_t dev)163 bool tmpfs_restore(service_id_t dsid) 164 164 { 165 165 libfs_ops_t *ops = &tmpfs_libfs_ops; … … 167 167 int rc; 168 168 169 rc = block_init(EXCHANGE_SERIALIZE, d ev, TMPFS_COMM_SIZE);169 rc = block_init(EXCHANGE_SERIALIZE, dsid, TMPFS_COMM_SIZE); 170 170 if (rc != EOK) 171 171 return false; … … 176 176 177 177 char tag[6]; 178 if (block_seqread(d ev, &bufpos, &buflen, &pos, tag, 5) != EOK)178 if (block_seqread(dsid, &bufpos, &buflen, &pos, tag, 5) != EOK) 179 179 goto error; 180 180 … … 183 183 goto error; 184 184 185 rc = ops->root_get(&fn, d ev);185 rc = ops->root_get(&fn, dsid); 186 186 if (rc != EOK) 187 187 goto error; 188 188 189 if (!tmpfs_restore_recursion(d ev, &bufpos, &buflen, &pos, fn))190 goto error; 191 192 block_fini(d ev);189 if (!tmpfs_restore_recursion(dsid, &bufpos, &buflen, &pos, fn)) 190 goto error; 191 192 block_fini(dsid); 193 193 return true; 194 194 195 195 error: 196 block_fini(d ev);196 block_fini(dsid); 197 197 return false; 198 198 } -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r86a34d3e rbd5f3b7 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 … … 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_device_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, … … 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: … … 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; … … 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 /* … … 276 270 } 277 271 278 int tmpfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index)279 { 280 unsigned long key[] = { 281 [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, 282 276 [NODES_KEY_INDEX] = index 283 277 }; … … 305 299 } 306 300 307 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) 308 302 { 309 303 fs_node_t *rootfn; … … 324 318 nodep->bp->data = nodep; /* link the FS and TMPFS nodes */ 325 319 326 rc = tmpfs_root_get(&rootfn, devmap_handle);320 rc = tmpfs_root_get(&rootfn, service_id); 327 321 assert(rc == EOK); 328 322 if (!rootfn) … … 330 324 else 331 325 nodep->index = tmpfs_next_index++; 332 nodep-> devmap_handle = devmap_handle;326 nodep->service_id = service_id; 333 327 if (lflag & L_DIRECTORY) 334 328 nodep->type = TMPFS_DIRECTORY; … … 338 332 /* Insert the new node into the nodes hash table. */ 339 333 unsigned long key[] = { 340 [NODES_KEY_DEV] = nodep-> devmap_handle,334 [NODES_KEY_DEV] = nodep->service_id, 341 335 [NODES_KEY_INDEX] = nodep->index 342 336 }; … … 354 348 355 349 unsigned long key[] = { 356 [NODES_KEY_DEV] = nodep-> devmap_handle,350 [NODES_KEY_DEV] = nodep->service_id, 357 351 [NODES_KEY_INDEX] = nodep->index 358 352 }; … … 433 427 } 434 428 435 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 436 { 437 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 { 438 437 fs_node_t *rootfn; 439 438 int rc; 440 439 441 /* Accept the mount options. */442 char *opts;443 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);444 if (rc != EOK) {445 async_answer_0(rid, rc);446 return;447 }448 449 440 /* Check if this device is not already mounted. */ 450 rc = tmpfs_root_get(&rootfn, devmap_handle);441 rc = tmpfs_root_get(&rootfn, service_id); 451 442 if ((rc == EOK) && (rootfn)) { 452 443 (void) tmpfs_node_put(rootfn); 453 free(opts); 454 async_answer_0(rid, EEXIST); 455 return; 444 return EEXIST; 456 445 } 457 446 458 447 /* Initialize TMPFS instance. */ 459 if (!tmpfs_instance_init(devmap_handle)) { 460 free(opts); 461 async_answer_0(rid, ENOMEM); 462 return; 463 } 464 465 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); 466 452 assert(rc == EOK); 467 453 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 468 454 if (str_cmp(opts, "restore") == 0) { 469 if (tmpfs_restore(devmap_handle)) 470 async_answer_3(rid, EOK, rootp->index, rootp->size, 471 rootp->lnkcnt); 472 else 473 async_answer_0(rid, ELIMIT); 474 } else { 475 async_answer_3(rid, EOK, rootp->index, rootp->size, 476 rootp->lnkcnt); 477 } 478 free(opts); 479 } 480 481 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) 482 { 483 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 484 } 485 486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 487 { 488 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 489 490 tmpfs_instance_done(devmap_handle); 491 async_answer_0(rid, EOK); 492 } 493 494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 495 { 496 libfs_unmount(&tmpfs_libfs_ops, rid, request); 497 } 498 499 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 500 { 501 libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 502 } 503 504 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 505 { 506 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 507 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 508 aoff64_t pos = 509 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 510 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 { 511 475 /* 512 476 * Lookup the respective TMPFS node. … … 514 478 link_t *hlp; 515 479 unsigned long key[] = { 516 [NODES_KEY_DEV] = devmap_handle,480 [NODES_KEY_DEV] = service_id, 517 481 [NODES_KEY_INDEX] = index 518 482 }; 519 483 hlp = hash_table_find(&nodes, key); 520 if (!hlp) { 521 async_answer_0(rid, ENOENT); 522 return; 523 } 484 if (!hlp) 485 return ENOENT; 524 486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 525 487 nh_link); … … 532 494 if (!async_data_read_receive(&callid, &size)) { 533 495 async_answer_0(callid, EINVAL); 534 async_answer_0(rid, EINVAL); 535 return; 496 return EINVAL; 536 497 } 537 498 … … 556 517 if (lnk == NULL) { 557 518 async_answer_0(callid, ENOENT); 558 async_answer_1(rid, ENOENT, 0); 559 return; 519 return ENOENT; 560 520 } 561 521 … … 567 527 } 568 528 569 /* 570 * Answer the VFS_READ call. 571 */ 572 async_answer_1(rid, EOK, bytes); 573 } 574 575 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 576 { 577 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 578 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 579 aoff64_t pos = 580 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 581 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 { 582 537 /* 583 538 * Lookup the respective TMPFS node. … … 585 540 link_t *hlp; 586 541 unsigned long key[] = { 587 [NODES_KEY_DEV] = devmap_handle,542 [NODES_KEY_DEV] = service_id, 588 543 [NODES_KEY_INDEX] = index 589 544 }; 590 545 hlp = hash_table_find(&nodes, key); 591 if (!hlp) { 592 async_answer_0(rid, ENOENT); 593 return; 594 } 546 if (!hlp) 547 return ENOENT; 595 548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 596 549 nh_link); … … 603 556 if (!async_data_write_receive(&callid, &size)) { 604 557 async_answer_0(callid, EINVAL); 605 async_answer_0(rid, EINVAL); 606 return; 558 return EINVAL; 607 559 } 608 560 … … 612 564 if (pos + size <= nodep->size) { 613 565 /* The file size is not changing. */ 614 (void) async_data_write_finalize(callid, nodep->data + pos, size);615 async_answer_2(rid, EOK, size, nodep->size);616 return;566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 size); 568 goto out; 617 569 } 618 570 size_t delta = (pos + size) - nodep->size; … … 627 579 if (!newdata) { 628 580 async_answer_0(callid, ENOMEM); 629 async_answer_2(rid, EOK, 0, nodep->size);630 return;581 size = 0; 582 goto out; 631 583 } 632 584 /* Clear any newly allocated memory in order to emulate gaps. */ … … 635 587 nodep->data = newdata; 636 588 (void) async_data_write_finalize(callid, nodep->data + pos, size); 637 async_answer_2(rid, EOK, size, nodep->size); 638 } 639 640 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 641 { 642 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 643 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 644 aoff64_t size = 645 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 646 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 599 /* 648 600 * Lookup the respective TMPFS node. 649 601 */ 650 602 unsigned long key[] = { 651 [NODES_KEY_DEV] = devmap_handle,603 [NODES_KEY_DEV] = service_id, 652 604 [NODES_KEY_INDEX] = index 653 605 }; 654 606 link_t *hlp = hash_table_find(&nodes, key); 655 if (!hlp) { 656 async_answer_0(rid, ENOENT); 657 return; 658 } 659 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 660 nh_link); 661 662 if (size == nodep->size) { 663 async_answer_0(rid, EOK); 664 return; 665 } 666 667 if (size > SIZE_MAX) { 668 async_answer_0(rid, ENOMEM); 669 return; 670 } 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; 671 616 672 617 void *newdata = realloc(nodep->data, size); 673 if (!newdata) { 674 async_answer_0(rid, ENOMEM); 675 return; 676 } 618 if (!newdata) 619 return ENOMEM; 677 620 678 621 if (size > nodep->size) { … … 683 626 nodep->size = size; 684 627 nodep->data = newdata; 685 async_answer_0(rid, EOK); 686 } 687 688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 689 { 690 async_answer_0(rid, EOK); 691 } 692 693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 694 { 695 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 696 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 697 int rc; 698 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 { 699 638 link_t *hlp; 700 639 unsigned long key[] = { 701 [NODES_KEY_DEV] = devmap_handle,640 [NODES_KEY_DEV] = service_id, 702 641 [NODES_KEY_INDEX] = index 703 642 }; 704 643 hlp = hash_table_find(&nodes, key); 705 if (!hlp) { 706 async_answer_0(rid, ENOENT); 707 return; 708 } 644 if (!hlp) 645 return ENOENT; 709 646 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 710 647 nh_link); 711 rc = tmpfs_destroy_node(FS_NODE(nodep)); 712 async_answer_0(rid, rc); 713 } 714 715 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request) 716 { 717 libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 718 } 719 720 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request) 721 { 722 libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 723 } 724 725 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) 726 652 { 727 653 /* … … 729 655 * thus the sync operation is a no-op. 730 656 */ 731 async_answer_0(rid, EOK); 732 } 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 }; 733 670 734 671 /** 735 672 * @} 736 673 */ 674
Note:
See TracChangeset
for help on using the changeset viewer.
