Changes in uspace/lib/c/generic/vfs/vfs.c [8e80d3f:96b02eb9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/vfs/vfs.c
r8e80d3f r96b02eb9 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 * Copyright (c) 2008 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 43 43 #include <sys/stat.h> 44 44 #include <sys/types.h> 45 #include <ipc/ipc.h> 45 46 #include <ipc/services.h> 46 #include <ipc/ns.h>47 47 #include <async.h> 48 #include <fibril_synch.h> 48 #include <atomic.h> 49 #include <futex.h> 49 50 #include <errno.h> 50 #include <assert.h>51 51 #include <str.h> 52 52 #include <devmap.h> … … 54 54 #include <ipc/devmap.h> 55 55 56 static async_sess_t vfs_session;57 58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);59 56 static int vfs_phone = -1; 60 61 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);57 static futex_t vfs_phone_futex = FUTEX_INITIALIZER; 58 static futex_t cwd_futex = FUTEX_INITIALIZER; 62 59 63 60 static int cwd_fd = -1; … … 69 66 char *ncwd_path; 70 67 char *ncwd_path_nc; 71 size_t total_size; 72 73 fibril_mutex_lock(&cwd_mutex); 68 69 futex_down(&cwd_futex); 74 70 size_t size = str_size(path); 75 71 if (*path != '/') { 76 72 if (!cwd_path) { 77 f ibril_mutex_unlock(&cwd_mutex);73 futex_up(&cwd_futex); 78 74 return NULL; 79 75 } 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 76 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 82 77 if (!ncwd_path_nc) { 83 f ibril_mutex_unlock(&cwd_mutex);78 futex_up(&cwd_futex); 84 79 return NULL; 85 80 } 86 str_cpy(ncwd_path_nc, total_size, cwd_path);81 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path); 87 82 ncwd_path_nc[cwd_size] = '/'; 88 83 ncwd_path_nc[cwd_size + 1] = '\0'; 89 84 } else { 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 85 ncwd_path_nc = malloc(size + 1); 92 86 if (!ncwd_path_nc) { 93 f ibril_mutex_unlock(&cwd_mutex);87 futex_up(&cwd_futex); 94 88 return NULL; 95 89 } 96 90 ncwd_path_nc[0] = '\0'; 97 91 } 98 str_append(ncwd_path_nc, total_size, path);92 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); 99 93 ncwd_path = canonify(ncwd_path_nc, retlen); 100 94 if (!ncwd_path) { 101 f ibril_mutex_unlock(&cwd_mutex);95 futex_up(&cwd_futex); 102 96 free(ncwd_path_nc); 103 97 return NULL; … … 111 105 free(ncwd_path_nc); 112 106 if (!ncwd_path) { 113 f ibril_mutex_unlock(&cwd_mutex);107 futex_up(&cwd_futex); 114 108 return NULL; 115 109 } 116 f ibril_mutex_unlock(&cwd_mutex);110 futex_up(&cwd_futex); 117 111 return ncwd_path; 118 112 } 119 113 120 /** Connect to VFS service and create session. */121 114 static void vfs_connect(void) 122 115 { 123 116 while (vfs_phone < 0) 124 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 125 126 async_session_create(&vfs_session, vfs_phone, 0); 127 } 128 129 /** Start an async exchange on the VFS session. 130 * 131 * @return New phone to be used during the exchange. 132 */ 133 static int vfs_exchange_begin(void) 134 { 135 fibril_mutex_lock(&vfs_phone_mutex); 136 if (vfs_phone < 0) 137 vfs_connect(); 138 fibril_mutex_unlock(&vfs_phone_mutex); 139 140 return async_exchange_begin(&vfs_session); 141 } 142 143 /** End an async exchange on the VFS session. 144 * 145 * @param phone Phone used during the exchange. 146 */ 147 static void vfs_exchange_end(int phone) 148 { 149 async_exchange_end(&vfs_session, phone); 117 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); 150 118 } 151 119 … … 186 154 } 187 155 188 int vfs_phone = vfs_exchange_begin(); 189 156 futex_down(&vfs_phone_futex); 157 async_serialize_start(); 158 vfs_connect(); 159 190 160 sysarg_t rc_orig; 191 161 aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL); 192 162 sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 193 163 if (rc != EOK) { 194 vfs_exchange_end(vfs_phone); 164 async_wait_for(req, &rc_orig); 165 async_serialize_end(); 166 futex_up(&vfs_phone_futex); 195 167 free(mpa); 196 async_wait_for(req, &rc_orig);197 168 198 169 if (null_id != -1) … … 207 178 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 208 179 if (rc != EOK) { 209 vfs_exchange_end(vfs_phone); 180 async_wait_for(req, &rc_orig); 181 async_serialize_end(); 182 futex_up(&vfs_phone_futex); 210 183 free(mpa); 211 async_wait_for(req, &rc_orig);212 184 213 185 if (null_id != -1) … … 222 194 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 223 195 if (rc != EOK) { 224 vfs_exchange_end(vfs_phone); 196 async_wait_for(req, &rc_orig); 197 async_serialize_end(); 198 futex_up(&vfs_phone_futex); 225 199 free(mpa); 226 async_wait_for(req, &rc_orig);227 200 228 201 if (null_id != -1) … … 238 211 rc = async_req_0_0(vfs_phone, IPC_M_PING); 239 212 if (rc != EOK) { 240 vfs_exchange_end(vfs_phone); 213 async_wait_for(req, &rc_orig); 214 async_serialize_end(); 215 futex_up(&vfs_phone_futex); 241 216 free(mpa); 242 async_wait_for(req, &rc_orig);243 217 244 218 if (null_id != -1) … … 251 225 } 252 226 253 vfs_exchange_end(vfs_phone); 227 async_wait_for(req, &rc); 228 async_serialize_end(); 229 futex_up(&vfs_phone_futex); 254 230 free(mpa); 255 async_wait_for(req, &rc);256 231 257 232 if ((rc != EOK) && (null_id != -1)) … … 273 248 return ENOMEM; 274 249 275 int vfs_phone = vfs_exchange_begin(); 250 futex_down(&vfs_phone_futex); 251 async_serialize_start(); 252 vfs_connect(); 276 253 277 254 req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL); 278 255 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 279 256 if (rc != EOK) { 280 vfs_exchange_end(vfs_phone); 257 async_wait_for(req, &rc_orig); 258 async_serialize_end(); 259 futex_up(&vfs_phone_futex); 281 260 free(mpa); 282 async_wait_for(req, &rc_orig); 283 if (rc_orig == EOK) 284 return (int) rc; 285 else 286 return (int) rc_orig; 287 } 288 289 290 vfs_exchange_end(vfs_phone); 261 if (rc_orig == EOK) 262 return (int) rc; 263 else 264 return (int) rc_orig; 265 } 266 267 268 async_wait_for(req, &rc); 269 async_serialize_end(); 270 futex_up(&vfs_phone_futex); 291 271 free(mpa); 292 async_wait_for(req, &rc);293 272 294 273 return (int) rc; … … 297 276 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 298 277 { 299 int vfs_phone = vfs_exchange_begin(); 278 futex_down(&vfs_phone_futex); 279 async_serialize_start(); 280 vfs_connect(); 300 281 301 282 ipc_call_t answer; … … 304 285 305 286 if (rc != EOK) { 306 vfs_exchange_end(vfs_phone);307 308 287 sysarg_t rc_orig; 309 288 async_wait_for(req, &rc_orig); 310 289 311 if (rc_orig == EOK) 312 return (int) rc; 313 else 314 return (int) rc_orig; 315 } 316 317 vfs_exchange_end(vfs_phone); 318 async_wait_for(req, &rc); 290 async_serialize_end(); 291 futex_up(&vfs_phone_futex); 292 293 if (rc_orig == EOK) 294 return (int) rc; 295 else 296 return (int) rc_orig; 297 } 298 299 async_wait_for(req, &rc); 300 async_serialize_end(); 301 futex_up(&vfs_phone_futex); 319 302 320 303 if (rc != EOK) … … 339 322 int open_node(fdi_node_t *node, int oflag) 340 323 { 341 int vfs_phone = vfs_exchange_begin(); 324 futex_down(&vfs_phone_futex); 325 async_serialize_start(); 326 vfs_connect(); 342 327 343 328 ipc_call_t answer; … … 345 330 node->devmap_handle, node->index, oflag, &answer); 346 331 347 vfs_exchange_end(vfs_phone);348 349 sysarg_t rc;350 async_wait_for(req, &rc);332 sysarg_t rc; 333 async_wait_for(req, &rc); 334 async_serialize_end(); 335 futex_up(&vfs_phone_futex); 351 336 352 337 if (rc != EOK) … … 360 345 sysarg_t rc; 361 346 362 int vfs_phone = vfs_exchange_begin(); 347 futex_down(&vfs_phone_futex); 348 async_serialize_start(); 349 vfs_connect(); 363 350 364 351 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes); 365 352 366 vfs_exchange_end(vfs_phone); 353 async_serialize_end(); 354 futex_up(&vfs_phone_futex); 367 355 368 356 return (int)rc; … … 375 363 aid_t req; 376 364 377 int vfs_phone = vfs_exchange_begin(); 365 futex_down(&vfs_phone_futex); 366 async_serialize_start(); 367 vfs_connect(); 378 368 379 369 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 380 rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte, 381 IPC_XF_RESTRICT); 382 if (rc != EOK) { 383 vfs_exchange_end(vfs_phone); 384 370 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte); 371 if (rc != EOK) { 385 372 sysarg_t rc_orig; 386 async_wait_for(req, &rc_orig); 387 373 374 async_wait_for(req, &rc_orig); 375 async_serialize_end(); 376 futex_up(&vfs_phone_futex); 388 377 if (rc_orig == EOK) 389 378 return (ssize_t) rc; … … 391 380 return (ssize_t) rc_orig; 392 381 } 393 vfs_exchange_end(vfs_phone); 394 async_wait_for(req, &rc); 382 async_wait_for(req, &rc); 383 async_serialize_end(); 384 futex_up(&vfs_phone_futex); 395 385 if (rc == EOK) 396 386 return (ssize_t) IPC_GET_ARG1(answer); … … 405 395 aid_t req; 406 396 407 int vfs_phone = vfs_exchange_begin(); 397 futex_down(&vfs_phone_futex); 398 async_serialize_start(); 399 vfs_connect(); 408 400 409 401 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 410 rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte, 411 IPC_XF_RESTRICT); 412 if (rc != EOK) { 413 vfs_exchange_end(vfs_phone); 414 402 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte); 403 if (rc != EOK) { 415 404 sysarg_t rc_orig; 416 async_wait_for(req, &rc_orig); 417 405 406 async_wait_for(req, &rc_orig); 407 async_serialize_end(); 408 futex_up(&vfs_phone_futex); 418 409 if (rc_orig == EOK) 419 410 return (ssize_t) rc; … … 421 412 return (ssize_t) rc_orig; 422 413 } 423 vfs_exchange_end(vfs_phone); 424 async_wait_for(req, &rc); 414 async_wait_for(req, &rc); 415 async_serialize_end(); 416 futex_up(&vfs_phone_futex); 425 417 if (rc == EOK) 426 418 return (ssize_t) IPC_GET_ARG1(answer); … … 431 423 int fsync(int fildes) 432 424 { 433 int vfs_phone = vfs_exchange_begin(); 425 futex_down(&vfs_phone_futex); 426 async_serialize_start(); 427 vfs_connect(); 434 428 435 429 sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes); 436 430 437 vfs_exchange_end(vfs_phone); 431 async_serialize_end(); 432 futex_up(&vfs_phone_futex); 438 433 439 434 return (int) rc; … … 442 437 off64_t lseek(int fildes, off64_t offset, int whence) 443 438 { 444 int vfs_phone = vfs_exchange_begin(); 439 futex_down(&vfs_phone_futex); 440 async_serialize_start(); 441 vfs_connect(); 445 442 446 443 sysarg_t newoff_lo; … … 450 447 &newoff_lo, &newoff_hi); 451 448 452 vfs_exchange_end(vfs_phone); 449 async_serialize_end(); 450 futex_up(&vfs_phone_futex); 453 451 454 452 if (rc != EOK) … … 462 460 sysarg_t rc; 463 461 464 int vfs_phone = vfs_exchange_begin(); 462 futex_down(&vfs_phone_futex); 463 async_serialize_start(); 464 vfs_connect(); 465 465 466 466 rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes, 467 467 LOWER32(length), UPPER32(length)); 468 vfs_exchange_end(vfs_phone); 468 async_serialize_end(); 469 futex_up(&vfs_phone_futex); 469 470 470 471 return (int) rc; … … 476 477 aid_t req; 477 478 478 int vfs_phone = vfs_exchange_begin(); 479 futex_down(&vfs_phone_futex); 480 async_serialize_start(); 481 vfs_connect(); 479 482 480 483 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL); 481 484 rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat)); 482 485 if (rc != EOK) { 483 vfs_exchange_end(vfs_phone);484 485 486 sysarg_t rc_orig; 486 async_wait_for(req, &rc_orig); 487 487 488 async_wait_for(req, &rc_orig); 489 async_serialize_end(); 490 futex_up(&vfs_phone_futex); 488 491 if (rc_orig == EOK) 489 492 return (ssize_t) rc; … … 491 494 return (ssize_t) rc_orig; 492 495 } 493 vfs_exchange_end(vfs_phone); 494 async_wait_for(req, &rc); 496 async_wait_for(req, &rc); 497 async_serialize_end(); 498 futex_up(&vfs_phone_futex); 495 499 496 500 return rc; … … 508 512 return ENOMEM; 509 513 510 int vfs_phone = vfs_exchange_begin(); 514 futex_down(&vfs_phone_futex); 515 async_serialize_start(); 516 vfs_connect(); 511 517 512 518 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL); 513 519 rc = async_data_write_start(vfs_phone, pa, pa_size); 514 520 if (rc != EOK) { 515 vfs_exchange_end(vfs_phone); 521 async_wait_for(req, &rc_orig); 522 async_serialize_end(); 523 futex_up(&vfs_phone_futex); 516 524 free(pa); 517 async_wait_for(req, &rc_orig);518 525 if (rc_orig == EOK) 519 526 return (int) rc; … … 523 530 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat)); 524 531 if (rc != EOK) { 525 vfs_exchange_end(vfs_phone); 532 async_wait_for(req, &rc_orig); 533 async_serialize_end(); 534 futex_up(&vfs_phone_futex); 526 535 free(pa); 527 async_wait_for(req, &rc_orig); 528 if (rc_orig == EOK) 529 return (int) rc; 530 else 531 return (int) rc_orig; 532 } 533 vfs_exchange_end(vfs_phone); 536 if (rc_orig == EOK) 537 return (int) rc; 538 else 539 return (int) rc_orig; 540 } 541 async_wait_for(req, &rc); 542 async_serialize_end(); 543 futex_up(&vfs_phone_futex); 534 544 free(pa); 535 async_wait_for(req, &rc);536 545 return rc; 537 546 } … … 592 601 return ENOMEM; 593 602 594 int vfs_phone = vfs_exchange_begin(); 603 futex_down(&vfs_phone_futex); 604 async_serialize_start(); 605 vfs_connect(); 595 606 596 607 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL); 597 608 rc = async_data_write_start(vfs_phone, pa, pa_size); 598 609 if (rc != EOK) { 599 vfs_exchange_end(vfs_phone); 610 sysarg_t rc_orig; 611 612 async_wait_for(req, &rc_orig); 613 async_serialize_end(); 614 futex_up(&vfs_phone_futex); 600 615 free(pa); 601 602 sysarg_t rc_orig; 603 async_wait_for(req, &rc_orig); 604 605 if (rc_orig == EOK) 606 return (int) rc; 607 else 608 return (int) rc_orig; 609 } 610 vfs_exchange_end(vfs_phone); 616 if (rc_orig == EOK) 617 return (int) rc; 618 else 619 return (int) rc_orig; 620 } 621 async_wait_for(req, &rc); 622 async_serialize_end(); 623 futex_up(&vfs_phone_futex); 611 624 free(pa); 612 async_wait_for(req, &rc);613 625 return rc; 614 626 } … … 624 636 return ENOMEM; 625 637 626 int vfs_phone = vfs_exchange_begin(); 638 futex_down(&vfs_phone_futex); 639 async_serialize_start(); 640 vfs_connect(); 627 641 628 642 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL); 629 643 rc = async_data_write_start(vfs_phone, pa, pa_size); 630 644 if (rc != EOK) { 631 vfs_exchange_end(vfs_phone); 645 sysarg_t rc_orig; 646 647 async_wait_for(req, &rc_orig); 648 async_serialize_end(); 649 futex_up(&vfs_phone_futex); 632 650 free(pa); 633 634 sysarg_t rc_orig; 635 async_wait_for(req, &rc_orig); 636 637 if (rc_orig == EOK) 638 return (int) rc; 639 else 640 return (int) rc_orig; 641 } 642 vfs_exchange_end(vfs_phone); 651 if (rc_orig == EOK) 652 return (int) rc; 653 else 654 return (int) rc_orig; 655 } 656 async_wait_for(req, &rc); 657 async_serialize_end(); 658 futex_up(&vfs_phone_futex); 643 659 free(pa); 644 async_wait_for(req, &rc);645 660 return rc; 646 661 } … … 674 689 } 675 690 676 int vfs_phone = vfs_exchange_begin(); 691 futex_down(&vfs_phone_futex); 692 async_serialize_start(); 693 vfs_connect(); 677 694 678 695 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL); 679 696 rc = async_data_write_start(vfs_phone, olda, olda_size); 680 697 if (rc != EOK) { 681 vfs_exchange_end(vfs_phone); 698 async_wait_for(req, &rc_orig); 699 async_serialize_end(); 700 futex_up(&vfs_phone_futex); 682 701 free(olda); 683 702 free(newa); 684 async_wait_for(req, &rc_orig);685 703 if (rc_orig == EOK) 686 704 return (int) rc; … … 690 708 rc = async_data_write_start(vfs_phone, newa, newa_size); 691 709 if (rc != EOK) { 692 vfs_exchange_end(vfs_phone); 710 async_wait_for(req, &rc_orig); 711 async_serialize_end(); 712 futex_up(&vfs_phone_futex); 693 713 free(olda); 694 714 free(newa); 695 async_wait_for(req, &rc_orig); 696 if (rc_orig == EOK) 697 return (int) rc; 698 else 699 return (int) rc_orig; 700 } 701 vfs_exchange_end(vfs_phone); 715 if (rc_orig == EOK) 716 return (int) rc; 717 else 718 return (int) rc_orig; 719 } 720 async_wait_for(req, &rc); 721 async_serialize_end(); 722 futex_up(&vfs_phone_futex); 702 723 free(olda); 703 724 free(newa); 704 async_wait_for(req, &rc);705 725 return rc; 706 726 } … … 720 740 } 721 741 722 f ibril_mutex_lock(&cwd_mutex);742 futex_down(&cwd_futex); 723 743 724 744 if (cwd_fd >= 0) … … 733 753 cwd_size = abs_size; 734 754 735 f ibril_mutex_unlock(&cwd_mutex);755 futex_up(&cwd_futex); 736 756 return EOK; 737 757 } … … 742 762 return NULL; 743 763 744 f ibril_mutex_lock(&cwd_mutex);764 futex_down(&cwd_futex); 745 765 746 766 if ((cwd_size == 0) || (size < cwd_size + 1)) { 747 f ibril_mutex_unlock(&cwd_mutex);767 futex_up(&cwd_futex); 748 768 return NULL; 749 769 } 750 770 751 771 str_cpy(buf, size, cwd_path); 752 f ibril_mutex_unlock(&cwd_mutex);772 futex_up(&cwd_futex); 753 773 754 774 return buf; … … 758 778 { 759 779 struct stat stat; 760 761 int rc = fstat(fildes, &stat); 762 if (rc != 0) 763 return rc; 764 780 int rc; 781 782 rc = fstat(fildes, &stat); 783 765 784 if (!stat.device) 766 785 return -1; … … 787 806 int dup2(int oldfd, int newfd) 788 807 { 789 int vfs_phone = vfs_exchange_begin(); 808 futex_down(&vfs_phone_futex); 809 async_serialize_start(); 810 vfs_connect(); 790 811 791 812 sysarg_t ret; 792 813 sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret); 793 814 794 vfs_exchange_end(vfs_phone); 815 async_serialize_end(); 816 futex_up(&vfs_phone_futex); 795 817 796 818 if (rc == EOK)
Note:
See TracChangeset
for help on using the changeset viewer.