Changeset a35b458 in mainline for uspace/srv/vfs/vfs_ops.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
r3061bc1 ra35b458 64 64 { 65 65 size_t res = 0; 66 66 67 67 while (a[res] == b[res] && a[res] != 0) 68 68 res++; 69 69 70 70 if (a[res] == b[res]) 71 71 return res; 72 72 73 73 res--; 74 74 while (a[res] != '/') … … 93 93 if (oldfd == newfd) 94 94 return EOK; 95 95 96 96 /* Lookup the file structure corresponding to fd. */ 97 97 vfs_file_t *oldfile = vfs_file_get(oldfd); … … 112 112 newfile->permissions = oldfile->permissions; 113 113 vfs_node_addref(newfile->node); 114 114 115 115 vfs_file_put(newfile); 116 116 } 117 117 } 118 118 vfs_file_put(oldfile); 119 119 120 120 return rc; 121 121 } … … 131 131 { 132 132 fs_handle_t fs_handle = 0; 133 133 134 134 fibril_mutex_lock(&fs_list_lock); 135 135 while (true) { 136 136 fs_handle = fs_name_to_handle(instance, fsname, false); 137 137 138 138 if (fs_handle != 0 || !(flags & VFS_MOUNT_BLOCKING)) 139 139 break; 140 140 141 141 fibril_condvar_wait(&fs_list_cv, &fs_list_lock); 142 142 } … … 145 145 if (fs_handle == 0) 146 146 return ENOFS; 147 147 148 148 /* Tell the mountee that it is being mounted. */ 149 149 ipc_call_t answer; … … 164 164 return rc; 165 165 } 166 166 167 167 vfs_lookup_res_t res; 168 168 res.triplet.fs_handle = fs_handle; … … 172 172 IPC_GET_ARG3(answer)); 173 173 res.type = VFS_NODE_DIRECTORY; 174 174 175 175 /* Add reference to the mounted root. */ 176 176 *root = vfs_node_get(&res); … … 182 182 return ENOMEM; 183 183 } 184 184 185 185 vfs_exchange_release(exch); 186 186 … … 194 194 errno_t rc; 195 195 errno_t retval; 196 196 197 197 fibril_mutex_lock(&fs_list_lock); 198 198 fs_handle = fs_name_to_handle(0, fs_name, false); 199 199 fibril_mutex_unlock(&fs_list_lock); 200 200 201 201 if (fs_handle == 0) 202 202 return ENOFS; 203 203 204 204 /* Send probe request to the file system server */ 205 205 ipc_call_t answer; … … 209 209 if (msg == 0) 210 210 return EINVAL; 211 211 212 212 /* Read probe information */ 213 213 retval = async_data_read_start(exch, info, sizeof(*info)); … … 216 216 return retval; 217 217 } 218 218 219 219 async_wait_for(msg, &rc); 220 220 vfs_exchange_release(exch); … … 229 229 vfs_file_t *file = NULL; 230 230 *out_fd = -1; 231 231 232 232 if (!(flags & VFS_MOUNT_CONNECT_ONLY)) { 233 233 mp = vfs_file_get(mpfd); … … 236 236 goto out; 237 237 } 238 238 239 239 if (mp->node->mount != NULL) { 240 240 rc = EBUSY; 241 241 goto out; 242 242 } 243 243 244 244 if (mp->node->type != VFS_NODE_DIRECTORY) { 245 245 rc = ENOTDIR; 246 246 goto out; 247 247 } 248 248 249 249 if (vfs_node_has_children(mp->node)) { 250 250 rc = ENOTEMPTY; … … 252 252 } 253 253 } 254 254 255 255 if (!(flags & VFS_MOUNT_NO_REF)) { 256 256 rc = vfs_fd_alloc(&file, false, out_fd); … … 259 259 } 260 260 } 261 261 262 262 vfs_node_t *root = NULL; 263 263 264 264 fibril_rwlock_write_lock(&namespace_rwlock); 265 265 … … 271 271 mp->node->mount = root; 272 272 } 273 273 274 274 fibril_rwlock_write_unlock(&namespace_rwlock); 275 275 276 276 if (rc != EOK) 277 277 goto out; 278 278 279 279 if (flags & VFS_MOUNT_NO_REF) { 280 280 vfs_node_delref(root); 281 281 } else { 282 282 assert(file != NULL); 283 283 284 284 file->node = root; 285 285 file->permissions = MODE_READ | MODE_WRITE | MODE_APPEND; … … 287 287 file->open_write = false; 288 288 } 289 289 290 290 out: 291 291 if (mp) … … 298 298 *out_fd = -1; 299 299 } 300 300 301 301 return rc; 302 302 } … … 310 310 if (!file) 311 311 return EBADF; 312 312 313 313 if ((mode & ~file->permissions) != 0) { 314 314 vfs_file_put(file); 315 315 return EPERM; 316 316 } 317 317 318 318 if (file->open_read || file->open_write) { 319 319 vfs_file_put(file); 320 320 return EBUSY; 321 321 } 322 322 323 323 file->open_read = (mode & MODE_READ) != 0; 324 324 file->open_write = (mode & (MODE_WRITE | MODE_APPEND)) != 0; 325 325 file->append = (mode & MODE_APPEND) != 0; 326 326 327 327 if (!file->open_read && !file->open_write) { 328 328 vfs_file_put(file); 329 329 return EINVAL; 330 330 } 331 331 332 332 if (file->node->type == VFS_NODE_DIRECTORY && file->open_write) { 333 333 file->open_read = file->open_write = false; … … 335 335 return EINVAL; 336 336 } 337 337 338 338 errno_t rc = vfs_open_node_remote(file->node); 339 339 if (rc != EOK) { … … 342 342 return rc; 343 343 } 344 344 345 345 vfs_file_put(file); 346 346 return EOK; … … 385 385 if (exch == NULL) 386 386 return ENOENT; 387 387 388 388 aid_t msg = async_send_fast(exch, read ? VFS_OUT_READ : VFS_OUT_WRITE, 389 389 file->node->service_id, file->node->index, LOWER32(pos), … … 397 397 return retval; 398 398 } 399 399 400 400 errno_t rc; 401 401 async_wait_for(msg, &rc); 402 402 403 403 chunk->size = IPC_GET_ARG1(*answer); 404 404 … … 418 418 * open files supports parallel access! 419 419 */ 420 420 421 421 /* Lookup the file structure corresponding to the file descriptor. */ 422 422 vfs_file_t *file = vfs_file_get(fd); 423 423 if (!file) 424 424 return EBADF; 425 425 426 426 if ((read && !file->open_read) || (!read && !file->open_write)) { 427 427 vfs_file_put(file); 428 428 return EINVAL; 429 429 } 430 430 431 431 vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle); 432 432 assert(fs_info); 433 433 434 434 bool rlock = read || 435 435 (fs_info->concurrent_read_write && fs_info->write_retains_size); 436 436 437 437 /* 438 438 * Lock the file's node so that no other client can read/write to it at … … 444 444 else 445 445 fibril_rwlock_write_lock(&file->node->contents_rwlock); 446 446 447 447 if (file->node->type == VFS_NODE_DIRECTORY) { 448 448 /* … … 450 450 * while we are in readdir(). 451 451 */ 452 452 453 453 if (!read) { 454 454 if (rlock) { … … 462 462 return EINVAL; 463 463 } 464 464 465 465 fibril_rwlock_read_lock(&namespace_rwlock); 466 466 } 467 467 468 468 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 469 469 470 470 if (!read && file->append) 471 471 pos = file->node->size; 472 472 473 473 /* 474 474 * Handle communication with the endpoint FS. … … 476 476 ipc_call_t answer; 477 477 errno_t rc = ipc_cb(fs_exch, file, pos, &answer, read, ipc_cb_data); 478 478 479 479 vfs_exchange_release(fs_exch); 480 480 481 481 if (file->node->type == VFS_NODE_DIRECTORY) 482 482 fibril_rwlock_read_unlock(&namespace_rwlock); 483 483 484 484 /* Unlock the VFS node. */ 485 485 if (rlock) { … … 493 493 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 494 494 } 495 495 496 496 vfs_file_put(file); 497 497 … … 518 518 vfs_node_addref(base); 519 519 vfs_file_put(base_file); 520 520 521 521 vfs_lookup_res_t base_lr; 522 522 vfs_lookup_res_t old_lr; 523 523 vfs_lookup_res_t new_lr_orig; 524 524 bool orig_unlinked = false; 525 525 526 526 errno_t rc; 527 527 528 528 size_t shared = shared_path(old, new); 529 529 530 530 /* Do not allow one path to be a prefix of the other. */ 531 531 if (old[shared] == 0 || new[shared] == 0) { … … 535 535 assert(old[shared] == '/'); 536 536 assert(new[shared] == '/'); 537 537 538 538 fibril_rwlock_write_lock(&namespace_rwlock); 539 539 540 540 /* Resolve the shared portion of the path first. */ 541 541 if (shared != 0) { … … 547 547 return rc; 548 548 } 549 549 550 550 vfs_node_put(base); 551 551 base = vfs_node_get(&base_lr); … … 565 565 return rc; 566 566 } 567 567 568 568 rc = vfs_lookup_internal(base, new, L_UNLINK | L_DISABLE_MOUNTS, 569 569 &new_lr_orig); … … 595 595 return rc; 596 596 } 597 597 598 598 /* If the node is not held by anyone, try to destroy it. */ 599 599 if (orig_unlinked) { … … 604 604 vfs_node_put(node); 605 605 } 606 606 607 607 vfs_node_put(base); 608 608 fibril_rwlock_write_unlock(&namespace_rwlock); … … 617 617 618 618 fibril_rwlock_write_lock(&file->node->contents_rwlock); 619 619 620 620 errno_t rc = vfs_truncate_internal(file->node->fs_handle, 621 621 file->node->service_id, file->node->index, size); 622 622 if (rc == EOK) 623 623 file->node->size = size; 624 624 625 625 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 626 626 vfs_file_put(file); … … 640 640 node->service_id, node->index, true, 0, NULL); 641 641 vfs_exchange_release(exch); 642 642 643 643 vfs_file_put(file); 644 644 return rc; … … 667 667 if (!file) 668 668 return EBADF; 669 669 670 670 async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle); 671 671 672 672 aid_t msg; 673 673 ipc_call_t answer; 674 674 msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->service_id, 675 675 file->node->index, &answer); 676 676 677 677 vfs_exchange_release(fs_exch); 678 678 679 679 errno_t rc; 680 680 async_wait_for(msg, &rc); 681 681 682 682 vfs_file_put(file); 683 683 return rc; 684 684 685 685 } 686 686 … … 693 693 UPPER32(size)); 694 694 vfs_exchange_release(exch); 695 695 696 696 return (errno_t) rc; 697 697 } … … 702 702 vfs_file_t *parent = NULL; 703 703 vfs_file_t *expect = NULL; 704 704 705 705 if (parentfd == expectfd) 706 706 return EINVAL; 707 707 708 708 fibril_rwlock_write_lock(&namespace_rwlock); 709 709 710 710 /* 711 711 * Files are retrieved in order of file descriptors, to prevent … … 719 719 } 720 720 } 721 721 722 722 if (expectfd >= 0) { 723 723 expect = vfs_file_get(expectfd); … … 727 727 } 728 728 } 729 729 730 730 if (parentfd > expectfd) { 731 731 parent = vfs_file_get(parentfd); … … 735 735 } 736 736 } 737 737 738 738 assert(parent != NULL); 739 739 740 740 if (expectfd >= 0) { 741 741 vfs_lookup_res_t lr; … … 743 743 if (rc != EOK) 744 744 goto exit; 745 745 746 746 vfs_node_t *found_node = vfs_node_peek(&lr); 747 747 vfs_node_put(found_node); … … 750 750 goto exit; 751 751 } 752 752 753 753 vfs_file_put(expect); 754 754 expect = NULL; 755 755 } 756 756 757 757 vfs_lookup_res_t lr; 758 758 rc = vfs_lookup_internal(parent->node, path, L_UNLINK, &lr); … … 783 783 if (mp == NULL) 784 784 return EBADF; 785 785 786 786 if (mp->node->mount == NULL) { 787 787 vfs_file_put(mp); 788 788 return ENOENT; 789 789 } 790 790 791 791 fibril_rwlock_write_lock(&namespace_rwlock); 792 792 793 793 /* 794 794 * Count the total number of references for the mounted file system. We … … 804 804 return EBUSY; 805 805 } 806 806 807 807 async_exch_t *exch = vfs_exchange_grab(mp->node->mount->fs_handle); 808 808 errno_t rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, 809 809 mp->node->mount->service_id); 810 810 vfs_exchange_release(exch); 811 811 812 812 if (rc != EOK) { 813 813 vfs_file_put(mp); … … 815 815 return rc; 816 816 } 817 817 818 818 vfs_node_forget(mp->node->mount); 819 819 vfs_node_put(mp->node); 820 820 mp->node->mount = NULL; 821 821 822 822 fibril_rwlock_write_unlock(&namespace_rwlock); 823 823 824 824 vfs_file_put(mp); 825 825 return EOK; … … 866 866 if (!walk_flags_valid(flags)) 867 867 return EINVAL; 868 868 869 869 vfs_file_t *parent = vfs_file_get(parentfd); 870 870 if (!parent) 871 871 return EBADF; 872 872 873 873 fibril_rwlock_read_lock(&namespace_rwlock); 874 874 875 875 vfs_lookup_res_t lr; 876 876 errno_t rc = vfs_lookup_internal(parent->node, path, … … 881 881 return rc; 882 882 } 883 883 884 884 vfs_node_t *node = vfs_node_get(&lr); 885 885 if (!node) { … … 888 888 return ENOMEM; 889 889 } 890 890 891 891 vfs_file_t *file; 892 892 rc = vfs_fd_alloc(&file, false, out_fd); … … 897 897 } 898 898 assert(file != NULL); 899 899 900 900 file->node = node; 901 901 file->permissions = parent->permissions; 902 902 file->open_read = false; 903 903 file->open_write = false; 904 904 905 905 vfs_file_put(file); 906 906 vfs_file_put(parent); 907 907 908 908 fibril_rwlock_read_unlock(&namespace_rwlock); 909 909
Note:
See TracChangeset
for help on using the changeset viewer.