Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs_ops.c

    r6a4e972 r1e4cada  
    9292                }
    9393               
    94                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     94                rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
    9595                if (rc != EOK) {
    9696                        /* The lookup failed for some reason. */
     
    429429}
    430430
    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 will
    450          * prevent races with other lookup operations. Second, it will stop new
    451          * references to already existing VFS nodes and creation of new VFS
    452          * nodes. This is because new references are added as a result of some
    453          * lookup operation or at least of some operation which is protected by
    454          * 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. We
    478          * are expecting at least two. One which we got above and one which we
    479          * got when the file system was mounted. If we find more, it means that
    480          * the file system cannot be gracefully unmounted at the moment because
    481          * 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 send
    498                  * 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 parent
    520                  * 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 
    568431void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    569432{
     
    591454        /*
    592455         * 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.
    595457         */
    596458        if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
    597459            ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
    598             (lflag & (L_OPEN | L_ROOT | L_MP))) {
     460            ((lflag & L_OPEN) != 0)) {
    599461                ipc_answer_0(rid, EINVAL);
    600462                return;
     
    1038900                }
    1039901                newpos = size + off;
    1040                 file->pos = newpos;
    1041902                fibril_mutex_unlock(&file->lock);
    1042903                ipc_answer_1(rid, EOK, newpos);
Note: See TracChangeset for help on using the changeset viewer.