Changes in uspace/srv/vfs/vfs_ops.c [ffa2c8ef:dd2cfa7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
rffa2c8ef rdd2cfa7 37 37 38 38 #include "vfs.h" 39 #include <macros.h> 40 #include <stdint.h> 39 #include <ipc/ipc.h> 41 40 #include <async.h> 42 41 #include <errno.h> 43 42 #include <stdio.h> 44 43 #include <stdlib.h> 45 #include <str .h>44 #include <string.h> 46 45 #include <bool.h> 47 #include <fibril_sync h.h>46 #include <fibril_sync.h> 48 47 #include <adt/list.h> 49 48 #include <unistd.h> … … 54 53 55 54 /* Forward declarations of static functions. */ 56 static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t, 57 aoff64_t); 55 static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t); 58 56 59 57 /** … … 65 63 vfs_pair_t rootfs = { 66 64 .fs_handle = 0, 67 .dev map_handle = 065 .dev_handle = 0 68 66 }; 69 67 70 static void vfs_mount_internal(ipc_callid_t rid, dev map_handle_t devmap_handle,68 static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, 71 69 fs_handle_t fs_handle, char *mp, char *opts) 72 70 { … … 78 76 size_t rsize; 79 77 unsigned rlnkcnt; 80 sysarg_t rc;78 ipcarg_t rc; 81 79 int phone; 82 80 aid_t msg; … … 90 88 /* Trying to mount root FS over root FS */ 91 89 fibril_rwlock_write_unlock(&namespace_rwlock); 92 async_answer_0(rid, EBUSY);90 ipc_answer_0(rid, EBUSY); 93 91 return; 94 92 } 95 93 96 rc = vfs_lookup_internal(mp, L_ MP, &mp_res, NULL);94 rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL); 97 95 if (rc != EOK) { 98 96 /* The lookup failed for some reason. */ 99 97 fibril_rwlock_write_unlock(&namespace_rwlock); 100 async_answer_0(rid, rc);98 ipc_answer_0(rid, rc); 101 99 return; 102 100 } … … 105 103 if (!mp_node) { 106 104 fibril_rwlock_write_unlock(&namespace_rwlock); 107 async_answer_0(rid, ENOMEM);105 ipc_answer_0(rid, ENOMEM); 108 106 return; 109 107 } … … 125 123 phone = vfs_grab_phone(fs_handle); 126 124 msg = async_send_1(phone, VFS_OUT_MOUNTED, 127 ( sysarg_t) devmap_handle, &answer);125 (ipcarg_t) dev_handle, &answer); 128 126 /* send the mount options */ 129 rc = async_data_write_start(phone, (void *)opts,127 rc = ipc_data_write_start(phone, (void *)opts, 130 128 str_size(opts)); 131 129 if (rc != EOK) { 132 130 async_wait_for(msg, NULL); 133 vfs_release_phone( fs_handle,phone);131 vfs_release_phone(phone); 134 132 fibril_rwlock_write_unlock(&namespace_rwlock); 135 async_answer_0(rid, rc);133 ipc_answer_0(rid, rc); 136 134 return; 137 135 } 138 136 async_wait_for(msg, &rc); 139 vfs_release_phone( fs_handle,phone);137 vfs_release_phone(phone); 140 138 141 139 if (rc != EOK) { 142 140 fibril_rwlock_write_unlock(&namespace_rwlock); 143 async_answer_0(rid, rc);141 ipc_answer_0(rid, rc); 144 142 return; 145 143 } … … 150 148 151 149 mr_res.triplet.fs_handle = fs_handle; 152 mr_res.triplet.dev map_handle = devmap_handle;150 mr_res.triplet.dev_handle = dev_handle; 153 151 mr_res.triplet.index = rindex; 154 152 mr_res.size = rsize; … … 157 155 158 156 rootfs.fs_handle = fs_handle; 159 rootfs.dev map_handle = devmap_handle;157 rootfs.dev_handle = dev_handle; 160 158 161 159 /* Add reference to the mounted root. */ … … 164 162 165 163 fibril_rwlock_write_unlock(&namespace_rwlock); 166 async_answer_0(rid, rc);164 ipc_answer_0(rid, rc); 167 165 return; 168 166 } else { … … 172 170 */ 173 171 fibril_rwlock_write_unlock(&namespace_rwlock); 174 async_answer_0(rid, ENOENT);172 ipc_answer_0(rid, ENOENT); 175 173 return; 176 174 } … … 187 185 phone = vfs_grab_phone(mp_res.triplet.fs_handle); 188 186 msg = async_send_4(phone, VFS_OUT_MOUNT, 189 ( sysarg_t) mp_res.triplet.devmap_handle,190 ( sysarg_t) mp_res.triplet.index,191 ( sysarg_t) fs_handle,192 ( sysarg_t) devmap_handle, &answer);187 (ipcarg_t) mp_res.triplet.dev_handle, 188 (ipcarg_t) mp_res.triplet.index, 189 (ipcarg_t) fs_handle, 190 (ipcarg_t) dev_handle, &answer); 193 191 194 192 /* send connection */ … … 196 194 if (rc != EOK) { 197 195 async_wait_for(msg, NULL); 198 vfs_release_phone( fs_handle,mountee_phone);199 vfs_release_phone( mp_res.triplet.fs_handle,phone);196 vfs_release_phone(mountee_phone); 197 vfs_release_phone(phone); 200 198 /* Mount failed, drop reference to mp_node. */ 201 199 if (mp_node) 202 200 vfs_node_put(mp_node); 203 async_answer_0(rid, rc);201 ipc_answer_0(rid, rc); 204 202 fibril_rwlock_write_unlock(&namespace_rwlock); 205 203 return; 206 204 } 207 205 208 vfs_release_phone( fs_handle,mountee_phone);206 vfs_release_phone(mountee_phone); 209 207 210 208 /* send the mount options */ 211 rc = async_data_write_start(phone, (void *)opts, str_size(opts));209 rc = ipc_data_write_start(phone, (void *)opts, str_size(opts)); 212 210 if (rc != EOK) { 213 211 async_wait_for(msg, NULL); 214 vfs_release_phone( mp_res.triplet.fs_handle,phone);212 vfs_release_phone(phone); 215 213 /* Mount failed, drop reference to mp_node. */ 216 214 if (mp_node) 217 215 vfs_node_put(mp_node); 218 216 fibril_rwlock_write_unlock(&namespace_rwlock); 219 async_answer_0(rid, rc);217 ipc_answer_0(rid, rc); 220 218 return; 221 219 } 222 220 async_wait_for(msg, &rc); 223 vfs_release_phone( mp_res.triplet.fs_handle,phone);221 vfs_release_phone(phone); 224 222 225 223 if (rc == EOK) { … … 229 227 230 228 mr_res.triplet.fs_handle = fs_handle; 231 mr_res.triplet.dev map_handle = devmap_handle;229 mr_res.triplet.dev_handle = dev_handle; 232 230 mr_res.triplet.index = rindex; 233 231 mr_res.size = rsize; … … 244 242 } 245 243 246 async_answer_0(rid, rc);244 ipc_answer_0(rid, rc); 247 245 fibril_rwlock_write_unlock(&namespace_rwlock); 248 246 } … … 250 248 void vfs_mount(ipc_callid_t rid, ipc_call_t *request) 251 249 { 252 devmap_handle_t devmap_handle;253 254 250 /* 255 251 * We expect the library to do the device-name to device-handle … … 257 253 * in the request. 258 254 */ 259 dev map_handle = (devmap_handle_t) IPC_GET_ARG1(*request);255 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 260 256 261 257 /* … … 270 266 271 267 /* We want the client to send us the mount point. */ 272 char *mp; 273 int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN, 274 0, NULL); 275 if (rc != EOK) { 276 async_answer_0(rid, rc); 277 return; 278 } 268 ipc_callid_t callid; 269 size_t size; 270 if (!ipc_data_write_receive(&callid, &size)) { 271 ipc_answer_0(callid, EINVAL); 272 ipc_answer_0(rid, EINVAL); 273 return; 274 } 275 276 /* Check whether size is reasonable wrt. the mount point. */ 277 if ((size < 1) || (size > MAX_PATH_LEN)) { 278 ipc_answer_0(callid, EINVAL); 279 ipc_answer_0(rid, EINVAL); 280 return; 281 } 282 283 /* Allocate buffer for the mount point data being received. */ 284 char *mp = malloc(size + 1); 285 if (!mp) { 286 ipc_answer_0(callid, ENOMEM); 287 ipc_answer_0(rid, ENOMEM); 288 return; 289 } 290 291 /* Deliver the mount point. */ 292 ipcarg_t retval = ipc_data_write_finalize(callid, mp, size); 293 if (retval != EOK) { 294 ipc_answer_0(rid, retval); 295 free(mp); 296 return; 297 } 298 mp[size] = '\0'; 279 299 280 300 /* Now we expect to receive the mount options. */ 281 char *opts; 282 rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN, 283 0, NULL); 284 if (rc != EOK) { 301 if (!ipc_data_write_receive(&callid, &size)) { 302 ipc_answer_0(callid, EINVAL); 303 ipc_answer_0(rid, EINVAL); 285 304 free(mp); 286 async_answer_0(rid, rc); 287 return; 288 } 305 return; 306 } 307 308 /* Check the offered options size. */ 309 if (size > MAX_MNTOPTS_LEN) { 310 ipc_answer_0(callid, EINVAL); 311 ipc_answer_0(rid, EINVAL); 312 free(mp); 313 return; 314 } 315 316 /* Allocate buffer for the mount options. */ 317 char *opts = (char *) malloc(size + 1); 318 if (!opts) { 319 ipc_answer_0(callid, ENOMEM); 320 ipc_answer_0(rid, ENOMEM); 321 free(mp); 322 return; 323 } 324 325 /* Deliver the mount options. */ 326 retval = ipc_data_write_finalize(callid, opts, size); 327 if (retval != EOK) { 328 ipc_answer_0(rid, retval); 329 free(mp); 330 free(opts); 331 return; 332 } 333 opts[size] = '\0'; 289 334 290 335 /* … … 292 337 * system. 293 338 */ 294 char *fs_name; 295 rc = async_data_write_accept((void **) &fs_name, true, 0, 296 FS_NAME_MAXLEN, 0, NULL); 297 if (rc != EOK) { 339 if (!ipc_data_write_receive(&callid, &size)) { 340 ipc_answer_0(callid, EINVAL); 341 ipc_answer_0(rid, EINVAL); 298 342 free(mp); 299 343 free(opts); 300 async_answer_0(rid, rc); 301 return; 302 } 303 344 return; 345 } 346 347 /* 348 * Don't receive more than is necessary for storing a full file system 349 * name. 350 */ 351 if ((size < 1) || (size > FS_NAME_MAXLEN)) { 352 ipc_answer_0(callid, EINVAL); 353 ipc_answer_0(rid, EINVAL); 354 free(mp); 355 free(opts); 356 return; 357 } 358 359 /* 360 * Allocate buffer for file system name. 361 */ 362 char *fs_name = (char *) malloc(size + 1); 363 if (fs_name == NULL) { 364 ipc_answer_0(callid, ENOMEM); 365 ipc_answer_0(rid, ENOMEM); 366 free(mp); 367 free(opts); 368 return; 369 } 370 371 /* Deliver the file system name. */ 372 retval = ipc_data_write_finalize(callid, fs_name, size); 373 if (retval != EOK) { 374 ipc_answer_0(rid, retval); 375 free(mp); 376 free(opts); 377 free(fs_name); 378 return; 379 } 380 fs_name[size] = '\0'; 381 304 382 /* 305 383 * Wait for IPC_M_PING so that we can return an error if we don't know … … 307 385 */ 308 386 ipc_call_t data; 309 ipc_callid_tcallid = async_get_call(&data);310 if (IPC_GET_ IMETHOD(data) != IPC_M_PING) {311 async_answer_0(callid, ENOTSUP);312 async_answer_0(rid, ENOTSUP);387 callid = async_get_call(&data); 388 if (IPC_GET_METHOD(data) != IPC_M_PING) { 389 ipc_answer_0(callid, ENOTSUP); 390 ipc_answer_0(rid, ENOTSUP); 313 391 free(mp); 314 392 free(opts); … … 332 410 333 411 fibril_mutex_unlock(&fs_head_lock); 334 async_answer_0(callid, ENOENT);335 async_answer_0(rid, ENOENT);412 ipc_answer_0(callid, ENOENT); 413 ipc_answer_0(rid, ENOENT); 336 414 free(mp); 337 415 free(fs_name); … … 342 420 343 421 /* Acknowledge that we know fs_name. */ 344 async_answer_0(callid, EOK);422 ipc_answer_0(callid, EOK); 345 423 346 424 /* Do the mount */ 347 vfs_mount_internal(rid, dev map_handle, fs_handle, mp, opts);425 vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts); 348 426 free(mp); 349 427 free(fs_name); … … 351 429 } 352 430 353 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)354 {355 int rc;356 char *mp;357 vfs_lookup_res_t mp_res;358 vfs_lookup_res_t mr_res;359 vfs_node_t *mr_node;360 int phone;361 362 /*363 * Receive the mount point path.364 */365 rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,366 0, NULL);367 if (rc != EOK)368 async_answer_0(rid, rc);369 370 /*371 * Taking the namespace lock will do two things for us. First, it will372 * prevent races with other lookup operations. Second, it will stop new373 * references to already existing VFS nodes and creation of new VFS374 * nodes. This is because new references are added as a result of some375 * lookup operation or at least of some operation which is protected by376 * the namespace lock.377 */378 fibril_rwlock_write_lock(&namespace_rwlock);379 380 /*381 * Lookup the mounted root and instantiate it.382 */383 rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);384 if (rc != EOK) {385 fibril_rwlock_write_unlock(&namespace_rwlock);386 free(mp);387 async_answer_0(rid, rc);388 return;389 }390 mr_node = vfs_node_get(&mr_res);391 if (!mr_node) {392 fibril_rwlock_write_unlock(&namespace_rwlock);393 free(mp);394 async_answer_0(rid, ENOMEM);395 return;396 }397 398 /*399 * Count the total number of references for the mounted file system. We400 * are expecting at least two. One which we got above and one which we401 * got when the file system was mounted. If we find more, it means that402 * the file system cannot be gracefully unmounted at the moment because403 * someone is working with it.404 */405 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,406 mr_node->devmap_handle) != 2) {407 fibril_rwlock_write_unlock(&namespace_rwlock);408 vfs_node_put(mr_node);409 free(mp);410 async_answer_0(rid, EBUSY);411 return;412 }413 414 if (str_cmp(mp, "/") == 0) {415 416 /*417 * Unmounting the root file system.418 *419 * In this case, there is no mount point node and we send420 * VFS_OUT_UNMOUNTED directly to the mounted file system.421 */422 423 free(mp);424 phone = vfs_grab_phone(mr_node->fs_handle);425 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,426 mr_node->devmap_handle);427 vfs_release_phone(mr_node->fs_handle, phone);428 if (rc != EOK) {429 fibril_rwlock_write_unlock(&namespace_rwlock);430 vfs_node_put(mr_node);431 async_answer_0(rid, rc);432 return;433 }434 rootfs.fs_handle = 0;435 rootfs.devmap_handle = 0;436 } else {437 438 /*439 * Unmounting a non-root file system.440 *441 * We have a regular mount point node representing the parent442 * file system, so we delegate the operation to it.443 */444 445 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);446 free(mp);447 if (rc != EOK) {448 fibril_rwlock_write_unlock(&namespace_rwlock);449 vfs_node_put(mr_node);450 async_answer_0(rid, rc);451 return;452 }453 vfs_node_t *mp_node = vfs_node_get(&mp_res);454 if (!mp_node) {455 fibril_rwlock_write_unlock(&namespace_rwlock);456 vfs_node_put(mr_node);457 async_answer_0(rid, ENOMEM);458 return;459 }460 461 phone = vfs_grab_phone(mp_node->fs_handle);462 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT,463 mp_node->devmap_handle, mp_node->index);464 vfs_release_phone(mp_node->fs_handle, phone);465 if (rc != EOK) {466 fibril_rwlock_write_unlock(&namespace_rwlock);467 vfs_node_put(mp_node);468 vfs_node_put(mr_node);469 async_answer_0(rid, rc);470 return;471 }472 473 /* Drop the reference we got above. */474 vfs_node_put(mp_node);475 /* Drop the reference from when the file system was mounted. */476 vfs_node_put(mp_node);477 }478 479 480 /*481 * All went well, the mounted file system was successfully unmounted.482 * The only thing left is to forget the unmounted root VFS node.483 */484 vfs_node_forget(mr_node);485 486 fibril_rwlock_write_unlock(&namespace_rwlock);487 async_answer_0(rid, EOK);488 }489 490 431 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 491 432 { 433 if (!vfs_files_init()) { 434 ipc_answer_0(rid, ENOMEM); 435 return; 436 } 437 492 438 /* 493 439 * The POSIX interface is open(path, oflag, mode). … … 501 447 int oflag = IPC_GET_ARG2(*request); 502 448 int mode = IPC_GET_ARG3(*request); 449 size_t len; 503 450 504 451 /* Ignore mode for now. */ … … 507 454 /* 508 455 * Make sure that we are called with exactly one of L_FILE and 509 * L_DIRECTORY. Make sure that the user does not pass L_OPEN, 510 * L_ROOT or L_MP. 456 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 511 457 */ 512 458 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) || 513 459 ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) || 514 ( lflag & (L_OPEN | L_ROOT | L_MP))) {515 async_answer_0(rid, EINVAL);460 ((lflag & L_OPEN) != 0)) { 461 ipc_answer_0(rid, EINVAL); 516 462 return; 517 463 } … … 522 468 lflag |= L_EXCLUSIVE; 523 469 524 char *path; 525 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 526 if (rc != EOK) { 527 async_answer_0(rid, rc); 528 return; 529 } 470 ipc_callid_t callid; 471 if (!ipc_data_write_receive(&callid, &len)) { 472 ipc_answer_0(callid, EINVAL); 473 ipc_answer_0(rid, EINVAL); 474 return; 475 } 476 477 char *path = malloc(len + 1); 478 if (!path) { 479 ipc_answer_0(callid, ENOMEM); 480 ipc_answer_0(rid, ENOMEM); 481 return; 482 } 483 484 int rc; 485 if ((rc = ipc_data_write_finalize(callid, path, len))) { 486 ipc_answer_0(rid, rc); 487 free(path); 488 return; 489 } 490 path[len] = '\0'; 530 491 531 492 /* … … 547 508 else 548 509 fibril_rwlock_read_unlock(&namespace_rwlock); 549 async_answer_0(rid, rc);510 ipc_answer_0(rid, rc); 550 511 free(path); 551 512 return; … … 566 527 if (node->size) { 567 528 rc = vfs_truncate_internal(node->fs_handle, 568 node->dev map_handle, node->index, 0);529 node->dev_handle, node->index, 0); 569 530 if (rc) { 570 531 fibril_rwlock_write_unlock(&node->contents_rwlock); 571 532 vfs_node_put(node); 572 async_answer_0(rid, rc);533 ipc_answer_0(rid, rc); 573 534 return; 574 535 } … … 582 543 * structure. 583 544 */ 584 int fd = vfs_fd_alloc( (oflag & O_DESC) != 0);545 int fd = vfs_fd_alloc(); 585 546 if (fd < 0) { 586 547 vfs_node_put(node); 587 async_answer_0(rid, fd);548 ipc_answer_0(rid, fd); 588 549 return; 589 550 } 590 551 vfs_file_t *file = vfs_file_get(fd); 591 assert(file);592 552 file->node = node; 593 553 if (oflag & O_APPEND) … … 603 563 vfs_node_addref(node); 604 564 vfs_node_put(node); 605 vfs_file_put(file);606 565 607 566 /* Success! Return the new file descriptor to the client. */ 608 async_answer_1(rid, EOK, fd);567 ipc_answer_1(rid, EOK, fd); 609 568 } 610 569 … … 613 572 // FIXME: check for sanity of the supplied fs, dev and index 614 573 574 if (!vfs_files_init()) { 575 ipc_answer_0(rid, ENOMEM); 576 return; 577 } 578 615 579 /* 616 580 * The interface is open_node(fs, dev, index, oflag). … … 619 583 620 584 lr.triplet.fs_handle = IPC_GET_ARG1(*request); 621 lr.triplet.dev map_handle = IPC_GET_ARG2(*request);585 lr.triplet.dev_handle = IPC_GET_ARG2(*request); 622 586 lr.triplet.index = IPC_GET_ARG3(*request); 623 587 int oflag = IPC_GET_ARG4(*request); … … 628 592 if (rc != EOK) { 629 593 fibril_rwlock_read_unlock(&namespace_rwlock); 630 async_answer_0(rid, rc);594 ipc_answer_0(rid, rc); 631 595 return; 632 596 } … … 640 604 if (node->size) { 641 605 rc = vfs_truncate_internal(node->fs_handle, 642 node->dev map_handle, node->index, 0);606 node->dev_handle, node->index, 0); 643 607 if (rc) { 644 608 fibril_rwlock_write_unlock(&node->contents_rwlock); 645 609 vfs_node_put(node); 646 async_answer_0(rid, rc);610 ipc_answer_0(rid, rc); 647 611 return; 648 612 } … … 656 620 * structure. 657 621 */ 658 int fd = vfs_fd_alloc( (oflag & O_DESC) != 0);622 int fd = vfs_fd_alloc(); 659 623 if (fd < 0) { 660 624 vfs_node_put(node); 661 async_answer_0(rid, fd);625 ipc_answer_0(rid, fd); 662 626 return; 663 627 } … … 676 640 vfs_node_addref(node); 677 641 vfs_node_put(node); 678 vfs_file_put(file);679 642 680 643 /* Success! Return the new file descriptor to the client. */ 681 async_answer_1(rid, EOK, fd);644 ipc_answer_1(rid, EOK, fd); 682 645 } 683 646 … … 689 652 vfs_file_t *file = vfs_file_get(fd); 690 653 if (!file) { 691 async_answer_0(rid, ENOENT);654 ipc_answer_0(rid, ENOENT); 692 655 return; 693 656 } … … 703 666 aid_t msg; 704 667 ipc_call_t answer; 705 msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev map_handle,668 msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle, 706 669 file->node->index, &answer); 707 670 708 671 /* Wait for reply from the FS server. */ 709 sysarg_t rc;672 ipcarg_t rc; 710 673 async_wait_for(msg, &rc); 711 674 712 vfs_release_phone(f ile->node->fs_handle, fs_phone);675 vfs_release_phone(fs_phone); 713 676 fibril_mutex_unlock(&file->lock); 714 715 vfs_file_put(file); 716 async_answer_0(rid, rc); 717 } 718 719 int vfs_close_internal(vfs_file_t *file) 720 { 721 /* 722 * Lock the open file structure so that no other thread can manipulate 723 * the same open file at a time. 724 */ 725 fibril_mutex_lock(&file->lock); 726 727 if (file->refcnt <= 1) { 728 /* Only close the file on the destination FS server 729 if there are no more file descriptors (except the 730 present one) pointing to this file. */ 731 732 int fs_phone = vfs_grab_phone(file->node->fs_handle); 733 734 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 735 aid_t msg; 736 ipc_call_t answer; 737 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, 738 file->node->devmap_handle, file->node->index, &answer); 739 740 /* Wait for reply from the FS server. */ 741 sysarg_t rc; 742 async_wait_for(msg, &rc); 743 744 vfs_release_phone(file->node->fs_handle, fs_phone); 745 fibril_mutex_unlock(&file->lock); 746 747 return IPC_GET_ARG1(answer); 748 } 749 750 fibril_mutex_unlock(&file->lock); 751 return EOK; 677 678 ipc_answer_0(rid, rc); 752 679 } 753 680 … … 759 686 vfs_file_t *file = vfs_file_get(fd); 760 687 if (!file) { 761 async_answer_0(rid, ENOENT); 762 return; 763 } 764 765 int ret = vfs_close_internal(file); 766 if (ret != EOK) 767 async_answer_0(rid, ret); 768 769 vfs_file_put(file); 770 ret = vfs_fd_free(fd); 771 async_answer_0(rid, ret); 688 ipc_answer_0(rid, ENOENT); 689 return; 690 } 691 692 /* 693 * Lock the open file structure so that no other thread can manipulate 694 * the same open file at a time. 695 */ 696 fibril_mutex_lock(&file->lock); 697 int fs_phone = vfs_grab_phone(file->node->fs_handle); 698 699 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 700 aid_t msg; 701 ipc_call_t answer; 702 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle, 703 file->node->index, &answer); 704 705 /* Wait for reply from the FS server. */ 706 ipcarg_t rc; 707 async_wait_for(msg, &rc); 708 709 vfs_release_phone(fs_phone); 710 fibril_mutex_unlock(&file->lock); 711 712 int retval = IPC_GET_ARG1(answer); 713 if (retval != EOK) 714 ipc_answer_0(rid, retval); 715 716 retval = vfs_fd_free(fd); 717 ipc_answer_0(rid, retval); 772 718 } 773 719 774 720 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) 775 721 { 776 vfs_info_t *vi;777 722 778 723 /* … … 791 736 vfs_file_t *file = vfs_file_get(fd); 792 737 if (!file) { 793 async_answer_0(rid, ENOENT); 738 ipc_answer_0(rid, ENOENT); 739 return; 740 } 741 742 /* 743 * Now we need to receive a call with client's 744 * IPC_M_DATA_READ/IPC_M_DATA_WRITE request. 745 */ 746 ipc_callid_t callid; 747 int res; 748 if (read) 749 res = ipc_data_read_receive(&callid, NULL); 750 else 751 res = ipc_data_write_receive(&callid, NULL); 752 if (!res) { 753 ipc_answer_0(callid, EINVAL); 754 ipc_answer_0(rid, EINVAL); 794 755 return; 795 756 } … … 801 762 fibril_mutex_lock(&file->lock); 802 763 803 vi = fs_handle_to_info(file->node->fs_handle);804 assert(vi);805 806 764 /* 807 765 * Lock the file's node so that no other client can read/write to it at 808 * the same time unless the FS supports concurrent reads/writes and its 809 * write implementation does not modify the file size. 810 */ 811 if (read || (vi->concurrent_read_write && vi->write_retains_size)) 766 * the same time. 767 */ 768 if (read) 812 769 fibril_rwlock_read_lock(&file->node->contents_rwlock); 813 770 else … … 823 780 } 824 781 825 int fs_phone = vfs_grab_phone(file->node->fs_handle); 826 827 /* 828 * Make a VFS_READ/VFS_WRITE request at the destination FS server 829 * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 782 int fs_phone = vfs_grab_phone(file->node->fs_handle); 783 784 /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ 785 aid_t msg; 786 ipc_call_t answer; 787 if (!read && file->append) 788 file->pos = file->node->size; 789 msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE, 790 file->node->dev_handle, file->node->index, file->pos, &answer); 791 792 /* 793 * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 830 794 * destination FS server. The call will be routed as if sent by 831 795 * ourselves. Note that call arguments are immutable in this case so we 832 796 * don't have to bother. 833 797 */ 834 sysarg_t rc; 835 ipc_call_t answer; 836 if (read) { 837 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ, 838 file->node->devmap_handle, file->node->index, file->pos, 839 &answer); 840 } else { 841 if (file->append) 842 file->pos = file->node->size; 843 844 rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE, 845 file->node->devmap_handle, file->node->index, file->pos, 846 &answer); 847 } 848 849 vfs_release_phone(file->node->fs_handle, fs_phone); 798 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 799 800 /* Wait for reply from the FS server. */ 801 ipcarg_t rc; 802 async_wait_for(msg, &rc); 803 804 vfs_release_phone(fs_phone); 850 805 851 806 size_t bytes = IPC_GET_ARG1(answer); 852 807 853 808 if (file->node->type == VFS_NODE_DIRECTORY) 854 809 fibril_rwlock_read_unlock(&namespace_rwlock); 855 810 856 811 /* Unlock the VFS node. */ 857 if (read || (vi->concurrent_read_write && vi->write_retains_size))812 if (read) 858 813 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 859 814 else { … … 868 823 file->pos += bytes; 869 824 fibril_mutex_unlock(&file->lock); 870 vfs_file_put(file); 871 825 872 826 /* 873 827 * FS server's reply is the final result of the whole operation we 874 828 * return to the client. 875 829 */ 876 async_answer_1(rid, rc, bytes);830 ipc_answer_1(rid, rc, bytes); 877 831 } 878 832 … … 890 844 { 891 845 int fd = (int) IPC_GET_ARG1(*request); 892 off 64_t off = (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request),893 IPC_GET_ARG3(*request));894 int whence = (int) IPC_GET_ARG4(*request); 895 846 off_t off = (off_t) IPC_GET_ARG2(*request); 847 int whence = (int) IPC_GET_ARG3(*request); 848 849 896 850 /* Lookup the file structure corresponding to the file descriptor. */ 897 851 vfs_file_t *file = vfs_file_get(fd); 898 852 if (!file) { 899 async_answer_0(rid, ENOENT); 900 return; 901 } 902 853 ipc_answer_0(rid, ENOENT); 854 return; 855 } 856 857 off_t newpos; 903 858 fibril_mutex_lock(&file->lock); 904 905 off64_t newoff; 906 switch (whence) { 907 case SEEK_SET: 908 if (off >= 0) { 909 file->pos = (aoff64_t) off; 859 if (whence == SEEK_SET) { 860 file->pos = off; 861 fibril_mutex_unlock(&file->lock); 862 ipc_answer_1(rid, EOK, off); 863 return; 864 } 865 if (whence == SEEK_CUR) { 866 if (file->pos + off < file->pos) { 910 867 fibril_mutex_unlock(&file->lock); 911 vfs_file_put(file); 912 async_answer_1(rid, EOK, off); 868 ipc_answer_0(rid, EOVERFLOW); 913 869 return; 914 870 } 915 break; 916 case SEEK_CUR: 917 if ((off >= 0) && (file->pos + off < file->pos)) { 871 file->pos += off; 872 newpos = file->pos; 873 fibril_mutex_unlock(&file->lock); 874 ipc_answer_1(rid, EOK, newpos); 875 return; 876 } 877 if (whence == SEEK_END) { 878 fibril_rwlock_read_lock(&file->node->contents_rwlock); 879 size_t size = file->node->size; 880 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 881 if (size + off < size) { 918 882 fibril_mutex_unlock(&file->lock); 919 vfs_file_put(file); 920 async_answer_0(rid, EOVERFLOW); 883 ipc_answer_0(rid, EOVERFLOW); 921 884 return; 922 885 } 923 924 if ((off < 0) && (file->pos < (aoff64_t) -off)) { 925 fibril_mutex_unlock(&file->lock); 926 vfs_file_put(file); 927 async_answer_0(rid, EOVERFLOW); 928 return; 929 } 930 931 file->pos += off; 932 newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos; 933 886 newpos = size + off; 934 887 fibril_mutex_unlock(&file->lock); 935 vfs_file_put(file); 936 async_answer_2(rid, EOK, LOWER32(newoff), 937 UPPER32(newoff)); 938 return; 939 case SEEK_END: 940 fibril_rwlock_read_lock(&file->node->contents_rwlock); 941 aoff64_t size = file->node->size; 942 943 if ((off >= 0) && (size + off < size)) { 944 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 945 fibril_mutex_unlock(&file->lock); 946 vfs_file_put(file); 947 async_answer_0(rid, EOVERFLOW); 948 return; 949 } 950 951 if ((off < 0) && (size < (aoff64_t) -off)) { 952 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 953 fibril_mutex_unlock(&file->lock); 954 vfs_file_put(file); 955 async_answer_0(rid, EOVERFLOW); 956 return; 957 } 958 959 file->pos = size + off; 960 newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos; 961 962 fibril_rwlock_read_unlock(&file->node->contents_rwlock); 963 fibril_mutex_unlock(&file->lock); 964 vfs_file_put(file); 965 async_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff)); 966 return; 967 } 968 888 ipc_answer_1(rid, EOK, newpos); 889 return; 890 } 969 891 fibril_mutex_unlock(&file->lock); 970 vfs_file_put(file);971 async_answer_0(rid, EINVAL); 972 } 973 974 int vfs_truncate_internal(fs_handle_t fs_handle, devmap_handle_t devmap_handle,975 fs_index_t index, aoff64_t size)976 { 977 sysarg_t rc;892 ipc_answer_0(rid, EINVAL); 893 } 894 895 int 896 vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle, 897 fs_index_t index, size_t size) 898 { 899 ipcarg_t rc; 978 900 int fs_phone; 979 901 980 902 fs_phone = vfs_grab_phone(fs_handle); 981 rc = async_req_ 4_0(fs_phone, VFS_OUT_TRUNCATE, (sysarg_t) devmap_handle,982 ( sysarg_t) index, LOWER32(size), UPPER32(size));983 vfs_release_phone(fs_ handle, fs_phone);903 rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle, 904 (ipcarg_t)index, (ipcarg_t)size); 905 vfs_release_phone(fs_phone); 984 906 return (int)rc; 985 907 } … … 988 910 { 989 911 int fd = IPC_GET_ARG1(*request); 990 aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request), 991 IPC_GET_ARG3(*request)); 912 size_t size = IPC_GET_ARG2(*request); 992 913 int rc; 993 914 994 915 vfs_file_t *file = vfs_file_get(fd); 995 916 if (!file) { 996 async_answer_0(rid, ENOENT);917 ipc_answer_0(rid, ENOENT); 997 918 return; 998 919 } … … 1001 922 fibril_rwlock_write_lock(&file->node->contents_rwlock); 1002 923 rc = vfs_truncate_internal(file->node->fs_handle, 1003 file->node->dev map_handle, file->node->index, size);924 file->node->dev_handle, file->node->index, size); 1004 925 if (rc == EOK) 1005 926 file->node->size = size; … … 1007 928 1008 929 fibril_mutex_unlock(&file->lock); 1009 vfs_file_put(file); 1010 async_answer_0(rid, (sysarg_t)rc); 930 ipc_answer_0(rid, (ipcarg_t)rc); 1011 931 } 1012 932 … … 1014 934 { 1015 935 int fd = IPC_GET_ARG1(*request); 1016 sysarg_t rc; 936 size_t size = IPC_GET_ARG2(*request); 937 ipcarg_t rc; 1017 938 1018 939 vfs_file_t *file = vfs_file_get(fd); 1019 940 if (!file) { 1020 async_answer_0(rid, ENOENT);941 ipc_answer_0(rid, ENOENT); 1021 942 return; 1022 943 } 1023 944 1024 945 ipc_callid_t callid; 1025 if (!async_data_read_receive(&callid, NULL)) { 1026 vfs_file_put(file); 1027 async_answer_0(callid, EINVAL); 1028 async_answer_0(rid, EINVAL); 946 if (!ipc_data_read_receive(&callid, NULL)) { 947 ipc_answer_0(callid, EINVAL); 948 ipc_answer_0(rid, EINVAL); 1029 949 return; 1030 950 } … … 1035 955 1036 956 aid_t msg; 1037 msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev map_handle,957 msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle, 1038 958 file->node->index, true, NULL); 1039 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);959 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1040 960 async_wait_for(msg, &rc); 1041 vfs_release_phone(f ile->node->fs_handle, fs_phone);961 vfs_release_phone(fs_phone); 1042 962 1043 963 fibril_mutex_unlock(&file->lock); 1044 vfs_file_put(file); 1045 async_answer_0(rid, rc); 964 ipc_answer_0(rid, rc); 1046 965 } 1047 966 1048 967 void vfs_stat(ipc_callid_t rid, ipc_call_t *request) 1049 968 { 1050 char *path; 1051 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1052 if (rc != EOK) { 1053 async_answer_0(rid, rc); 1054 return; 1055 } 1056 969 size_t len; 1057 970 ipc_callid_t callid; 1058 if (!async_data_read_receive(&callid, NULL)) { 971 972 if (!ipc_data_write_receive(&callid, &len)) { 973 ipc_answer_0(callid, EINVAL); 974 ipc_answer_0(rid, EINVAL); 975 return; 976 } 977 char *path = malloc(len + 1); 978 if (!path) { 979 ipc_answer_0(callid, ENOMEM); 980 ipc_answer_0(rid, ENOMEM); 981 return; 982 } 983 int rc; 984 if ((rc = ipc_data_write_finalize(callid, path, len))) { 985 ipc_answer_0(rid, rc); 1059 986 free(path); 1060 async_answer_0(callid, EINVAL); 1061 async_answer_0(rid, EINVAL); 987 return; 988 } 989 path[len] = '\0'; 990 991 if (!ipc_data_read_receive(&callid, NULL)) { 992 free(path); 993 ipc_answer_0(callid, EINVAL); 994 ipc_answer_0(rid, EINVAL); 1062 995 return; 1063 996 } … … 1069 1002 if (rc != EOK) { 1070 1003 fibril_rwlock_read_unlock(&namespace_rwlock); 1071 async_answer_0(callid, rc);1072 async_answer_0(rid, rc);1004 ipc_answer_0(callid, rc); 1005 ipc_answer_0(rid, rc); 1073 1006 return; 1074 1007 } … … 1076 1009 if (!node) { 1077 1010 fibril_rwlock_read_unlock(&namespace_rwlock); 1078 async_answer_0(callid, ENOMEM);1079 async_answer_0(rid, ENOMEM);1011 ipc_answer_0(callid, ENOMEM); 1012 ipc_answer_0(rid, ENOMEM); 1080 1013 return; 1081 1014 } … … 1085 1018 int fs_phone = vfs_grab_phone(node->fs_handle); 1086 1019 aid_t msg; 1087 msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev map_handle,1020 msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle, 1088 1021 node->index, false, NULL); 1089 async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);1090 1091 sysarg_t rv;1022 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 1023 1024 ipcarg_t rv; 1092 1025 async_wait_for(msg, &rv); 1093 vfs_release_phone( node->fs_handle,fs_phone);1094 1095 async_answer_0(rid, rv);1026 vfs_release_phone(fs_phone); 1027 1028 ipc_answer_0(rid, rv); 1096 1029 1097 1030 vfs_node_put(node); … … 1101 1034 { 1102 1035 int mode = IPC_GET_ARG1(*request); 1103 1104 char *path; 1105 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1106 if (rc != EOK) { 1107 async_answer_0(rid, rc); 1108 return; 1109 } 1110 1036 1037 size_t len; 1038 ipc_callid_t callid; 1039 1040 if (!ipc_data_write_receive(&callid, &len)) { 1041 ipc_answer_0(callid, EINVAL); 1042 ipc_answer_0(rid, EINVAL); 1043 return; 1044 } 1045 char *path = malloc(len + 1); 1046 if (!path) { 1047 ipc_answer_0(callid, ENOMEM); 1048 ipc_answer_0(rid, ENOMEM); 1049 return; 1050 } 1051 int rc; 1052 if ((rc = ipc_data_write_finalize(callid, path, len))) { 1053 ipc_answer_0(rid, rc); 1054 free(path); 1055 return; 1056 } 1057 path[len] = '\0'; 1058 1111 1059 /* Ignore mode for now. */ 1112 1060 (void) mode; … … 1117 1065 fibril_rwlock_write_unlock(&namespace_rwlock); 1118 1066 free(path); 1119 async_answer_0(rid, rc);1067 ipc_answer_0(rid, rc); 1120 1068 } 1121 1069 … … 1123 1071 { 1124 1072 int lflag = IPC_GET_ARG1(*request); 1125 1126 char *path; 1127 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1128 if (rc != EOK) { 1129 async_answer_0(rid, rc); 1130 return; 1131 } 1073 1074 size_t len; 1075 ipc_callid_t callid; 1076 1077 if (!ipc_data_write_receive(&callid, &len)) { 1078 ipc_answer_0(callid, EINVAL); 1079 ipc_answer_0(rid, EINVAL); 1080 return; 1081 } 1082 char *path = malloc(len + 1); 1083 if (!path) { 1084 ipc_answer_0(callid, ENOMEM); 1085 ipc_answer_0(rid, ENOMEM); 1086 return; 1087 } 1088 int rc; 1089 if ((rc = ipc_data_write_finalize(callid, path, len))) { 1090 ipc_answer_0(rid, rc); 1091 free(path); 1092 return; 1093 } 1094 path[len] = '\0'; 1132 1095 1133 1096 fibril_rwlock_write_lock(&namespace_rwlock); … … 1138 1101 if (rc != EOK) { 1139 1102 fibril_rwlock_write_unlock(&namespace_rwlock); 1140 async_answer_0(rid, rc);1103 ipc_answer_0(rid, rc); 1141 1104 return; 1142 1105 } … … 1153 1116 fibril_rwlock_write_unlock(&namespace_rwlock); 1154 1117 vfs_node_put(node); 1155 async_answer_0(rid, EOK);1118 ipc_answer_0(rid, EOK); 1156 1119 } 1157 1120 1158 1121 void vfs_rename(ipc_callid_t rid, ipc_call_t *request) 1159 1122 { 1123 size_t olen, nlen; 1124 ipc_callid_t callid; 1125 int rc; 1126 1160 1127 /* Retrieve the old path. */ 1161 char *old; 1162 int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL); 1163 if (rc != EOK) { 1164 async_answer_0(rid, rc); 1165 return; 1166 } 1128 if (!ipc_data_write_receive(&callid, &olen)) { 1129 ipc_answer_0(callid, EINVAL); 1130 ipc_answer_0(rid, EINVAL); 1131 return; 1132 } 1133 char *old = malloc(olen + 1); 1134 if (!old) { 1135 ipc_answer_0(callid, ENOMEM); 1136 ipc_answer_0(rid, ENOMEM); 1137 return; 1138 } 1139 if ((rc = ipc_data_write_finalize(callid, old, olen))) { 1140 ipc_answer_0(rid, rc); 1141 free(old); 1142 return; 1143 } 1144 old[olen] = '\0'; 1167 1145 1168 1146 /* Retrieve the new path. */ 1169 char *new;1170 rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);1171 if (rc != EOK) {1147 if (!ipc_data_write_receive(&callid, &nlen)) { 1148 ipc_answer_0(callid, EINVAL); 1149 ipc_answer_0(rid, EINVAL); 1172 1150 free(old); 1173 async_answer_0(rid, rc); 1174 return; 1175 } 1176 1177 size_t olen; 1178 size_t nlen; 1151 return; 1152 } 1153 char *new = malloc(nlen + 1); 1154 if (!new) { 1155 ipc_answer_0(callid, ENOMEM); 1156 ipc_answer_0(rid, ENOMEM); 1157 free(old); 1158 return; 1159 } 1160 if ((rc = ipc_data_write_finalize(callid, new, nlen))) { 1161 ipc_answer_0(rid, rc); 1162 free(old); 1163 free(new); 1164 return; 1165 } 1166 new[nlen] = '\0'; 1167 1179 1168 char *oldc = canonify(old, &olen); 1180 1169 char *newc = canonify(new, &nlen); 1181 1182 if ((!oldc) || (!newc)) { 1183 async_answer_0(rid, EINVAL); 1170 if (!oldc || !newc) { 1171 ipc_answer_0(rid, EINVAL); 1184 1172 free(old); 1185 1173 free(new); 1186 1174 return; 1187 1175 } 1188 1189 1176 oldc[olen] = '\0'; 1190 1177 newc[nlen] = '\0'; 1191 1192 1178 if ((!str_lcmp(newc, oldc, str_length(oldc))) && 1193 1179 ((newc[str_length(oldc)] == '/') || … … 1200 1186 * - oldc and newc are equal. 1201 1187 */ 1202 async_answer_0(rid, EINVAL);1188 ipc_answer_0(rid, EINVAL); 1203 1189 free(old); 1204 1190 free(new); … … 1210 1196 vfs_lookup_res_t new_par_lr; 1211 1197 fibril_rwlock_write_lock(&namespace_rwlock); 1212 1213 1198 /* Lookup the node belonging to the old file name. */ 1214 1199 rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL); 1215 1200 if (rc != EOK) { 1216 1201 fibril_rwlock_write_unlock(&namespace_rwlock); 1217 async_answer_0(rid, rc);1202 ipc_answer_0(rid, rc); 1218 1203 free(old); 1219 1204 free(new); 1220 1205 return; 1221 1206 } 1222 1223 1207 vfs_node_t *old_node = vfs_node_get(&old_lr); 1224 1208 if (!old_node) { 1225 1209 fibril_rwlock_write_unlock(&namespace_rwlock); 1226 async_answer_0(rid, ENOMEM);1210 ipc_answer_0(rid, ENOMEM); 1227 1211 free(old); 1228 1212 free(new); 1229 1213 return; 1230 1214 } 1231 1232 1215 /* Determine the path to the parent of the node with the new name. */ 1233 1216 char *parentc = str_dup(newc); 1234 1217 if (!parentc) { 1235 1218 fibril_rwlock_write_unlock(&namespace_rwlock); 1236 async_answer_0(rid, rc);1219 ipc_answer_0(rid, rc); 1237 1220 free(old); 1238 1221 free(new); 1239 1222 return; 1240 1223 } 1241 1242 1224 char *lastsl = str_rchr(parentc + 1, '/'); 1243 1225 if (lastsl) … … 1245 1227 else 1246 1228 parentc[1] = '\0'; 1247 1248 1229 /* Lookup parent of the new file name. */ 1249 1230 rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL); … … 1251 1232 if (rc != EOK) { 1252 1233 fibril_rwlock_write_unlock(&namespace_rwlock); 1253 async_answer_0(rid, rc);1234 ipc_answer_0(rid, rc); 1254 1235 free(old); 1255 1236 free(new); 1256 1237 return; 1257 1238 } 1258 1259 1239 /* Check whether linking to the same file system instance. */ 1260 1240 if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) || 1261 (old_node->dev map_handle != new_par_lr.triplet.devmap_handle)) {1241 (old_node->dev_handle != new_par_lr.triplet.dev_handle)) { 1262 1242 fibril_rwlock_write_unlock(&namespace_rwlock); 1263 async_answer_0(rid, EXDEV); /* different file systems */1243 ipc_answer_0(rid, EXDEV); /* different file systems */ 1264 1244 free(old); 1265 1245 free(new); 1266 1246 return; 1267 1247 } 1268 1269 1248 /* Destroy the old link for the new name. */ 1270 1249 vfs_node_t *new_node = NULL; 1271 1250 rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL); 1272 1273 1251 switch (rc) { 1274 1252 case ENOENT: … … 1279 1257 if (!new_node) { 1280 1258 fibril_rwlock_write_unlock(&namespace_rwlock); 1281 async_answer_0(rid, ENOMEM);1259 ipc_answer_0(rid, ENOMEM); 1282 1260 free(old); 1283 1261 free(new); … … 1290 1268 default: 1291 1269 fibril_rwlock_write_unlock(&namespace_rwlock); 1292 async_answer_0(rid, ENOTEMPTY);1270 ipc_answer_0(rid, ENOTEMPTY); 1293 1271 free(old); 1294 1272 free(new); 1295 1273 return; 1296 1274 } 1297 1298 1275 /* Create the new link for the new name. */ 1299 1276 rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index); … … 1302 1279 if (new_node) 1303 1280 vfs_node_put(new_node); 1304 async_answer_0(rid, rc);1281 ipc_answer_0(rid, rc); 1305 1282 free(old); 1306 1283 free(new); 1307 1284 return; 1308 1285 } 1309 1310 1286 fibril_mutex_lock(&nodes_mutex); 1311 1287 old_node->lnkcnt++; 1312 1288 fibril_mutex_unlock(&nodes_mutex); 1313 1314 1289 /* Destroy the link for the old name. */ 1315 1290 rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL); … … 1319 1294 if (new_node) 1320 1295 vfs_node_put(new_node); 1321 async_answer_0(rid, rc);1296 ipc_answer_0(rid, rc); 1322 1297 free(old); 1323 1298 free(new); 1324 1299 return; 1325 1300 } 1326 1327 1301 fibril_mutex_lock(&nodes_mutex); 1328 1302 old_node->lnkcnt--; … … 1330 1304 fibril_rwlock_write_unlock(&namespace_rwlock); 1331 1305 vfs_node_put(old_node); 1332 1333 1306 if (new_node) 1334 1307 vfs_node_put(new_node); 1335 1336 1308 free(old); 1337 1309 free(new); 1338 async_answer_0(rid, EOK); 1339 } 1340 1341 void vfs_dup(ipc_callid_t rid, ipc_call_t *request) 1342 { 1343 int oldfd = IPC_GET_ARG1(*request); 1344 int newfd = IPC_GET_ARG2(*request); 1345 1346 /* If the file descriptors are the same, do nothing. */ 1347 if (oldfd == newfd) { 1348 async_answer_1(rid, EOK, newfd); 1349 return; 1350 } 1351 1352 /* Lookup the file structure corresponding to oldfd. */ 1353 vfs_file_t *oldfile = vfs_file_get(oldfd); 1354 if (!oldfile) { 1355 async_answer_0(rid, EBADF); 1356 return; 1357 } 1358 1359 /* 1360 * Lock the open file structure so that no other thread can manipulate 1361 * the same open file at a time. 1362 */ 1363 fibril_mutex_lock(&oldfile->lock); 1364 1365 /* Lookup an open file structure possibly corresponding to newfd. */ 1366 vfs_file_t *newfile = vfs_file_get(newfd); 1367 if (newfile) { 1368 /* Close the originally opened file. */ 1369 int ret = vfs_close_internal(newfile); 1370 if (ret != EOK) { 1371 fibril_mutex_unlock(&oldfile->lock); 1372 vfs_file_put(oldfile); 1373 vfs_file_put(newfile); 1374 async_answer_0(rid, ret); 1375 return; 1376 } 1377 1378 ret = vfs_fd_free(newfd); 1379 if (ret != EOK) { 1380 fibril_mutex_unlock(&oldfile->lock); 1381 vfs_file_put(oldfile); 1382 vfs_file_put(newfile); 1383 async_answer_0(rid, ret); 1384 return; 1385 } 1386 vfs_file_put(newfile); 1387 } 1388 1389 /* Assign the old file to newfd. */ 1390 int ret = vfs_fd_assign(oldfile, newfd); 1391 fibril_mutex_unlock(&oldfile->lock); 1392 vfs_file_put(oldfile); 1393 1394 if (ret != EOK) 1395 async_answer_0(rid, ret); 1396 else 1397 async_answer_1(rid, EOK, newfd); 1310 ipc_answer_0(rid, EOK); 1398 1311 } 1399 1312
Note:
See TracChangeset
for help on using the changeset viewer.