Ignore:
File:
1 edited

Legend:

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

    r79ae36dd rccca251  
    7878        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) {
     
    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) {
     
    231227                rsize = (size_t) IPC_GET_ARG2(answer);
    232228                rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
    233                
     229       
    234230                mr_res.triplet.fs_handle = fs_handle;
    235231                mr_res.triplet.devmap_handle = devmap_handle;
     
    238234                mr_res.lnkcnt = rlnkcnt;
    239235                mr_res.type = VFS_NODE_DIRECTORY;
    240                
     236       
    241237                /* Add reference to the mounted root. */
    242238                mr_node = vfs_node_get(&mr_res);
     
    247243                        vfs_node_put(mp_node);
    248244        }
    249        
     245
    250246        async_answer_0(rid, rc);
    251247        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    307303       
    308304        /*
    309          * 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
    310306         * fs_name.
    311307         */
    312308        ipc_call_t data;
    313309        ipc_callid_t callid = async_get_call(&data);
    314         if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
     310        if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
    315311                async_answer_0(callid, ENOTSUP);
    316312                async_answer_0(rid, ENOTSUP);
     
    362358        vfs_lookup_res_t mr_res;
    363359        vfs_node_t *mr_node;
    364         async_exch_t *exch;
    365        
     360        int phone;
     361
    366362        /*
    367363         * Receive the mount point path.
     
    371367        if (rc != EOK)
    372368                async_answer_0(rid, rc);
    373        
     369
    374370        /*
    375371         * Taking the namespace lock will do two things for us. First, it will
     
    399395                return;
    400396        }
    401        
     397
    402398        /*
    403399         * Count the total number of references for the mounted file system. We
     
    415411                return;
    416412        }
    417        
     413
    418414        if (str_cmp(mp, "/") == 0) {
    419                
     415
    420416                /*
    421417                 * Unmounting the root file system.
     
    424420                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
    425421                 */
    426                
     422
    427423                free(mp);
    428                
    429                 exch = vfs_exchange_grab(mr_node->fs_handle);
    430                 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,
    431426                    mr_node->devmap_handle);
    432                 vfs_exchange_release(exch);
    433                
     427                vfs_release_phone(mr_node->fs_handle, phone);
    434428                if (rc != EOK) {
    435429                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    438432                        return;
    439433                }
    440                
    441434                rootfs.fs_handle = 0;
    442435                rootfs.devmap_handle = 0;
    443436        } else {
    444                
     437
    445438                /*
    446439                 * Unmounting a non-root file system.
     
    449442                 * file system, so we delegate the operation to it.
    450443                 */
    451                
     444
    452445                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    453446                free(mp);
     
    458451                        return;
    459452                }
    460                
    461453                vfs_node_t *mp_node = vfs_node_get(&mp_res);
    462454                if (!mp_node) {
     
    466458                        return;
    467459                }
    468                
    469                 exch = vfs_exchange_grab(mp_node->fs_handle);
    470                 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,
    471463                    mp_node->devmap_handle, mp_node->index);
    472                 vfs_exchange_release(exch);
    473                
     464                vfs_release_phone(mp_node->fs_handle, phone);
    474465                if (rc != EOK) {
    475466                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    479470                        return;
    480471                }
    481                
     472
    482473                /* Drop the reference we got above. */
    483474                vfs_node_put(mp_node);
     
    485476                vfs_node_put(mp_node);
    486477        }
    487        
     478
     479
    488480        /*
    489481         * All went well, the mounted file system was successfully unmounted.
     
    491483         */
    492484        vfs_node_forget(mr_node);
    493        
     485
    494486        fibril_rwlock_write_unlock(&namespace_rwlock);
    495487        async_answer_0(rid, EOK);
     
    706698         */
    707699        fibril_mutex_lock(&file->lock);
    708         async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
     700        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    709701       
    710702        /* Make a VFS_OUT_SYMC request at the destination FS server. */
    711703        aid_t msg;
    712704        ipc_call_t answer;
    713         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,
    714706            file->node->index, &answer);
    715        
    716         vfs_exchange_release(fs_exch);
    717        
     707
    718708        /* Wait for reply from the FS server. */
    719709        sysarg_t rc;
    720710        async_wait_for(msg, &rc);
    721711       
     712        vfs_release_phone(file->node->fs_handle, fs_phone);
    722713        fibril_mutex_unlock(&file->lock);
    723        
     714
    724715        vfs_file_put(file);
    725716        async_answer_0(rid, rc);
    726717}
    727718
     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
    728754void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    729755{
    730756        int fd = IPC_GET_ARG1(*request);
    731         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);
    732771        async_answer_0(rid, ret);
    733772}
     
    735774static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    736775{
     776        vfs_info_t *vi;
     777
    737778        /*
    738779         * The following code strongly depends on the fact that the files data
     
    744785         * open files supports parallel access!
    745786         */
    746        
     787
    747788        int fd = IPC_GET_ARG1(*request);
    748789       
     
    759800         */
    760801        fibril_mutex_lock(&file->lock);
    761        
    762         vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
    763         assert(fs_info);
    764        
     802
     803        vi = fs_handle_to_info(file->node->fs_handle);
     804        assert(vi);
     805
    765806        /*
    766807         * Lock the file's node so that no other client can read/write to it at
     
    768809         * write implementation does not modify the file size.
    769810         */
    770         if ((read) ||
    771             ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
     811        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    772812                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    773813        else
    774814                fibril_rwlock_write_lock(&file->node->contents_rwlock);
    775        
     815
    776816        if (file->node->type == VFS_NODE_DIRECTORY) {
    777817                /*
     
    783823        }
    784824       
    785         async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
     825        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    786826       
    787827        /*
     
    795835        ipc_call_t answer;
    796836        if (read) {
    797                 rc = async_data_read_forward_3_1(fs_exch, VFS_OUT_READ,
     837                rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
    798838                    file->node->devmap_handle, file->node->index, file->pos,
    799839                    &answer);
     
    802842                        file->pos = file->node->size;
    803843               
    804                 rc = async_data_write_forward_3_1(fs_exch, VFS_OUT_WRITE,
     844                rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
    805845                    file->node->devmap_handle, file->node->index, file->pos,
    806846                    &answer);
    807847        }
    808848       
    809         vfs_exchange_release(fs_exch);
     849        vfs_release_phone(file->node->fs_handle, fs_phone);
    810850       
    811851        size_t bytes = IPC_GET_ARG1(answer);
     
    815855       
    816856        /* Unlock the VFS node. */
    817         if ((read) ||
    818             ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
     857        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    819858                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    820859        else {
     
    936975    fs_index_t index, aoff64_t size)
    937976{
    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) devmap_handle, (sysarg_t) index, LOWER32(size),
    941             UPPER32(size));
    942         vfs_exchange_release(exch);
    943        
    944         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;
    945985}
    946986
     
    9921032        fibril_mutex_lock(&file->lock);
    9931033
    994         async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
     1034        int fs_phone = vfs_grab_phone(file->node->fs_handle);
    9951035       
    9961036        aid_t msg;
    997         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,
    9981038            file->node->index, true, NULL);
    999         async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1000        
    1001         vfs_exchange_release(exch);
    1002        
     1039        async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    10031040        async_wait_for(msg, &rc);
    1004        
     1041        vfs_release_phone(file->node->fs_handle, fs_phone);
     1042
    10051043        fibril_mutex_unlock(&file->lock);
    10061044        vfs_file_put(file);
     
    10451083        fibril_rwlock_read_unlock(&namespace_rwlock);
    10461084
    1047         async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
    1048        
     1085        int fs_phone = vfs_grab_phone(node->fs_handle);
    10491086        aid_t msg;
    1050         msg = async_send_3(exch, VFS_OUT_STAT, node->devmap_handle,
     1087        msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
    10511088            node->index, false, NULL);
    1052         async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1053        
    1054         vfs_exchange_release(exch);
     1089        async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    10551090       
    10561091        sysarg_t rv;
    10571092        async_wait_for(msg, &rv);
     1093        vfs_release_phone(node->fs_handle, fs_phone);
    10581094
    10591095        async_answer_0(rid, rv);
     
    13331369        fibril_mutex_lock(&oldfile->lock);
    13341370       
    1335         /* Make sure newfd is closed. */
    1336         (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        }
    13371394       
    13381395        /* Assign the old file to newfd. */
Note: See TracChangeset for help on using the changeset viewer.