Ignore:
File:
1 edited

Legend:

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

    rccca251 re6da6d5  
    5252#include <assert.h>
    5353#include <vfs/canonify.h>
     54#include <vfs/vfs_mtab.h>
     55
     56FIBRIL_MUTEX_INITIALIZE(mtab_list_lock);
     57LIST_INITIALIZE(mtab_list);
     58static size_t mtab_size = 0;
    5459
    5560/* Forward declarations of static functions. */
    56 static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t,
     61static int vfs_truncate_internal(fs_handle_t, service_id_t, fs_index_t,
    5762    aoff64_t);
    5863
     
    6570vfs_pair_t rootfs = {
    6671        .fs_handle = 0,
    67         .devmap_handle = 0
     72        .service_id = 0
    6873};
    6974
    70 static void vfs_mount_internal(ipc_callid_t rid, devmap_handle_t devmap_handle,
     75static int vfs_mount_internal(ipc_callid_t rid, service_id_t service_id,
    7176    fs_handle_t fs_handle, char *mp, char *opts)
    7277{
     
    7681        vfs_node_t *mr_node;
    7782        fs_index_t rindex;
    78         size_t rsize;
     83        aoff64_t rsize;
    7984        unsigned rlnkcnt;
     85        async_exch_t *exch;
    8086        sysarg_t rc;
    81         int phone;
    8287        aid_t msg;
    8388        ipc_call_t answer;
     
    9196                        fibril_rwlock_write_unlock(&namespace_rwlock);
    9297                        async_answer_0(rid, EBUSY);
    93                         return;
     98                        return EBUSY;
    9499                }
    95100               
     
    99104                        fibril_rwlock_write_unlock(&namespace_rwlock);
    100105                        async_answer_0(rid, rc);
    101                         return;
     106                        return rc;
    102107                }
    103108               
     
    106111                        fibril_rwlock_write_unlock(&namespace_rwlock);
    107112                        async_answer_0(rid, ENOMEM);
    108                         return;
     113                        return ENOMEM;
    109114                }
    110115               
     
    123128                       
    124129                        /* Tell the mountee that it is being mounted. */
    125                         phone = vfs_grab_phone(fs_handle);
    126                         msg = async_send_1(phone, VFS_OUT_MOUNTED,
    127                             (sysarg_t) devmap_handle, &answer);
    128                         /* send the mount options */
    129                         rc = async_data_write_start(phone, (void *)opts,
     130                        exch = vfs_exchange_grab(fs_handle);
     131                        msg = async_send_1(exch, VFS_OUT_MOUNTED,
     132                            (sysarg_t) service_id, &answer);
     133                        /* Send the mount options */
     134                        rc = async_data_write_start(exch, (void *)opts,
    130135                            str_size(opts));
     136                        vfs_exchange_release(exch);
     137                       
    131138                        if (rc != EOK) {
    132139                                async_wait_for(msg, NULL);
    133                                 vfs_release_phone(fs_handle, phone);
    134140                                fibril_rwlock_write_unlock(&namespace_rwlock);
    135141                                async_answer_0(rid, rc);
    136                                 return;
     142                                return rc;
    137143                        }
    138144                        async_wait_for(msg, &rc);
    139                         vfs_release_phone(fs_handle, phone);
    140145                       
    141146                        if (rc != EOK) {
    142147                                fibril_rwlock_write_unlock(&namespace_rwlock);
    143148                                async_answer_0(rid, rc);
    144                                 return;
     149                                return rc;
    145150                        }
    146151
    147152                        rindex = (fs_index_t) IPC_GET_ARG1(answer);
    148                         rsize = (size_t) IPC_GET_ARG2(answer);
    149                         rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
     153                        rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
     154                            IPC_GET_ARG3(answer));
     155                        rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
    150156                       
    151157                        mr_res.triplet.fs_handle = fs_handle;
    152                         mr_res.triplet.devmap_handle = devmap_handle;
     158                        mr_res.triplet.service_id = service_id;
    153159                        mr_res.triplet.index = rindex;
    154160                        mr_res.size = rsize;
     
    157163                       
    158164                        rootfs.fs_handle = fs_handle;
    159                         rootfs.devmap_handle = devmap_handle;
     165                        rootfs.service_id = service_id;
    160166                       
    161167                        /* Add reference to the mounted root. */
     
    165171                        fibril_rwlock_write_unlock(&namespace_rwlock);
    166172                        async_answer_0(rid, rc);
    167                         return;
     173                        return rc;
    168174                } else {
    169175                        /*
     
    173179                        fibril_rwlock_write_unlock(&namespace_rwlock);
    174180                        async_answer_0(rid, ENOENT);
    175                         return;
    176                 }
    177         }
    178        
    179         /*
    180          * At this point, we have all necessary pieces: file system and device
    181          * handles, and we know the mount point VFS node.
    182          */
    183        
    184         int mountee_phone = vfs_grab_phone(fs_handle);
    185         assert(mountee_phone >= 0);
    186 
    187         phone = vfs_grab_phone(mp_res.triplet.fs_handle);
    188         msg = async_send_4(phone, VFS_OUT_MOUNT,
    189             (sysarg_t) mp_res.triplet.devmap_handle,
     181                        return ENOENT;
     182                }
     183        }
     184       
     185        /*
     186         * At this point, we have all necessary pieces: file system handle
     187         * and service ID, and we know the mount point VFS node.
     188         */
     189       
     190        async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);
     191        assert(mountee_exch);
     192       
     193        exch = vfs_exchange_grab(mp_res.triplet.fs_handle);
     194        msg = async_send_4(exch, VFS_OUT_MOUNT,
     195            (sysarg_t) mp_res.triplet.service_id,
    190196            (sysarg_t) mp_res.triplet.index,
    191197            (sysarg_t) fs_handle,
    192             (sysarg_t) devmap_handle, &answer);
    193        
    194         /* send connection */
    195         rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
    196         if (rc != EOK) {
     198            (sysarg_t) service_id, &answer);
     199       
     200        /* Send connection */
     201        rc = async_exchange_clone(exch, mountee_exch);
     202        vfs_exchange_release(mountee_exch);
     203       
     204        if (rc != EOK) {
     205                vfs_exchange_release(exch);
    197206                async_wait_for(msg, NULL);
    198                 vfs_release_phone(fs_handle, mountee_phone);
    199                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     207               
    200208                /* Mount failed, drop reference to mp_node. */
    201209                if (mp_node)
    202210                        vfs_node_put(mp_node);
     211               
    203212                async_answer_0(rid, rc);
    204213                fibril_rwlock_write_unlock(&namespace_rwlock);
    205                 return;
    206         }
    207 
    208         vfs_release_phone(fs_handle, mountee_phone);
     214                return rc;
     215        }
    209216       
    210217        /* send the mount options */
    211         rc = async_data_write_start(phone, (void *)opts, str_size(opts));
    212         if (rc != EOK) {
     218        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     219        if (rc != EOK) {
     220                vfs_exchange_release(exch);
    213221                async_wait_for(msg, NULL);
    214                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     222               
    215223                /* Mount failed, drop reference to mp_node. */
    216224                if (mp_node)
    217225                        vfs_node_put(mp_node);
     226               
    218227                fibril_rwlock_write_unlock(&namespace_rwlock);
    219228                async_answer_0(rid, rc);
    220                 return;
    221         }
     229                return rc;
     230        }
     231       
     232        /*
     233         * Wait for the answer before releasing the exchange to avoid deadlock
     234         * in case the answer depends on further calls to the same file system.
     235         * Think of a case when mounting a FS on a file_bd backed by a file on
     236         * the same FS.
     237         */
    222238        async_wait_for(msg, &rc);
    223         vfs_release_phone(mp_res.triplet.fs_handle, phone);
     239        vfs_exchange_release(exch);
    224240       
    225241        if (rc == EOK) {
    226242                rindex = (fs_index_t) IPC_GET_ARG1(answer);
    227                 rsize = (size_t) IPC_GET_ARG2(answer);
    228                 rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
    229        
     243                rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
     244                    IPC_GET_ARG3(answer));
     245                rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
     246               
    230247                mr_res.triplet.fs_handle = fs_handle;
    231                 mr_res.triplet.devmap_handle = devmap_handle;
     248                mr_res.triplet.service_id = service_id;
    232249                mr_res.triplet.index = rindex;
    233250                mr_res.size = rsize;
    234251                mr_res.lnkcnt = rlnkcnt;
    235252                mr_res.type = VFS_NODE_DIRECTORY;
    236        
     253               
    237254                /* Add reference to the mounted root. */
    238255                mr_node = vfs_node_get(&mr_res);
     
    243260                        vfs_node_put(mp_node);
    244261        }
    245 
     262       
    246263        async_answer_0(rid, rc);
    247264        fibril_rwlock_write_unlock(&namespace_rwlock);
     265        return rc;
    248266}
    249267
    250268void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
    251269{
    252         devmap_handle_t devmap_handle;
     270        service_id_t service_id;
    253271
    254272        /*
     
    257275         * in the request.
    258276         */
    259         devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     277        service_id = (service_id_t) IPC_GET_ARG1(*request);
    260278       
    261279        /*
     
    265283       
    266284        /*
    267          * For now, don't make use of ARG3, but it can be used to
    268          * carry mount options in the future.
    269          */
    270        
     285         * Instance number is passed as ARG3.
     286         */
     287        unsigned int instance = IPC_GET_ARG3(*request);
     288
    271289        /* We want the client to send us the mount point. */
    272290        char *mp;
     
    303321       
    304322        /*
    305          * Wait for IPC_M_PING so that we can return an error if we don't know
     323         * Wait for VFS_IN_PING so that we can return an error if we don't know
    306324         * fs_name.
    307325         */
    308326        ipc_call_t data;
    309327        ipc_callid_t callid = async_get_call(&data);
    310         if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
     328        if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
    311329                async_answer_0(callid, ENOTSUP);
    312330                async_answer_0(rid, ENOTSUP);
     
    321339         * This will also give us its file system handle.
    322340         */
    323         fibril_mutex_lock(&fs_head_lock);
     341        fibril_mutex_lock(&fs_list_lock);
    324342        fs_handle_t fs_handle;
    325343recheck:
    326         fs_handle = fs_name_to_handle(fs_name, false);
     344        fs_handle = fs_name_to_handle(instance, fs_name, false);
    327345        if (!fs_handle) {
    328346                if (flags & IPC_FLAG_BLOCKING) {
    329                         fibril_condvar_wait(&fs_head_cv, &fs_head_lock);
     347                        fibril_condvar_wait(&fs_list_cv, &fs_list_lock);
    330348                        goto recheck;
    331349                }
    332350               
    333                 fibril_mutex_unlock(&fs_head_lock);
     351                fibril_mutex_unlock(&fs_list_lock);
    334352                async_answer_0(callid, ENOENT);
    335353                async_answer_0(rid, ENOENT);
     
    339357                return;
    340358        }
    341         fibril_mutex_unlock(&fs_head_lock);
    342        
    343         /* Acknowledge that we know fs_name. */
    344         async_answer_0(callid, EOK);
    345        
     359        fibril_mutex_unlock(&fs_list_lock);
     360
     361        /* Add the filesystem info to the list of mounted filesystems */
     362        mtab_ent_t *mtab_ent = malloc(sizeof(mtab_ent_t));
     363        if (!mtab_ent) {
     364                async_answer_0(callid, ENOMEM);
     365                async_answer_0(rid, ENOMEM);
     366                free(mp);
     367                free(fs_name);
     368                free(opts);
     369                return;
     370        }
     371
    346372        /* Do the mount */
    347         vfs_mount_internal(rid, devmap_handle, fs_handle, mp, opts);
     373        rc = vfs_mount_internal(rid, service_id, fs_handle, mp, opts);
     374        if (rc != EOK) {
     375                async_answer_0(callid, ENOTSUP);
     376                async_answer_0(rid, ENOTSUP);
     377                free(mtab_ent);
     378                free(mp);
     379                free(opts);
     380                free(fs_name);
     381                return;
     382        }
     383
     384        /* Add the filesystem info to the list of mounted filesystems */
     385
     386        str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp);
     387        str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name);
     388        str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts);
     389        mtab_ent->instance = instance;
     390        mtab_ent->service_id = service_id;
     391
     392        link_initialize(&mtab_ent->link);
     393
     394        fibril_mutex_lock(&mtab_list_lock);
     395        list_append(&mtab_ent->link, &mtab_list);
     396        mtab_size++;
     397        fibril_mutex_unlock(&mtab_list_lock);
     398
    348399        free(mp);
    349400        free(fs_name);
    350401        free(opts);
     402
     403        /* Acknowledge that we know fs_name. */
     404        async_answer_0(callid, EOK);
    351405}
    352406
     
    358412        vfs_lookup_res_t mr_res;
    359413        vfs_node_t *mr_node;
    360         int phone;
    361 
     414        async_exch_t *exch;
     415       
    362416        /*
    363417         * Receive the mount point path.
     
    367421        if (rc != EOK)
    368422                async_answer_0(rid, rc);
    369 
     423       
    370424        /*
    371425         * Taking the namespace lock will do two things for us. First, it will
     
    395449                return;
    396450        }
    397 
     451       
    398452        /*
    399453         * Count the total number of references for the mounted file system. We
     
    404458         */
    405459        if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
    406             mr_node->devmap_handle) != 2) {
     460            mr_node->service_id) != 2) {
    407461                fibril_rwlock_write_unlock(&namespace_rwlock);
    408462                vfs_node_put(mr_node);
     
    411465                return;
    412466        }
    413 
     467       
    414468        if (str_cmp(mp, "/") == 0) {
    415 
     469               
    416470                /*
    417471                 * Unmounting the root file system.
     
    420474                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
    421475                 */
    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);
     476               
     477                exch = vfs_exchange_grab(mr_node->fs_handle);
     478                rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,
     479                    mr_node->service_id);
     480                vfs_exchange_release(exch);
     481               
    428482                if (rc != EOK) {
    429483                        fibril_rwlock_write_unlock(&namespace_rwlock);
     484                        free(mp);
    430485                        vfs_node_put(mr_node);
    431486                        async_answer_0(rid, rc);
    432487                        return;
    433488                }
     489               
    434490                rootfs.fs_handle = 0;
    435                 rootfs.devmap_handle = 0;
     491                rootfs.service_id = 0;
    436492        } else {
    437 
     493               
    438494                /*
    439495                 * Unmounting a non-root file system.
     
    442498                 * file system, so we delegate the operation to it.
    443499                 */
    444 
     500               
    445501                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    446                 free(mp);
    447502                if (rc != EOK) {
    448503                        fibril_rwlock_write_unlock(&namespace_rwlock);
     504                        free(mp);
    449505                        vfs_node_put(mr_node);
    450506                        async_answer_0(rid, rc);
    451507                        return;
    452508                }
     509               
    453510                vfs_node_t *mp_node = vfs_node_get(&mp_res);
    454511                if (!mp_node) {
    455512                        fibril_rwlock_write_unlock(&namespace_rwlock);
     513                        free(mp);
    456514                        vfs_node_put(mr_node);
    457515                        async_answer_0(rid, ENOMEM);
    458516                        return;
    459517                }
    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);
     518               
     519                exch = vfs_exchange_grab(mp_node->fs_handle);
     520                rc = async_req_2_0(exch, VFS_OUT_UNMOUNT,
     521                    mp_node->service_id, mp_node->index);
     522                vfs_exchange_release(exch);
     523               
    465524                if (rc != EOK) {
    466525                        fibril_rwlock_write_unlock(&namespace_rwlock);
     526                        free(mp);
    467527                        vfs_node_put(mp_node);
    468528                        vfs_node_put(mr_node);
     
    470530                        return;
    471531                }
    472 
     532               
    473533                /* Drop the reference we got above. */
    474534                vfs_node_put(mp_node);
     
    476536                vfs_node_put(mp_node);
    477537        }
    478 
    479 
     538       
    480539        /*
    481540         * All went well, the mounted file system was successfully unmounted.
     
    483542         */
    484543        vfs_node_forget(mr_node);
    485 
    486544        fibril_rwlock_write_unlock(&namespace_rwlock);
     545
     546        fibril_mutex_lock(&mtab_list_lock);
     547
     548        int found = 0;
     549
     550        list_foreach(mtab_list, cur) {
     551                mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
     552                    link);
     553
     554                if (str_cmp(mtab_ent->mp, mp) == 0) {
     555                        list_remove(&mtab_ent->link);
     556                        mtab_size--;
     557                        free(mtab_ent);
     558                        found = 1;
     559                        break;
     560                }
     561        }
     562        assert(found);
     563        fibril_mutex_unlock(&mtab_list_lock);
     564
     565        free(mp);
     566
    487567        async_answer_0(rid, EOK);
    488568}
     
    566646                if (node->size) {
    567647                        rc = vfs_truncate_internal(node->fs_handle,
    568                             node->devmap_handle, node->index, 0);
     648                            node->service_id, node->index, 0);
    569649                        if (rc) {
    570650                                fibril_rwlock_write_unlock(&node->contents_rwlock);
     
    609689}
    610690
    611 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    612 {
    613         // FIXME: check for sanity of the supplied fs, dev and index
    614        
    615         /*
    616          * The interface is open_node(fs, dev, index, oflag).
    617          */
    618         vfs_lookup_res_t lr;
    619        
    620         lr.triplet.fs_handle = IPC_GET_ARG1(*request);
    621         lr.triplet.devmap_handle = IPC_GET_ARG2(*request);
    622         lr.triplet.index = IPC_GET_ARG3(*request);
    623         int oflag = IPC_GET_ARG4(*request);
    624        
    625         fibril_rwlock_read_lock(&namespace_rwlock);
    626        
    627         int rc = vfs_open_node_internal(&lr);
    628         if (rc != EOK) {
    629                 fibril_rwlock_read_unlock(&namespace_rwlock);
    630                 async_answer_0(rid, rc);
    631                 return;
    632         }
    633        
    634         vfs_node_t *node = vfs_node_get(&lr);
    635         fibril_rwlock_read_unlock(&namespace_rwlock);
    636        
    637         /* Truncate the file if requested and if necessary. */
    638         if (oflag & O_TRUNC) {
    639                 fibril_rwlock_write_lock(&node->contents_rwlock);
    640                 if (node->size) {
    641                         rc = vfs_truncate_internal(node->fs_handle,
    642                             node->devmap_handle, node->index, 0);
    643                         if (rc) {
    644                                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    645                                 vfs_node_put(node);
    646                                 async_answer_0(rid, rc);
    647                                 return;
    648                         }
    649                         node->size = 0;
    650                 }
    651                 fibril_rwlock_write_unlock(&node->contents_rwlock);
    652         }
    653        
    654         /*
    655          * Get ourselves a file descriptor and the corresponding vfs_file_t
    656          * structure.
    657          */
    658         int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
    659         if (fd < 0) {
    660                 vfs_node_put(node);
    661                 async_answer_0(rid, fd);
    662                 return;
    663         }
    664         vfs_file_t *file = vfs_file_get(fd);
    665         file->node = node;
    666         if (oflag & O_APPEND)
    667                 file->append = true;
    668        
    669         /*
    670          * The following increase in reference count is for the fact that the
    671          * file is being opened and that a file structure is pointing to it.
    672          * It is necessary so that the file will not disappear when
    673          * vfs_node_put() is called. The reference will be dropped by the
    674          * respective VFS_IN_CLOSE.
    675          */
    676         vfs_node_addref(node);
    677         vfs_node_put(node);
    678         vfs_file_put(file);
    679        
    680         /* Success! Return the new file descriptor to the client. */
    681         async_answer_1(rid, EOK, fd);
    682 }
    683 
    684691void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
    685692{
     
    698705         */
    699706        fibril_mutex_lock(&file->lock);
    700         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     707        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    701708       
    702709        /* Make a VFS_OUT_SYMC request at the destination FS server. */
    703710        aid_t msg;
    704711        ipc_call_t answer;
    705         msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle,
     712        msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->service_id,
    706713            file->node->index, &answer);
    707 
     714       
     715        vfs_exchange_release(fs_exch);
     716       
    708717        /* Wait for reply from the FS server. */
    709718        sysarg_t rc;
    710719        async_wait_for(msg, &rc);
    711720       
    712         vfs_release_phone(file->node->fs_handle, fs_phone);
    713721        fibril_mutex_unlock(&file->lock);
    714 
     722       
    715723        vfs_file_put(file);
    716724        async_answer_0(rid, rc);
    717725}
    718726
    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;
    752 }
    753 
    754727void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    755728{
    756729        int fd = IPC_GET_ARG1(*request);
    757        
    758         /* Lookup the file structure corresponding to the file descriptor. */
    759         vfs_file_t *file = vfs_file_get(fd);
    760         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);
     730        int ret = vfs_fd_free(fd);
    771731        async_answer_0(rid, ret);
    772732}
     
    774734static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    775735{
    776         vfs_info_t *vi;
    777 
    778736        /*
    779737         * The following code strongly depends on the fact that the files data
     
    785743         * open files supports parallel access!
    786744         */
    787 
     745       
    788746        int fd = IPC_GET_ARG1(*request);
    789747       
     
    800758         */
    801759        fibril_mutex_lock(&file->lock);
    802 
    803         vi = fs_handle_to_info(file->node->fs_handle);
    804         assert(vi);
    805 
     760       
     761        vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
     762        assert(fs_info);
     763       
    806764        /*
    807765         * Lock the file's node so that no other client can read/write to it at
     
    809767         * write implementation does not modify the file size.
    810768         */
    811         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     769        if ((read) ||
     770            ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
    812771                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    813772        else
    814773                fibril_rwlock_write_lock(&file->node->contents_rwlock);
    815 
     774       
    816775        if (file->node->type == VFS_NODE_DIRECTORY) {
    817776                /*
     
    823782        }
    824783       
    825         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     784        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    826785       
    827786        /*
     
    835794        ipc_call_t answer;
    836795        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);
     796                rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ,
     797                    file->node->service_id, file->node->index,
     798                    LOWER32(file->pos), UPPER32(file->pos), &answer);
    840799        } else {
    841800                if (file->append)
    842801                        file->pos = file->node->size;
    843802               
    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);
     803                rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE,
     804                    file->node->service_id, file->node->index,
     805                    LOWER32(file->pos), UPPER32(file->pos), &answer);
     806        }
     807       
     808        vfs_exchange_release(fs_exch);
    850809       
    851810        size_t bytes = IPC_GET_ARG1(answer);
     
    855814       
    856815        /* Unlock the VFS node. */
    857         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     816        if ((read) ||
     817            ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
    858818                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    859819        else {
    860820                /* Update the cached version of node's size. */
    861821                if (rc == EOK)
    862                         file->node->size = IPC_GET_ARG2(answer);
     822                        file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer),
     823                            IPC_GET_ARG3(answer));
    863824                fibril_rwlock_write_unlock(&file->node->contents_rwlock);
    864825        }
     
    972933}
    973934
    974 int vfs_truncate_internal(fs_handle_t fs_handle, devmap_handle_t devmap_handle,
     935int vfs_truncate_internal(fs_handle_t fs_handle, service_id_t service_id,
    975936    fs_index_t index, aoff64_t size)
    976937{
    977         sysarg_t rc;
    978         int fs_phone;
    979        
    980         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);
    984         return (int)rc;
     938        async_exch_t *exch = vfs_exchange_grab(fs_handle);
     939        sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE,
     940            (sysarg_t) service_id, (sysarg_t) index, LOWER32(size),
     941            UPPER32(size));
     942        vfs_exchange_release(exch);
     943       
     944        return (int) rc;
    985945}
    986946
     
    1001961        fibril_rwlock_write_lock(&file->node->contents_rwlock);
    1002962        rc = vfs_truncate_internal(file->node->fs_handle,
    1003             file->node->devmap_handle, file->node->index, size);
     963            file->node->service_id, file->node->index, size);
    1004964        if (rc == EOK)
    1005965                file->node->size = size;
     
    1032992        fibril_mutex_lock(&file->lock);
    1033993
    1034         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     994        async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
    1035995       
    1036996        aid_t msg;
    1037         msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle,
     997        msg = async_send_3(exch, VFS_OUT_STAT, file->node->service_id,
    1038998            file->node->index, true, NULL);
    1039         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     999        async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1000       
     1001        vfs_exchange_release(exch);
     1002       
    10401003        async_wait_for(msg, &rc);
    1041         vfs_release_phone(file->node->fs_handle, fs_phone);
    1042 
     1004       
    10431005        fibril_mutex_unlock(&file->lock);
    10441006        vfs_file_put(file);
     
    10831045        fibril_rwlock_read_unlock(&namespace_rwlock);
    10841046
    1085         int fs_phone = vfs_grab_phone(node->fs_handle);
     1047        async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     1048       
    10861049        aid_t msg;
    1087         msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
     1050        msg = async_send_3(exch, VFS_OUT_STAT, node->service_id,
    10881051            node->index, false, NULL);
    1089         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1052        async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1053       
     1054        vfs_exchange_release(exch);
    10901055       
    10911056        sysarg_t rv;
    10921057        async_wait_for(msg, &rv);
    1093         vfs_release_phone(node->fs_handle, fs_phone);
    10941058
    10951059        async_answer_0(rid, rv);
     
    12611225        /* Check whether linking to the same file system instance. */
    12621226        if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
    1263             (old_node->devmap_handle != new_par_lr.triplet.devmap_handle)) {
     1227            (old_node->service_id != new_par_lr.triplet.service_id)) {
    12641228                fibril_rwlock_write_unlock(&namespace_rwlock);
    12651229                vfs_node_put(old_node);
     
    13691333        fibril_mutex_lock(&oldfile->lock);
    13701334       
    1371         /* Lookup an open file structure possibly corresponding to newfd. */
    1372         vfs_file_t *newfile = vfs_file_get(newfd);
    1373         if (newfile) {
    1374                 /* Close the originally opened file. */
    1375                 int ret = vfs_close_internal(newfile);
    1376                 if (ret != EOK) {
    1377                         fibril_mutex_unlock(&oldfile->lock);
    1378                         vfs_file_put(oldfile);
    1379                         vfs_file_put(newfile);
    1380                         async_answer_0(rid, ret);
    1381                         return;
    1382                 }
    1383                
    1384                 ret = vfs_fd_free(newfd);
    1385                 if (ret != EOK) {
    1386                         fibril_mutex_unlock(&oldfile->lock);
    1387                         vfs_file_put(oldfile);
    1388                         vfs_file_put(newfile);
    1389                         async_answer_0(rid, ret);
    1390                         return;
    1391                 }
    1392                 vfs_file_put(newfile);
    1393         }
     1335        /* Make sure newfd is closed. */
     1336        (void) vfs_fd_free(newfd);
    13941337       
    13951338        /* Assign the old file to newfd. */
     
    14041347}
    14051348
     1349void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
     1350{
     1351        int fd = vfs_wait_handle_internal();
     1352        async_answer_1(rid, EOK, fd);
     1353}
     1354
     1355void vfs_get_mtab(ipc_callid_t rid, ipc_call_t *request)
     1356{
     1357        ipc_callid_t callid;
     1358        ipc_call_t data;
     1359        sysarg_t rc = EOK;
     1360        size_t len;
     1361
     1362        fibril_mutex_lock(&mtab_list_lock);
     1363
     1364        /* Send to the caller the number of mounted filesystems */
     1365        callid = async_get_call(&data);
     1366        if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
     1367                rc = ENOTSUP;
     1368                async_answer_0(callid, rc);
     1369                goto exit;
     1370        }
     1371        async_answer_1(callid, EOK, mtab_size);
     1372
     1373        list_foreach(mtab_list, cur) {
     1374                mtab_ent_t *mtab_ent = list_get_instance(cur, mtab_ent_t,
     1375                    link);
     1376
     1377                rc = ENOTSUP;
     1378
     1379                if (!async_data_read_receive(&callid, &len)) {
     1380                        async_answer_0(callid, rc);
     1381                        goto exit;
     1382                }
     1383
     1384                (void) async_data_read_finalize(callid, mtab_ent->mp,
     1385                    str_size(mtab_ent->mp));
     1386
     1387                if (!async_data_read_receive(&callid, &len)) {
     1388                        async_answer_0(callid, rc);
     1389                        goto exit;
     1390                }
     1391
     1392                (void) async_data_read_finalize(callid, mtab_ent->opts,
     1393                    str_size(mtab_ent->opts));
     1394
     1395                if (!async_data_read_receive(&callid, &len)) {
     1396                        async_answer_0(callid, rc);
     1397                        goto exit;
     1398                }
     1399
     1400                (void) async_data_read_finalize(callid, mtab_ent->fs_name,
     1401                    str_size(mtab_ent->fs_name));
     1402
     1403                callid = async_get_call(&data);
     1404
     1405                if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
     1406                        async_answer_0(callid, rc);
     1407                        goto exit;
     1408                }
     1409
     1410                rc = EOK;
     1411                async_answer_2(callid, rc, mtab_ent->instance,
     1412                    mtab_ent->service_id);
     1413        }
     1414
     1415exit:
     1416        fibril_mutex_unlock(&mtab_list_lock);
     1417        async_answer_0(rid, rc);
     1418}
     1419
    14061420/**
    14071421 * @}
Note: See TracChangeset for help on using the changeset viewer.