Changes in uspace/srv/vfs/vfs_ops.c [6a4e972:08232ee] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_ops.c
r6a4e972 r08232ee 92 92 } 93 93 94 rc = vfs_lookup_internal(mp, L_ MP, &mp_res, NULL);94 rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL); 95 95 if (rc != EOK) { 96 96 /* The lookup failed for some reason. */ … … 429 429 } 430 430 431 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)432 {433 int rc;434 char *mp;435 vfs_lookup_res_t mp_res;436 vfs_lookup_res_t mr_res;437 vfs_node_t *mp_node;438 vfs_node_t *mr_node;439 int phone;440 441 /*442 * Receive the mount point path.443 */444 rc = async_data_string_receive(&mp, MAX_PATH_LEN);445 if (rc != EOK)446 ipc_answer_0(rid, rc);447 448 /*449 * Taking the namespace lock will do two things for us. First, it will450 * prevent races with other lookup operations. Second, it will stop new451 * references to already existing VFS nodes and creation of new VFS452 * nodes. This is because new references are added as a result of some453 * lookup operation or at least of some operation which is protected by454 * the namespace lock.455 */456 fibril_rwlock_write_lock(&namespace_rwlock);457 458 /*459 * Lookup the mounted root and instantiate it.460 */461 rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);462 if (rc != EOK) {463 fibril_rwlock_write_unlock(&namespace_rwlock);464 free(mp);465 ipc_answer_0(rid, rc);466 return;467 }468 mr_node = vfs_node_get(&mr_res);469 if (!mr_node) {470 fibril_rwlock_write_unlock(&namespace_rwlock);471 free(mp);472 ipc_answer_0(rid, ENOMEM);473 return;474 }475 476 /*477 * Count the total number of references for the mounted file system. We478 * are expecting at least two. One which we got above and one which we479 * got when the file system was mounted. If we find more, it means that480 * the file system cannot be gracefully unmounted at the moment because481 * someone is working with it.482 */483 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,484 mr_node->dev_handle) != 2) {485 fibril_rwlock_write_unlock(&namespace_rwlock);486 vfs_node_put(mr_node);487 free(mp);488 ipc_answer_0(rid, EBUSY);489 return;490 }491 492 if (str_cmp(mp, "/") == 0) {493 494 /*495 * Unmounting the root file system.496 *497 * In this case, there is no mount point node and we send498 * VFS_OUT_UNMOUNTED directly to the mounted file system.499 */500 501 free(mp);502 phone = vfs_grab_phone(mr_node->fs_handle);503 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,504 mr_node->dev_handle);505 vfs_release_phone(phone);506 if (rc != EOK) {507 fibril_rwlock_write_unlock(&namespace_rwlock);508 vfs_node_put(mr_node);509 ipc_answer_0(rid, rc);510 return;511 }512 rootfs.fs_handle = 0;513 rootfs.dev_handle = 0;514 } else {515 516 /*517 * Unmounting a non-root file system.518 *519 * We have a regular mount point node representing the parent520 * file system, so we delegate the operation to it.521 */522 523 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);524 free(mp);525 if (rc != EOK) {526 fibril_rwlock_write_unlock(&namespace_rwlock);527 vfs_node_put(mr_node);528 ipc_answer_0(rid, rc);529 return;530 }531 vfs_node_t *mp_node = vfs_node_get(&mp_res);532 if (!mp_node) {533 fibril_rwlock_write_unlock(&namespace_rwlock);534 vfs_node_put(mr_node);535 ipc_answer_0(rid, ENOMEM);536 return;537 }538 539 phone = vfs_grab_phone(mp_node->fs_handle);540 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,541 mp_node->index);542 vfs_release_phone(phone);543 if (rc != EOK) {544 fibril_rwlock_write_unlock(&namespace_rwlock);545 vfs_node_put(mp_node);546 vfs_node_put(mr_node);547 ipc_answer_0(rid, rc);548 return;549 }550 551 /* Drop the reference we got above. */552 vfs_node_put(mp_node);553 /* Drop the reference from when the file system was mounted. */554 vfs_node_put(mp_node);555 }556 557 558 /*559 * All went well, the mounted file system was successfully unmounted.560 * The only thing left is to forget the unmounted root VFS node.561 */562 vfs_node_forget(mr_node);563 564 fibril_rwlock_write_unlock(&namespace_rwlock);565 ipc_answer_0(rid, EOK);566 }567 568 431 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 569 432 { … … 591 454 /* 592 455 * Make sure that we are called with exactly one of L_FILE and 593 * L_DIRECTORY. Make sure that the user does not pass L_OPEN, 594 * L_ROOT or L_MP. 456 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 595 457 */ 596 458 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) || 597 459 ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) || 598 ( lflag & (L_OPEN | L_ROOT | L_MP))) {460 ((lflag & L_OPEN) != 0)) { 599 461 ipc_answer_0(rid, EINVAL); 600 462 return;
Note:
See TracChangeset
for help on using the changeset viewer.