Changes in uspace/srv/fs/tmpfs/tmpfs_ops.c [75160a6:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/tmpfs/tmpfs_ops.c
r75160a6 rffa2c8ef 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 39 39 #include "tmpfs.h" 40 40 #include "../../vfs/vfs.h" 41 #include <ipc/ipc.h> 41 #include <macros.h> 42 #include <stdint.h> 42 43 #include <async.h> 43 44 #include <errno.h> 44 45 #include <atomic.h> 45 46 #include <stdlib.h> 46 #include <str ing.h>47 #include <str.h> 47 48 #include <stdio.h> 48 49 #include <assert.h> … … 67 68 68 69 /* Forward declarations of static functions. */ 69 static fs_node_t *tmpfs_match(fs_node_t *, const char *); 70 static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t); 71 static void tmpfs_node_put(fs_node_t *); 72 static fs_node_t *tmpfs_create_node(dev_handle_t, int); 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); 72 static int tmpfs_node_open(fs_node_t *); 73 static int tmpfs_node_put(fs_node_t *); 74 static int tmpfs_create_node(fs_node_t **, devmap_handle_t, int); 75 static int tmpfs_destroy_node(fs_node_t *); 73 76 static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *); 74 77 static int tmpfs_unlink_node(fs_node_t *, fs_node_t *, const char *); 75 static int tmpfs_destroy_node(fs_node_t *);76 78 77 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); 83 } 84 85 static int tmpfs_has_children(bool *has_children, fs_node_t *fn) 86 { 87 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_head); 88 return EOK; 89 } 90 78 91 static fs_index_t tmpfs_index_get(fs_node_t *fn) 79 92 { … … 81 94 } 82 95 83 static size_t tmpfs_size_get(fs_node_t *fn)96 static aoff64_t tmpfs_size_get(fs_node_t *fn) 84 97 { 85 98 return TMPFS_NODE(fn)->size; … … 91 104 } 92 105 93 static bool tmpfs_has_children(fs_node_t *fn)94 {95 return !list_empty(&TMPFS_NODE(fn)->cs_head);96 }97 98 static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)99 {100 return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);101 }102 103 106 static char tmpfs_plb_get_char(unsigned pos) 104 107 { … … 114 117 { 115 118 return TMPFS_NODE(fn)->type == TMPFS_FILE; 119 } 120 121 static devmap_handle_t tmpfs_device_get(fs_node_t *fn) 122 { 123 return 0; 116 124 } 117 125 118 126 /** libfs operations */ 119 127 libfs_ops_t tmpfs_libfs_ops = { 128 .root_get = tmpfs_root_get, 120 129 .match = tmpfs_match, 121 130 .node_get = tmpfs_node_get, 131 .node_open = tmpfs_node_open, 122 132 .node_put = tmpfs_node_put, 123 133 .create = tmpfs_create_node, … … 125 135 .link = tmpfs_link_node, 126 136 .unlink = tmpfs_unlink_node, 137 .has_children = tmpfs_has_children, 127 138 .index_get = tmpfs_index_get, 128 139 .size_get = tmpfs_size_get, 129 140 .lnkcnt_get = tmpfs_lnkcnt_get, 130 .has_children = tmpfs_has_children,131 .root_get = tmpfs_root_get,132 141 .plb_get_char = tmpfs_plb_get_char, 133 142 .is_directory = tmpfs_is_directory, 134 .is_file = tmpfs_is_file 143 .is_file = tmpfs_is_file, 144 .device_get = tmpfs_device_get 135 145 }; 136 146 … … 138 148 hash_table_t nodes; 139 149 140 #define NODES_KEY_ INDEX 0141 #define NODES_KEY_ DEV1150 #define NODES_KEY_DEV 0 151 #define NODES_KEY_INDEX 1 142 152 143 153 /* Implementation of hash table interface for the nodes hash table. */ … … 151 161 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 152 162 nh_link); 153 return (nodep->index == key[NODES_KEY_INDEX] && 154 nodep->dev_handle == key[NODES_KEY_DEV]); 163 164 switch (keys) { 165 case 1: 166 return (nodep->devmap_handle == key[NODES_KEY_DEV]); 167 case 2: 168 return ((nodep->devmap_handle == key[NODES_KEY_DEV]) && 169 (nodep->index == key[NODES_KEY_INDEX])); 170 default: 171 assert((keys == 1) || (keys == 2)); 172 } 173 174 return 0; 155 175 } 156 176 157 177 static void nodes_remove_callback(link_t *item) 158 178 { 179 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 180 nh_link); 181 182 while (!list_empty(&nodep->cs_head)) { 183 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next, 184 tmpfs_dentry_t, link); 185 186 assert(nodep->type == TMPFS_DIRECTORY); 187 list_remove(&dentryp->link); 188 free(dentryp); 189 } 190 191 if (nodep->data) { 192 assert(nodep->type == TMPFS_FILE); 193 free(nodep->data); 194 } 195 free(nodep->bp); 196 free(nodep); 159 197 } 160 198 … … 170 208 nodep->bp = NULL; 171 209 nodep->index = 0; 172 nodep->dev _handle = 0;210 nodep->devmap_handle = 0; 173 211 nodep->type = TMPFS_NONE; 174 212 nodep->lnkcnt = 0; … … 194 232 } 195 233 196 static bool tmpfs_instance_init(dev _handle_t dev_handle)234 static bool tmpfs_instance_init(devmap_handle_t devmap_handle) 197 235 { 198 236 fs_node_t *rfn; 199 200 rfn = tmpfs_create_node(dev_handle, L_DIRECTORY); 201 if (!rfn) 237 int rc; 238 239 rc = tmpfs_create_node(&rfn, devmap_handle, L_DIRECTORY); 240 if (rc != EOK || !rfn) 202 241 return false; 203 242 TMPFS_NODE(rfn)->lnkcnt = 0; /* FS root is not linked */ … … 205 244 } 206 245 207 fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component) 246 static void tmpfs_instance_done(devmap_handle_t devmap_handle) 247 { 248 unsigned long key[] = { 249 [NODES_KEY_DEV] = devmap_handle 250 }; 251 /* 252 * Here we are making use of one special feature of our hash table 253 * implementation, which allows to remove more items based on a partial 254 * key match. In the following, we are going to remove all nodes 255 * matching our device handle. The nodes_remove_callback() function will 256 * take care of resource deallocation. 257 */ 258 hash_table_remove(&nodes, key, 1); 259 } 260 261 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 208 262 { 209 263 tmpfs_node_t *parentp = TMPFS_NODE(pfn); … … 212 266 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 213 267 lnk = lnk->next) { 214 tmpfs_dentry_t *dentryp = list_get_instance(lnk, tmpfs_dentry_t, 215 link); 216 if (!str_cmp(dentryp->name, component)) 217 return FS_NODE(dentryp->node); 218 } 219 220 return NULL; 221 } 222 223 fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index) 268 tmpfs_dentry_t *dentryp; 269 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 270 if (!str_cmp(dentryp->name, component)) { 271 *rfn = FS_NODE(dentryp->node); 272 return EOK; 273 } 274 } 275 276 *rfn = NULL; 277 return EOK; 278 } 279 280 int tmpfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index) 224 281 { 225 282 unsigned long key[] = { 226 [NODES_KEY_ INDEX] = index,227 [NODES_KEY_ DEV] = dev_handle283 [NODES_KEY_DEV] = devmap_handle, 284 [NODES_KEY_INDEX] = index 228 285 }; 229 286 link_t *lnk = hash_table_find(&nodes, key); 230 if (!lnk) 231 return NULL; 232 return FS_NODE(hash_table_get_instance(lnk, tmpfs_node_t, nh_link)); 233 } 234 235 void tmpfs_node_put(fs_node_t *fn) 287 if (lnk) { 288 tmpfs_node_t *nodep; 289 nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link); 290 *rfn = FS_NODE(nodep); 291 } else { 292 *rfn = NULL; 293 } 294 return EOK; 295 } 296 297 int tmpfs_node_open(fs_node_t *fn) 236 298 { 237 299 /* nothing to do */ 238 } 239 240 fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag) 241 { 300 return EOK; 301 } 302 303 int tmpfs_node_put(fs_node_t *fn) 304 { 305 /* nothing to do */ 306 return EOK; 307 } 308 309 int tmpfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag) 310 { 311 fs_node_t *rootfn; 312 int rc; 313 242 314 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); 243 315 244 316 tmpfs_node_t *nodep = malloc(sizeof(tmpfs_node_t)); 245 317 if (!nodep) 246 return NULL;318 return ENOMEM; 247 319 tmpfs_node_initialize(nodep); 248 320 nodep->bp = malloc(sizeof(fs_node_t)); 249 321 if (!nodep->bp) { 250 322 free(nodep); 251 return NULL;323 return ENOMEM; 252 324 } 253 325 fs_node_initialize(nodep->bp); 254 326 nodep->bp->data = nodep; /* link the FS and TMPFS nodes */ 255 if (!tmpfs_root_get(dev_handle)) 327 328 rc = tmpfs_root_get(&rootfn, devmap_handle); 329 assert(rc == EOK); 330 if (!rootfn) 256 331 nodep->index = TMPFS_SOME_ROOT; 257 332 else 258 333 nodep->index = tmpfs_next_index++; 259 nodep->dev _handle = dev_handle;334 nodep->devmap_handle = devmap_handle; 260 335 if (lflag & L_DIRECTORY) 261 336 nodep->type = TMPFS_DIRECTORY; … … 265 340 /* Insert the new node into the nodes hash table. */ 266 341 unsigned long key[] = { 267 [NODES_KEY_ INDEX] = nodep->index,268 [NODES_KEY_ DEV] = nodep->dev_handle342 [NODES_KEY_DEV] = nodep->devmap_handle, 343 [NODES_KEY_INDEX] = nodep->index 269 344 }; 270 345 hash_table_insert(&nodes, key, &nodep->nh_link); 271 return FS_NODE(nodep); 346 *rfn = FS_NODE(nodep); 347 return EOK; 348 } 349 350 int tmpfs_destroy_node(fs_node_t *fn) 351 { 352 tmpfs_node_t *nodep = TMPFS_NODE(fn); 353 354 assert(!nodep->lnkcnt); 355 assert(list_empty(&nodep->cs_head)); 356 357 unsigned long key[] = { 358 [NODES_KEY_DEV] = nodep->devmap_handle, 359 [NODES_KEY_INDEX] = nodep->index 360 }; 361 hash_table_remove(&nodes, key, 2); 362 363 /* 364 * The nodes_remove_callback() function takes care of the actual 365 * resource deallocation. 366 */ 367 return EOK; 272 368 } 273 369 … … 343 439 } 344 440 345 int tmpfs_destroy_node(fs_node_t *fn)346 {347 tmpfs_node_t *nodep = TMPFS_NODE(fn);348 349 assert(!nodep->lnkcnt);350 assert(list_empty(&nodep->cs_head));351 352 unsigned long key[] = {353 [NODES_KEY_INDEX] = nodep->index,354 [NODES_KEY_DEV] = nodep->dev_handle355 };356 hash_table_remove(&nodes, key, 2);357 358 if (nodep->type == TMPFS_FILE)359 free(nodep->data);360 free(nodep->bp);361 free(nodep);362 return EOK;363 }364 365 441 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 366 442 { 367 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 368 369 /* accept the mount options */ 370 ipc_callid_t callid; 371 size_t size; 372 if (!ipc_data_write_receive(&callid, &size)) { 373 ipc_answer_0(callid, EINVAL); 374 ipc_answer_0(rid, EINVAL); 375 return; 376 } 377 char *opts = malloc(size + 1); 378 if (!opts) { 379 ipc_answer_0(callid, ENOMEM); 380 ipc_answer_0(rid, ENOMEM); 381 return; 382 } 383 ipcarg_t retval = ipc_data_write_finalize(callid, opts, size); 384 if (retval != EOK) { 385 ipc_answer_0(rid, retval); 443 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 444 fs_node_t *rootfn; 445 int rc; 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 455 /* Check if this device is not already mounted. */ 456 rc = tmpfs_root_get(&rootfn, devmap_handle); 457 if ((rc == EOK) && (rootfn)) { 458 (void) tmpfs_node_put(rootfn); 386 459 free(opts); 387 return;388 }389 opts[size] = '\0';460 async_answer_0(rid, EEXIST); 461 return; 462 } 390 463 391 464 /* Initialize TMPFS instance. */ 392 if (!tmpfs_instance_init(dev_handle)) { 393 ipc_answer_0(rid, ENOMEM); 394 return; 395 } 396 397 tmpfs_node_t *rootp = TMPFS_NODE(tmpfs_root_get(dev_handle)); 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); 472 assert(rc == EOK); 473 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 398 474 if (str_cmp(opts, "restore") == 0) { 399 if (tmpfs_restore(dev _handle))400 ipc_answer_3(rid, EOK, rootp->index, rootp->size,475 if (tmpfs_restore(devmap_handle)) 476 async_answer_3(rid, EOK, rootp->index, rootp->size, 401 477 rootp->lnkcnt); 402 478 else 403 ipc_answer_0(rid, ELIMIT);479 async_answer_0(rid, ELIMIT); 404 480 } else { 405 ipc_answer_3(rid, EOK, rootp->index, rootp->size,481 async_answer_3(rid, EOK, rootp->index, rootp->size, 406 482 rootp->lnkcnt); 407 483 } 484 free(opts); 408 485 } 409 486 … … 413 490 } 414 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 415 505 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 416 506 { … … 420 510 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 421 511 { 422 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 423 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 424 off_t pos = (off_t)IPC_GET_ARG3(*request); 425 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 426 517 /* 427 518 * Lookup the respective TMPFS node. … … 429 520 link_t *hlp; 430 521 unsigned long key[] = { 431 [NODES_KEY_ INDEX] = index,432 [NODES_KEY_ DEV] = dev_handle,522 [NODES_KEY_DEV] = devmap_handle, 523 [NODES_KEY_INDEX] = index 433 524 }; 434 525 hlp = hash_table_find(&nodes, key); 435 526 if (!hlp) { 436 ipc_answer_0(rid, ENOENT);527 async_answer_0(rid, ENOENT); 437 528 return; 438 529 } 439 530 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 440 531 nh_link); 441 532 442 533 /* 443 534 * Receive the read request. … … 445 536 ipc_callid_t callid; 446 537 size_t size; 447 if (! ipc_data_read_receive(&callid, &size)) {448 ipc_answer_0(callid, EINVAL);449 ipc_answer_0(rid, EINVAL);538 if (!async_data_read_receive(&callid, &size)) { 539 async_answer_0(callid, EINVAL); 540 async_answer_0(rid, EINVAL); 450 541 return; 451 542 } … … 453 544 size_t bytes; 454 545 if (nodep->type == TMPFS_FILE) { 455 bytes = m ax(0, min(nodep->size - pos, size));456 (void) ipc_data_read_finalize(callid, nodep->data + pos,546 bytes = min(nodep->size - pos, size); 547 (void) async_data_read_finalize(callid, nodep->data + pos, 457 548 bytes); 458 549 } else { 459 550 tmpfs_dentry_t *dentryp; 460 551 link_t *lnk; 461 int i;552 aoff64_t i; 462 553 463 554 assert(nodep->type == TMPFS_DIRECTORY); … … 469 560 */ 470 561 for (i = 0, lnk = nodep->cs_head.next; 471 i < pos && lnk != &nodep->cs_head;562 (i < pos) && (lnk != &nodep->cs_head); 472 563 i++, lnk = lnk->next) 473 564 ; 474 565 475 566 if (lnk == &nodep->cs_head) { 476 ipc_answer_0(callid, ENOENT);477 ipc_answer_1(rid, ENOENT, 0);567 async_answer_0(callid, ENOENT); 568 async_answer_1(rid, ENOENT, 0); 478 569 return; 479 570 } … … 481 572 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 482 573 483 (void) ipc_data_read_finalize(callid, dentryp->name,574 (void) async_data_read_finalize(callid, dentryp->name, 484 575 str_size(dentryp->name) + 1); 485 576 bytes = 1; … … 489 580 * Answer the VFS_READ call. 490 581 */ 491 ipc_answer_1(rid, EOK, bytes);582 async_answer_1(rid, EOK, bytes); 492 583 } 493 584 494 585 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 495 586 { 496 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 497 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 498 off_t pos = (off_t)IPC_GET_ARG3(*request); 499 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 500 592 /* 501 593 * Lookup the respective TMPFS node. … … 503 595 link_t *hlp; 504 596 unsigned long key[] = { 505 [NODES_KEY_ INDEX] = index,506 [NODES_KEY_ DEV] = dev_handle597 [NODES_KEY_DEV] = devmap_handle, 598 [NODES_KEY_INDEX] = index 507 599 }; 508 600 hlp = hash_table_find(&nodes, key); 509 601 if (!hlp) { 510 ipc_answer_0(rid, ENOENT);602 async_answer_0(rid, ENOENT); 511 603 return; 512 604 } … … 519 611 ipc_callid_t callid; 520 612 size_t size; 521 if (! ipc_data_write_receive(&callid, &size)) {522 ipc_answer_0(callid, EINVAL);523 ipc_answer_0(rid, EINVAL);613 if (!async_data_write_receive(&callid, &size)) { 614 async_answer_0(callid, EINVAL); 615 async_answer_0(rid, EINVAL); 524 616 return; 525 617 } … … 530 622 if (pos + size <= nodep->size) { 531 623 /* The file size is not changing. */ 532 (void) ipc_data_write_finalize(callid, nodep->data + pos, size);533 ipc_answer_2(rid, EOK, size, nodep->size);624 (void) async_data_write_finalize(callid, nodep->data + pos, size); 625 async_answer_2(rid, EOK, size, nodep->size); 534 626 return; 535 627 } … … 544 636 void *newdata = realloc(nodep->data, nodep->size + delta); 545 637 if (!newdata) { 546 ipc_answer_0(callid, ENOMEM);547 ipc_answer_2(rid, EOK, 0, nodep->size);638 async_answer_0(callid, ENOMEM); 639 async_answer_2(rid, EOK, 0, nodep->size); 548 640 return; 549 641 } … … 552 644 nodep->size += delta; 553 645 nodep->data = newdata; 554 (void) ipc_data_write_finalize(callid, nodep->data + pos, size);555 ipc_answer_2(rid, EOK, size, nodep->size);646 (void) async_data_write_finalize(callid, nodep->data + pos, size); 647 async_answer_2(rid, EOK, size, nodep->size); 556 648 } 557 649 558 650 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 559 651 { 560 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 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 657 /* 658 * Lookup the respective TMPFS node. 659 */ 660 unsigned long key[] = { 661 [NODES_KEY_DEV] = devmap_handle, 662 [NODES_KEY_INDEX] = index 663 }; 664 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 } 681 682 void *newdata = realloc(nodep->data, size); 683 if (!newdata) { 684 async_answer_0(rid, ENOMEM); 685 return; 686 } 687 688 if (size > nodep->size) { 689 size_t delta = size - nodep->size; 690 memset(newdata + nodep->size, 0, delta); 691 } 692 693 nodep->size = size; 694 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); 561 706 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 562 size_t size = (off_t)IPC_GET_ARG3(*request); 563 564 /* 565 * Lookup the respective TMPFS node. 566 */ 707 int rc; 708 567 709 link_t *hlp; 568 710 unsigned long key[] = { 569 [NODES_KEY_ INDEX] = index,570 [NODES_KEY_ DEV] = dev_handle711 [NODES_KEY_DEV] = devmap_handle, 712 [NODES_KEY_INDEX] = index 571 713 }; 572 714 hlp = hash_table_find(&nodes, key); 573 715 if (!hlp) { 574 ipc_answer_0(rid, ENOENT); 575 return; 576 } 577 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 578 nh_link); 579 580 if (size == nodep->size) { 581 ipc_answer_0(rid, EOK); 582 return; 583 } 584 585 void *newdata = realloc(nodep->data, size); 586 if (!newdata) { 587 ipc_answer_0(rid, ENOMEM); 588 return; 589 } 590 if (size > nodep->size) { 591 size_t delta = size - nodep->size; 592 memset(newdata + nodep->size, 0, delta); 593 } 594 nodep->size = size; 595 nodep->data = newdata; 596 ipc_answer_0(rid, EOK); 597 } 598 599 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 600 { 601 ipc_answer_0(rid, EOK); 602 } 603 604 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 605 { 606 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 607 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 608 int rc; 609 610 link_t *hlp; 611 unsigned long key[] = { 612 [NODES_KEY_INDEX] = index, 613 [NODES_KEY_DEV] = dev_handle 614 }; 615 hlp = hash_table_find(&nodes, key); 616 if (!hlp) { 617 ipc_answer_0(rid, ENOENT); 716 async_answer_0(rid, ENOENT); 618 717 return; 619 718 } … … 621 720 nh_link); 622 721 rc = tmpfs_destroy_node(FS_NODE(nodep)); 623 ipc_answer_0(rid, rc);722 async_answer_0(rid, rc); 624 723 } 625 724 … … 636 735 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request) 637 736 { 638 /* Dummy implementation */ 639 ipc_answer_0(rid, EOK); 737 /* 738 * TMPFS keeps its data structures always consistent, 739 * thus the sync operation is a no-op. 740 */ 741 async_answer_0(rid, EOK); 640 742 } 641 743
Note:
See TracChangeset
for help on using the changeset viewer.