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