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