Changeset 4636a60 in mainline


Ignore:
Timestamp:
2013-07-30T22:54:10Z (11 years ago)
Author:
Jiri Zarevucky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
06256b0
Parents:
5bcd5b7
Message:

Handle mounts at the server side, instead of in the endpoints.

Location:
uspace
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/vfs/vfs.c

    r5bcd5b7 r4636a60  
    260260        }
    261261       
    262         /* Ask VFS whether it likes fs_name. */
    263         rc = async_req_0_0(exch, VFS_IN_PING);
    264         if (rc != EOK) {
    265                 vfs_exchange_end(exch);
    266                 free(mpa);
    267                 async_wait_for(req, &rc_orig);
    268                
    269                 if (null_id != -1)
    270                         loc_null_destroy(null_id);
    271                
    272                 if (rc_orig == EOK)
    273                         return (int) rc;
    274                 else
    275                         return (int) rc_orig;
    276         }
    277        
    278262        vfs_exchange_end(exch);
    279263        free(mpa);
  • uspace/srv/vfs/vfs_ops.c

    r5bcd5b7 r4636a60  
    7070vfs_node_t *root = NULL;
    7171
    72 #if 0
    73 static int vfs_attach_internal(vfs_node_t *mpoint, vfs_node_t *mountee)
    74 {
    75         assert(mpoint != NULL);
    76         assert(mountee != NULL);
    77        
    78         if (mpoint->mount != NULL) {
    79                 return EBUSY;
    80         }
    81        
    82         if (mpoint->type != VFS_NODE_DIRECTORY) {
    83                 return ENOTDIR;
    84         }
    85        
    86         if (vfs_node_has_children(mpoint)) {
    87                 return ENOTEMPTY;
    88         }
    89        
    90         mpoint->mount = mountee;
    91         vfs_node_addref(mountee);
    92         /* Add reference to make sure the node is not freed. Removed in detach_internal(). */
    93         vfs_node_addref(mpoint);
     72static int vfs_connect_internal(service_id_t service_id, unsigned flags, unsigned instance,
     73        char *options, char *fsname, vfs_node_t **root)
     74{
     75        fs_handle_t fs_handle = 0;
     76       
     77        fibril_mutex_lock(&fs_list_lock);
     78        while (1) {
     79                fs_handle = fs_name_to_handle(instance, fsname, false);
     80               
     81                if (fs_handle != 0 || !(flags & IPC_FLAG_BLOCKING)) {
     82                        break;
     83                }
     84               
     85                fibril_condvar_wait(&fs_list_cv, &fs_list_lock);
     86        }
     87        fibril_mutex_unlock(&fs_list_lock);
     88
     89        if (fs_handle == 0) {
     90                return ENOENT;
     91        }
     92       
     93        /* Tell the mountee that it is being mounted. */
     94        ipc_call_t answer;
     95        async_exch_t *exch = vfs_exchange_grab(fs_handle);
     96        aid_t msg = async_send_1(exch, VFS_OUT_MOUNTED, (sysarg_t) service_id, &answer);
     97        /* Send the mount options */
     98        sysarg_t rc = async_data_write_start(exch, options, str_size(options));
     99        if (rc != EOK) {
     100                async_forget(msg);
     101                vfs_exchange_release(exch);
     102                return rc;
     103        }
     104        async_wait_for(msg, &rc);
     105        vfs_exchange_release(exch);
     106       
     107        if (rc != EOK) {
     108                return rc;
     109        }
     110       
     111        vfs_lookup_res_t res;
     112        res.triplet.fs_handle = fs_handle;
     113        res.triplet.service_id = service_id;
     114        res.triplet.index = (fs_index_t) IPC_GET_ARG1(answer);
     115        res.size = (int64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     116        res.type = VFS_NODE_DIRECTORY;
     117       
     118        /* Add reference to the mounted root. */
     119        *root = vfs_node_get(&res);
     120        assert(*root);
     121                       
    94122        return EOK;
    95123}
    96124
    97 static int vfs_detach_internal(vfs_node_t *mpoint)
    98 {
    99         assert(mpoint != NULL);
    100        
    101         if (mpoint->mount == NULL) {
    102                 return ENOENT;
    103         }
    104         vfs_node_put(mpoint->mount);
    105         mpoint->mount = NULL;
    106         vfs_node_put(mpoint);
    107 }
    108 #endif
    109 
    110 static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id,
    111     fs_handle_t fs_handle, char *mp, char *opts)
    112 {
    113         vfs_lookup_res_t mp_res;
    114         vfs_lookup_res_t mr_res;
    115         vfs_node_t *mp_node = NULL;
    116         vfs_node_t *mr_node;
    117         fs_index_t rindex;
    118         aoff64_t rsize;
    119         async_exch_t *exch;
    120         sysarg_t rc;
    121         aid_t msg;
    122         ipc_call_t answer;
    123        
     125static int vfs_mount_internal(service_id_t service_id, unsigned flags, unsigned instance,
     126        char *opts, char *fs_name, char *mp)
     127{
    124128        /* Resolve the path to the mountpoint. */
    125         fibril_rwlock_write_lock(&namespace_rwlock);
     129       
    126130        if (root == NULL) {
    127131                /* We still don't have the root file system mounted. */
     
    131135                         * being mounted first.
    132136                         */
    133                         fibril_rwlock_write_unlock(&namespace_rwlock);
    134                         async_answer_0(rid, ENOENT);
    135137                        return ENOENT;
    136138                }
    137139               
    138                 /*
    139                  * For this simple, but important case,
    140                  * we are almost done.
    141                  */
    142                        
    143                 /* Tell the mountee that it is being mounted. */
    144                 exch = vfs_exchange_grab(fs_handle);
    145                 msg = async_send_1(exch, VFS_OUT_MOUNTED,
    146                     (sysarg_t) service_id, &answer);
    147                 /* Send the mount options */
    148                 rc = async_data_write_start(exch, (void *)opts,
    149                     str_size(opts));
    150                 vfs_exchange_release(exch);
    151                        
    152                 if (rc != EOK) {
    153                         async_forget(msg);
    154                         fibril_rwlock_write_unlock(&namespace_rwlock);
    155                         async_answer_0(rid, rc);
    156                         return rc;
    157                 }
    158                 async_wait_for(msg, &rc);
    159                        
    160                 if (rc != EOK) {
    161                         fibril_rwlock_write_unlock(&namespace_rwlock);
    162                         async_answer_0(rid, rc);
    163                         return rc;
    164                 }
    165 
    166                 rindex = (fs_index_t) IPC_GET_ARG1(answer);
    167                 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
    168                     IPC_GET_ARG3(answer));
    169                
    170                 mr_res.triplet.fs_handle = fs_handle;
    171                 mr_res.triplet.service_id = service_id;
    172                 mr_res.triplet.index = rindex;
    173                 mr_res.size = rsize;
    174                 mr_res.type = VFS_NODE_DIRECTORY;
    175                        
    176                 /* Add reference to the mounted root. */
    177                 root = vfs_node_get(&mr_res);
    178                 assert(root);
    179                        
    180                 fibril_rwlock_write_unlock(&namespace_rwlock);
    181                 async_answer_0(rid, rc);
    182                 return rc;
     140                return vfs_connect_internal(service_id, flags, instance, opts, fs_name, &root);
    183141        }
    184142       
     
    186144        if (str_cmp(mp, "/") == 0) {
    187145                /* Trying to mount root FS over root FS */
    188                 fibril_rwlock_write_unlock(&namespace_rwlock);
    189                 async_answer_0(rid, EBUSY);
    190146                return EBUSY;
    191147        }
    192148       
    193         rc = vfs_lookup_internal(root, mp, L_DIRECTORY, &mp_res);
     149        vfs_lookup_res_t mp_res;
     150        int rc = vfs_lookup_internal(root, mp, L_DIRECTORY, &mp_res);
    194151        if (rc != EOK) {
    195152                /* The lookup failed. */
    196                 fibril_rwlock_write_unlock(&namespace_rwlock);
    197                 async_answer_0(rid, rc);
    198153                return rc;
    199154        }
    200155       
     156        vfs_node_t *mp_node;
    201157        mp_node = vfs_node_get(&mp_res);
    202158        if (!mp_node) {
    203                 fibril_rwlock_write_unlock(&namespace_rwlock);
    204                 async_answer_0(rid, ENOMEM);
    205159                return ENOMEM;
    206160        }
    207161       
    208         /*
    209          * Now we hold a reference to mp_node.
    210          * It will be dropped upon the corresponding VFS_IN_UNMOUNT.
    211          * This prevents the mount point from being deleted.
    212          */
    213        
    214         /*
    215          * At this point, we have all necessary pieces: file system handle
    216          * and service ID, and we know the mount point VFS node.
    217          */
    218        
    219         async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);
    220         assert(mountee_exch);
    221        
    222         exch = vfs_exchange_grab(mp_res.triplet.fs_handle);
    223         msg = async_send_4(exch, VFS_OUT_MOUNT,
    224             (sysarg_t) mp_res.triplet.service_id,
    225             (sysarg_t) mp_res.triplet.index,
    226             (sysarg_t) fs_handle,
    227             (sysarg_t) service_id, &answer);
    228        
    229         /* Send connection */
    230         rc = async_exchange_clone(exch, mountee_exch);
    231         vfs_exchange_release(mountee_exch);
    232        
    233         if (rc != EOK) {
    234                 vfs_exchange_release(exch);
    235                 async_forget(msg);
    236                
    237                 /* Mount failed, drop reference to mp_node. */
    238                 if (mp_node)
    239                         vfs_node_put(mp_node);
    240                
    241                 async_answer_0(rid, rc);
    242                 fibril_rwlock_write_unlock(&namespace_rwlock);
    243                 return rc;
    244         }
    245        
    246         /* send the mount options */
    247         rc = async_data_write_start(exch, (void *) opts, str_size(opts));
    248         if (rc != EOK) {
    249                 vfs_exchange_release(exch);
    250                 async_forget(msg);
    251                
    252                 /* Mount failed, drop reference to mp_node. */
    253                 if (mp_node)
    254                         vfs_node_put(mp_node);
    255                
    256                 fibril_rwlock_write_unlock(&namespace_rwlock);
    257                 async_answer_0(rid, rc);
    258                 return rc;
    259         }
    260        
    261         /*
    262          * Wait for the answer before releasing the exchange to avoid deadlock
    263          * in case the answer depends on further calls to the same file system.
    264          * Think of a case when mounting a FS on a file_bd backed by a file on
    265          * the same FS.
    266          */
    267         async_wait_for(msg, &rc);
    268         vfs_exchange_release(exch);
    269        
    270         if (rc == EOK) {
    271                 rindex = (fs_index_t) IPC_GET_ARG1(answer);
    272                 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
    273                     IPC_GET_ARG3(answer));
    274                
    275                 mr_res.triplet.fs_handle = fs_handle;
    276                 mr_res.triplet.service_id = service_id;
    277                 mr_res.triplet.index = rindex;
    278                 mr_res.size = rsize;
    279                 mr_res.type = VFS_NODE_DIRECTORY;
    280                
    281                 /* Add reference to the mounted root. */
    282                 mr_node = vfs_node_get(&mr_res);
    283                 assert(mr_node);
    284         } else {
    285                 /* Mount failed, drop reference to mp_node. */
    286                 if (mp_node)
    287                         vfs_node_put(mp_node);
    288         }
    289        
    290         async_answer_0(rid, rc);
    291         fibril_rwlock_write_unlock(&namespace_rwlock);
    292         return rc;
     162        if (mp_node->mount != NULL) {
     163                return EBUSY;
     164        }
     165       
     166        if (mp_node->type != VFS_NODE_DIRECTORY) {
     167                return ENOTDIR;
     168        }
     169       
     170        if (vfs_node_has_children(mp_node)) {
     171                return ENOTEMPTY;
     172        }
     173       
     174        vfs_node_t *mountee;
     175       
     176        rc = vfs_connect_internal(service_id, flags, instance, opts, fs_name, &mountee);
     177        if (rc != EOK) {
     178                vfs_node_put(mp_node);
     179                return ENOMEM;
     180        }
     181       
     182        mp_node->mount = mountee;
     183        /* The two references to nodes are held by the mount so that they cannot be freed.
     184         * They are removed in detach_internal().
     185         */
     186        return EOK;
    293187}
    294188
    295189void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
    296190{
    297         service_id_t service_id;
    298 
    299191        /*
    300192         * We expect the library to do the device-name to device-handle
     
    302194         * in the request.
    303195         */
    304         service_id = (service_id_t) IPC_GET_ARG1(*request);
     196        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*request);
    305197       
    306198        /*
     
    328220            0, NULL);
    329221        if (rc != EOK) {
     222                async_answer_0(rid, rc);
    330223                free(mp);
    331                 async_answer_0(rid, rc);
    332224                return;
    333225        }
     
    341233            FS_NAME_MAXLEN, 0, NULL);
    342234        if (rc != EOK) {
     235                async_answer_0(rid, rc);
    343236                free(mp);
    344237                free(opts);
    345                 async_answer_0(rid, rc);
    346                 return;
    347         }
    348        
    349         /*
    350          * Wait for VFS_IN_PING so that we can return an error if we don't know
    351          * fs_name.
    352          */
    353         ipc_call_t data;
    354         ipc_callid_t callid = async_get_call(&data);
    355         if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
    356                 async_answer_0(callid, ENOTSUP);
    357                 async_answer_0(rid, ENOTSUP);
    358                 free(mp);
    359                 free(opts);
    360                 free(fs_name);
    361                 return;
    362         }
    363 
    364         /*
    365          * Check if we know a file system with the same name as is in fs_name.
    366          * This will also give us its file system handle.
    367          */
    368         fibril_mutex_lock(&fs_list_lock);
    369         fs_handle_t fs_handle;
    370 recheck:
    371         fs_handle = fs_name_to_handle(instance, fs_name, false);
    372         if (!fs_handle) {
    373                 if (flags & IPC_FLAG_BLOCKING) {
    374                         fibril_condvar_wait(&fs_list_cv, &fs_list_lock);
    375                         goto recheck;
    376                 }
    377                
    378                 fibril_mutex_unlock(&fs_list_lock);
    379                 async_answer_0(callid, ENOENT);
    380                 async_answer_0(rid, ENOENT);
    381                 free(mp);
    382                 free(fs_name);
    383                 free(opts);
    384                 return;
    385         }
    386         fibril_mutex_unlock(&fs_list_lock);
    387 
     238                return;
     239        }
     240       
    388241        /* Add the filesystem info to the list of mounted filesystems */
    389242        mtab_ent_t *mtab_ent = malloc(sizeof(mtab_ent_t));
    390243        if (!mtab_ent) {
    391                 async_answer_0(callid, ENOMEM);
    392244                async_answer_0(rid, ENOMEM);
    393245                free(mp);
     
    396248                return;
    397249        }
    398 
    399         /* Do the mount */
    400         rc = vfs_mount_internal(rid, service_id, fs_handle, mp, opts);
    401         if (rc != EOK) {
    402                 async_answer_0(callid, ENOTSUP);
    403                 async_answer_0(rid, ENOTSUP);
    404                 free(mtab_ent);
    405                 free(mp);
    406                 free(opts);
    407                 free(fs_name);
    408                 return;
    409         }
     250       
     251        /* Mount the filesystem. */
     252        fibril_rwlock_write_lock(&namespace_rwlock);
     253        rc = vfs_mount_internal(service_id, flags, instance, opts, fs_name, mp);
     254        fibril_rwlock_write_unlock(&namespace_rwlock);
    410255
    411256        /* Add the filesystem info to the list of mounted filesystems */
    412 
    413         str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp);
    414         str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name);
    415         str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts);
    416         mtab_ent->instance = instance;
    417         mtab_ent->service_id = service_id;
    418 
    419         link_initialize(&mtab_ent->link);
    420 
    421         fibril_mutex_lock(&mtab_list_lock);
    422         list_append(&mtab_ent->link, &mtab_list);
    423         mtab_size++;
    424         fibril_mutex_unlock(&mtab_list_lock);
     257        if (rc == EOK) {
     258                str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp);
     259                str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name);
     260                str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts);
     261                mtab_ent->instance = instance;
     262                mtab_ent->service_id = service_id;
     263
     264                link_initialize(&mtab_ent->link);
     265
     266                fibril_mutex_lock(&mtab_list_lock);
     267                list_append(&mtab_ent->link, &mtab_list);
     268                mtab_size++;
     269                fibril_mutex_unlock(&mtab_list_lock);
     270        }
     271       
     272        async_answer_0(rid, rc);
    425273
    426274        free(mp);
    427275        free(fs_name);
    428276        free(opts);
    429 
    430         /* Acknowledge that we know fs_name. */
    431         async_answer_0(callid, EOK);
    432277}
    433278
    434279void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    435280{
    436         int rc;
     281        /*
     282         * Receive the mount point path.
     283         */
    437284        char *mp;
    438         vfs_lookup_res_t mp_res;
    439         vfs_lookup_res_t mr_res;
    440         vfs_node_t *mr_node;
    441         async_exch_t *exch;
    442        
    443         /*
    444          * Receive the mount point path.
    445          */
    446         rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     285        int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    447286            0, NULL);
    448287        if (rc != EOK)
     
    458297         */
    459298        fibril_rwlock_write_lock(&namespace_rwlock);
    460        
    461         /*
    462          * Lookup the mounted root and instantiate it.
    463          */
    464         rc = vfs_lookup_internal(root, mp, 0, &mr_res);
    465         if (rc != EOK) {
    466                 fibril_rwlock_write_unlock(&namespace_rwlock);
     299               
     300        if (str_cmp(mp, "/") == 0) {
    467301                free(mp);
    468                 async_answer_0(rid, rc);
    469                 return;
    470         }
    471         mr_node = vfs_node_get(&mr_res);
    472         if (!mr_node) {
    473                 fibril_rwlock_write_unlock(&namespace_rwlock);
    474                 free(mp);
    475                 async_answer_0(rid, ENOMEM);
    476                 return;
    477         }
    478        
    479         /*
    480          * Count the total number of references for the mounted file system. We
    481          * are expecting at least two. One which we got above and one which we
    482          * got when the file system was mounted. If we find more, it means that
    483          * the file system cannot be gracefully unmounted at the moment because
    484          * someone is working with it.
    485          */
    486         if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
    487             mr_node->service_id) != 2) {
    488                 fibril_rwlock_write_unlock(&namespace_rwlock);
    489                 vfs_node_put(mr_node);
    490                 free(mp);
    491                 async_answer_0(rid, EBUSY);
    492                 return;
    493         }
    494        
    495         if (str_cmp(mp, "/") == 0) {
    496302               
    497303                /*
     
    502308                 */
    503309               
    504                 exch = vfs_exchange_grab(mr_node->fs_handle);
    505                 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,
    506                     mr_node->service_id);
     310                if (!root) {
     311                        fibril_rwlock_write_unlock(&namespace_rwlock);
     312                        async_answer_0(rid, ENOENT);
     313                        return;
     314                }
     315               
     316                /*
     317                 * Count the total number of references for the mounted file system. We
     318                 * are expecting at least one, which we got when the file system was mounted.
     319                 * If we find more, it means that
     320                 * the file system cannot be gracefully unmounted at the moment because
     321                 * someone is working with it.
     322                 */
     323                if (vfs_nodes_refcount_sum_get(root->fs_handle, root->service_id) != 1) {
     324                        fibril_rwlock_write_unlock(&namespace_rwlock);
     325                        async_answer_0(rid, EBUSY);
     326                        return;
     327                }
     328               
     329                async_exch_t *exch = vfs_exchange_grab(root->fs_handle);
     330                rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, root->service_id);
    507331                vfs_exchange_release(exch);
    508332               
    509                 if (rc != EOK) {
    510                         fibril_rwlock_write_unlock(&namespace_rwlock);
    511                         free(mp);
    512                         vfs_node_put(mr_node);
    513                         async_answer_0(rid, rc);
    514                         return;
    515                 }
    516                
    517                 root = NULL;
    518         } else {
    519                
    520                 /*
    521                  * Unmounting a non-root file system.
    522                  *
    523                  * We have a regular mount point node representing the parent
    524                  * file system, so we delegate the operation to it.
    525                  */
    526                
    527                 rc = vfs_lookup_internal(root, mp, L_MP, &mp_res);
    528                 if (rc != EOK) {
    529                         fibril_rwlock_write_unlock(&namespace_rwlock);
    530                         free(mp);
    531                         vfs_node_put(mr_node);
    532                         async_answer_0(rid, rc);
    533                         return;
    534                 }
    535                
    536                 vfs_node_t *mp_node = vfs_node_get(&mp_res);
    537                 if (!mp_node) {
    538                         fibril_rwlock_write_unlock(&namespace_rwlock);
    539                         free(mp);
    540                         vfs_node_put(mr_node);
    541                         async_answer_0(rid, ENOMEM);
    542                         return;
    543                 }
    544                
    545                 exch = vfs_exchange_grab(mp_node->fs_handle);
    546                 rc = async_req_2_0(exch, VFS_OUT_UNMOUNT,
    547                     mp_node->service_id, mp_node->index);
    548                 vfs_exchange_release(exch);
    549                
    550                 if (rc != EOK) {
    551                         fibril_rwlock_write_unlock(&namespace_rwlock);
    552                         free(mp);
    553                         vfs_node_put(mp_node);
    554                         vfs_node_put(mr_node);
    555                         async_answer_0(rid, rc);
    556                         return;
    557                 }
    558                
    559                 /* Drop the reference we got above. */
     333                fibril_rwlock_write_unlock(&namespace_rwlock);
     334                if (rc == EOK) {
     335                        vfs_node_forget(root);
     336                        root = NULL;
     337                }
     338                async_answer_0(rid, rc);
     339                return;
     340        }
     341       
     342        /*
     343         * Lookup the mounted root and instantiate it.
     344         */
     345        vfs_lookup_res_t mp_res;
     346        rc = vfs_lookup_internal(root, mp, L_MP, &mp_res);
     347        if (rc != EOK) {
     348                fibril_rwlock_write_unlock(&namespace_rwlock);
     349                free(mp);
     350                async_answer_0(rid, rc);
     351                return;
     352        }
     353        vfs_node_t *mp_node = vfs_node_get(&mp_res);
     354        if (!mp_node) {
     355                fibril_rwlock_write_unlock(&namespace_rwlock);
     356                free(mp);
     357                async_answer_0(rid, ENOMEM);
     358                return;
     359        }
     360       
     361        if (mp_node->mount == NULL) {
     362                fibril_rwlock_write_unlock(&namespace_rwlock);
    560363                vfs_node_put(mp_node);
    561                 /* Drop the reference from when the file system was mounted. */
     364                free(mp);
     365                async_answer_0(rid, ENOENT);
     366                return;
     367        }
     368       
     369        /*
     370         * Count the total number of references for the mounted file system. We
     371         * are expecting at least one, which we got when the file system was mounted.
     372         * If we find more, it means that
     373         * the file system cannot be gracefully unmounted at the moment because
     374         * someone is working with it.
     375         */
     376        if (vfs_nodes_refcount_sum_get(mp_node->mount->fs_handle, mp_node->mount->service_id) != 1) {
     377                fibril_rwlock_write_unlock(&namespace_rwlock);
    562378                vfs_node_put(mp_node);
    563         }
    564        
    565         /*
    566          * All went well, the mounted file system was successfully unmounted.
    567          * The only thing left is to forget the unmounted root VFS node.
    568          */
    569         vfs_node_forget(mr_node);
     379                free(mp);
     380                async_answer_0(rid, EBUSY);
     381                return;
     382        }
     383       
     384        /* Unmount the filesystem. */
     385        async_exch_t *exch = vfs_exchange_grab(mp_node->mount->fs_handle);
     386        rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, mp_node->mount->service_id);
     387        vfs_exchange_release(exch);
     388       
     389        vfs_node_forget(mp_node->mount);
     390        mp_node->mount = NULL;
     391       
     392        vfs_node_put(mp_node);
    570393        fibril_rwlock_write_unlock(&namespace_rwlock);
    571 
     394       
    572395        fibril_mutex_lock(&mtab_list_lock);
    573 
    574396        int found = 0;
    575 
    576397        list_foreach(mtab_list, cur) {
    577                 mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
    578                     link);
     398                mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t, link);
    579399
    580400                if (str_cmp(mtab_ent->mp, mp) == 0) {
     
    589409        fibril_mutex_unlock(&mtab_list_lock);
    590410
    591         free(mp);
    592 
     411        free(mp);       
     412       
    593413        async_answer_0(rid, EOK);
     414        return;
    594415}
    595416
Note: See TracChangeset for help on using the changeset viewer.