Ignore:
File:
1 edited

Legend:

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

    r5bb9907 rccca251  
    7676        vfs_node_t *mr_node;
    7777        fs_index_t rindex;
    78         aoff64_t rsize;
     78        size_t rsize;
    7979        unsigned rlnkcnt;
    80         async_exch_t *exch;
    8180        sysarg_t rc;
     81        int phone;
    8282        aid_t msg;
    8383        ipc_call_t answer;
     
    123123                       
    124124                        /* Tell the mountee that it is being mounted. */
    125                         exch = vfs_exchange_grab(fs_handle);
    126                         msg = async_send_1(exch, VFS_OUT_MOUNTED,
     125                        phone = vfs_grab_phone(fs_handle);
     126                        msg = async_send_1(phone, VFS_OUT_MOUNTED,
    127127                            (sysarg_t) devmap_handle, &answer);
    128                         /* Send the mount options */
    129                         rc = async_data_write_start(exch, (void *)opts,
     128                        /* send the mount options */
     129                        rc = async_data_write_start(phone, (void *)opts,
    130130                            str_size(opts));
    131                         vfs_exchange_release(exch);
    132                        
    133131                        if (rc != EOK) {
    134132                                async_wait_for(msg, NULL);
     133                                vfs_release_phone(fs_handle, phone);
    135134                                fibril_rwlock_write_unlock(&namespace_rwlock);
    136135                                async_answer_0(rid, rc);
     
    138137                        }
    139138                        async_wait_for(msg, &rc);
     139                        vfs_release_phone(fs_handle, phone);
    140140                       
    141141                        if (rc != EOK) {
     
    146146
    147147                        rindex = (fs_index_t) IPC_GET_ARG1(answer);
    148                         rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    149                         rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
     148                        rsize = (size_t) IPC_GET_ARG2(answer);
     149                        rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
    150150                       
    151151                        mr_res.triplet.fs_handle = fs_handle;
     
    182182         */
    183183       
    184         async_exch_t *mountee_exch = vfs_exchange_grab(fs_handle);
    185         assert(mountee_exch);
    186        
    187         exch = vfs_exchange_grab(mp_res.triplet.fs_handle);
    188         msg = async_send_4(exch, VFS_OUT_MOUNT,
     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,
    189189            (sysarg_t) mp_res.triplet.devmap_handle,
    190190            (sysarg_t) mp_res.triplet.index,
     
    192192            (sysarg_t) devmap_handle, &answer);
    193193       
    194         /* Send connection */
    195         rc = async_exchange_clone(exch, mountee_exch);
    196         vfs_exchange_release(mountee_exch);
    197        
    198         if (rc != EOK) {
    199                 vfs_exchange_release(exch);
     194        /* send connection */
     195        rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
     196        if (rc != EOK) {
    200197                async_wait_for(msg, NULL);
    201                
     198                vfs_release_phone(fs_handle, mountee_phone);
     199                vfs_release_phone(mp_res.triplet.fs_handle, phone);
    202200                /* Mount failed, drop reference to mp_node. */
    203201                if (mp_node)
    204202                        vfs_node_put(mp_node);
    205                
    206203                async_answer_0(rid, rc);
    207204                fibril_rwlock_write_unlock(&namespace_rwlock);
    208205                return;
    209206        }
     207
     208        vfs_release_phone(fs_handle, mountee_phone);
    210209       
    211210        /* send the mount options */
    212         rc = async_data_write_start(exch, (void *) opts, str_size(opts));
    213         if (rc != EOK) {
    214                 vfs_exchange_release(exch);
     211        rc = async_data_write_start(phone, (void *)opts, str_size(opts));
     212        if (rc != EOK) {
    215213                async_wait_for(msg, NULL);
    216                
     214                vfs_release_phone(mp_res.triplet.fs_handle, phone);
    217215                /* Mount failed, drop reference to mp_node. */
    218216                if (mp_node)
    219217                        vfs_node_put(mp_node);
    220                
    221218                fibril_rwlock_write_unlock(&namespace_rwlock);
    222219                async_answer_0(rid, rc);
    223220                return;
    224221        }
    225        
    226         vfs_exchange_release(exch);
    227222        async_wait_for(msg, &rc);
     223        vfs_release_phone(mp_res.triplet.fs_handle, phone);
    228224       
    229225        if (rc == EOK) {
    230226                rindex = (fs_index_t) IPC_GET_ARG1(answer);
    231                 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
    232                     IPC_GET_ARG3(answer));
    233                 rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
    234                
     227                rsize = (size_t) IPC_GET_ARG2(answer);
     228                rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
     229       
    235230                mr_res.triplet.fs_handle = fs_handle;
    236231                mr_res.triplet.devmap_handle = devmap_handle;
     
    239234                mr_res.lnkcnt = rlnkcnt;
    240235                mr_res.type = VFS_NODE_DIRECTORY;
    241                
     236       
    242237                /* Add reference to the mounted root. */
    243238                mr_node = vfs_node_get(&mr_res);
     
    248243                        vfs_node_put(mp_node);
    249244        }
    250        
     245
    251246        async_answer_0(rid, rc);
    252247        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    308303       
    309304        /*
    310          * Wait for VFS_IN_PING so that we can return an error if we don't know
     305         * Wait for IPC_M_PING so that we can return an error if we don't know
    311306         * fs_name.
    312307         */
    313308        ipc_call_t data;
    314309        ipc_callid_t callid = async_get_call(&data);
    315         if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
     310        if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
    316311                async_answer_0(callid, ENOTSUP);
    317312                async_answer_0(rid, ENOTSUP);
     
    326321         * This will also give us its file system handle.
    327322         */
    328         fibril_mutex_lock(&fs_list_lock);
     323        fibril_mutex_lock(&fs_head_lock);
    329324        fs_handle_t fs_handle;
    330325recheck:
     
    332327        if (!fs_handle) {
    333328                if (flags & IPC_FLAG_BLOCKING) {
    334                         fibril_condvar_wait(&fs_list_cv, &fs_list_lock);
     329                        fibril_condvar_wait(&fs_head_cv, &fs_head_lock);
    335330                        goto recheck;
    336331                }
    337332               
    338                 fibril_mutex_unlock(&fs_list_lock);
     333                fibril_mutex_unlock(&fs_head_lock);
    339334                async_answer_0(callid, ENOENT);
    340335                async_answer_0(rid, ENOENT);
     
    344339                return;
    345340        }
    346         fibril_mutex_unlock(&fs_list_lock);
     341        fibril_mutex_unlock(&fs_head_lock);
    347342       
    348343        /* Acknowledge that we know fs_name. */
     
    363358        vfs_lookup_res_t mr_res;
    364359        vfs_node_t *mr_node;
    365         async_exch_t *exch;
    366        
     360        int phone;
     361
    367362        /*
    368363         * Receive the mount point path.
     
    372367        if (rc != EOK)
    373368                async_answer_0(rid, rc);
    374        
     369
    375370        /*
    376371         * Taking the namespace lock will do two things for us. First, it will
     
    400395                return;
    401396        }
    402        
     397
    403398        /*
    404399         * Count the total number of references for the mounted file system. We
     
    416411                return;
    417412        }
    418        
     413
    419414        if (str_cmp(mp, "/") == 0) {
    420                
     415
    421416                /*
    422417                 * Unmounting the root file system.
     
    425420                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
    426421                 */
    427                
     422
    428423                free(mp);
    429                
    430                 exch = vfs_exchange_grab(mr_node->fs_handle);
    431                 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,
     424                phone = vfs_grab_phone(mr_node->fs_handle);
     425                rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
    432426                    mr_node->devmap_handle);
    433                 vfs_exchange_release(exch);
    434                
     427                vfs_release_phone(mr_node->fs_handle, phone);
    435428                if (rc != EOK) {
    436429                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    439432                        return;
    440433                }
    441                
    442434                rootfs.fs_handle = 0;
    443435                rootfs.devmap_handle = 0;
    444436        } else {
    445                
     437
    446438                /*
    447439                 * Unmounting a non-root file system.
     
    450442                 * file system, so we delegate the operation to it.
    451443                 */
    452                
     444
    453445                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    454446                free(mp);
     
    459451                        return;
    460452                }
    461                
    462453                vfs_node_t *mp_node = vfs_node_get(&mp_res);
    463454                if (!mp_node) {
     
    467458                        return;
    468459                }
    469                
    470                 exch = vfs_exchange_grab(mp_node->fs_handle);
    471                 rc = async_req_2_0(exch, VFS_OUT_UNMOUNT,
     460
     461                phone = vfs_grab_phone(mp_node->fs_handle);
     462                rc = async_req_2_0(phone, VFS_OUT_UNMOUNT,
    472463                    mp_node->devmap_handle, mp_node->index);
    473                 vfs_exchange_release(exch);
    474                
     464                vfs_release_phone(mp_node->fs_handle, phone);
    475465                if (rc != EOK) {
    476466                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    480470                        return;
    481471                }
    482                
     472
    483473                /* Drop the reference we got above. */
    484474                vfs_node_put(mp_node);
     
    486476                vfs_node_put(mp_node);
    487477        }
    488        
     478
     479
    489480        /*
    490481         * All went well, the mounted file system was successfully unmounted.
     
    492483         */
    493484        vfs_node_forget(mr_node);
    494        
     485
    495486        fibril_rwlock_write_unlock(&namespace_rwlock);
    496487        async_answer_0(rid, EOK);
     
    707698         */
    708699        fibril_mutex_lock(&file->lock);
    709         async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
     700        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    710701       
    711702        /* Make a VFS_OUT_SYMC request at the destination FS server. */
    712703        aid_t msg;
    713704        ipc_call_t answer;
    714         msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->devmap_handle,
     705        msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle,
    715706            file->node->index, &answer);
    716        
    717         vfs_exchange_release(fs_exch);
    718        
     707
    719708        /* Wait for reply from the FS server. */
    720709        sysarg_t rc;
    721710        async_wait_for(msg, &rc);
    722711       
     712        vfs_release_phone(file->node->fs_handle, fs_phone);
    723713        fibril_mutex_unlock(&file->lock);
    724        
     714
    725715        vfs_file_put(file);
    726716        async_answer_0(rid, rc);
    727717}
    728718
     719int 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
    729754void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    730755{
    731756        int fd = IPC_GET_ARG1(*request);
    732         int ret = vfs_fd_free(fd);
     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);
    733771        async_answer_0(rid, ret);
    734772}
     
    736774static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    737775{
     776        vfs_info_t *vi;
     777
    738778        /*
    739779         * The following code strongly depends on the fact that the files data
     
    745785         * open files supports parallel access!
    746786         */
    747        
     787
    748788        int fd = IPC_GET_ARG1(*request);
    749789       
     
    760800         */
    761801        fibril_mutex_lock(&file->lock);
    762        
    763         vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
    764         assert(fs_info);
    765        
     802
     803        vi = fs_handle_to_info(file->node->fs_handle);
     804        assert(vi);
     805
    766806        /*
    767807         * Lock the file's node so that no other client can read/write to it at
     
    769809         * write implementation does not modify the file size.
    770810         */
    771         if ((read) ||
    772             ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
     811        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    773812                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    774813        else
    775814                fibril_rwlock_write_lock(&file->node->contents_rwlock);
    776        
     815
    777816        if (file->node->type == VFS_NODE_DIRECTORY) {
    778817                /*
     
    784823        }
    785824       
    786         async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
     825        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    787826       
    788827        /*
     
    796835        ipc_call_t answer;
    797836        if (read) {
    798                 rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ,
    799                     file->node->devmap_handle, file->node->index,
    800                     LOWER32(file->pos), UPPER32(file->pos), &answer);
     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);
    801840        } else {
    802841                if (file->append)
    803842                        file->pos = file->node->size;
    804843               
    805                 rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE,
    806                     file->node->devmap_handle, file->node->index,
    807                     LOWER32(file->pos), UPPER32(file->pos), &answer);
    808         }
    809        
    810         vfs_exchange_release(fs_exch);
     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);
    811850       
    812851        size_t bytes = IPC_GET_ARG1(answer);
     
    816855       
    817856        /* Unlock the VFS node. */
    818         if ((read) ||
    819             ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
     857        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    820858                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    821859        else {
    822860                /* Update the cached version of node's size. */
    823861                if (rc == EOK)
    824                         file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer),
    825                             IPC_GET_ARG3(answer));
     862                        file->node->size = IPC_GET_ARG2(answer);
    826863                fibril_rwlock_write_unlock(&file->node->contents_rwlock);
    827864        }
     
    938975    fs_index_t index, aoff64_t size)
    939976{
    940         async_exch_t *exch = vfs_exchange_grab(fs_handle);
    941         sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE,
    942             (sysarg_t) devmap_handle, (sysarg_t) index, LOWER32(size),
    943             UPPER32(size));
    944         vfs_exchange_release(exch);
    945        
    946         return (int) rc;
     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;
    947985}
    948986
     
    9941032        fibril_mutex_lock(&file->lock);
    9951033
    996         async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
     1034        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    9971035       
    9981036        aid_t msg;
    999         msg = async_send_3(exch, VFS_OUT_STAT, file->node->devmap_handle,
     1037        msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle,
    10001038            file->node->index, true, NULL);
    1001         async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1002        
    1003         vfs_exchange_release(exch);
    1004        
     1039        async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    10051040        async_wait_for(msg, &rc);
    1006        
     1041        vfs_release_phone(file->node->fs_handle, fs_phone);
     1042
    10071043        fibril_mutex_unlock(&file->lock);
    10081044        vfs_file_put(file);
     
    10471083        fibril_rwlock_read_unlock(&namespace_rwlock);
    10481084
    1049         async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
    1050        
     1085        int fs_phone = vfs_grab_phone(node->fs_handle);
    10511086        aid_t msg;
    1052         msg = async_send_3(exch, VFS_OUT_STAT, node->devmap_handle,
     1087        msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
    10531088            node->index, false, NULL);
    1054         async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1055        
    1056         vfs_exchange_release(exch);
     1089        async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    10571090       
    10581091        sysarg_t rv;
    10591092        async_wait_for(msg, &rv);
     1093        vfs_release_phone(node->fs_handle, fs_phone);
    10601094
    10611095        async_answer_0(rid, rv);
     
    13351369        fibril_mutex_lock(&oldfile->lock);
    13361370       
    1337         /* Make sure newfd is closed. */
    1338         (void) vfs_fd_free(newfd);
     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        }
    13391394       
    13401395        /* Assign the old file to newfd. */
Note: See TracChangeset for help on using the changeset viewer.