Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef rdd2cfa7  
    3737
    3838#include "vfs.h"
    39 #include <macros.h>
    40 #include <stdint.h>
     39#include <ipc/ipc.h>
    4140#include <async.h>
    4241#include <errno.h>
    4342#include <stdio.h>
    4443#include <stdlib.h>
    45 #include <str.h>
     44#include <string.h>
    4645#include <bool.h>
    47 #include <fibril_synch.h>
     46#include <fibril_sync.h>
    4847#include <adt/list.h>
    4948#include <unistd.h>
     
    5453
    5554/* Forward declarations of static functions. */
    56 static int vfs_truncate_internal(fs_handle_t, devmap_handle_t, fs_index_t,
    57     aoff64_t);
     55static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t);
    5856
    5957/**
     
    6563vfs_pair_t rootfs = {
    6664        .fs_handle = 0,
    67         .devmap_handle = 0
     65        .dev_handle = 0
    6866};
    6967
    70 static void vfs_mount_internal(ipc_callid_t rid, devmap_handle_t devmap_handle,
     68static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle,
    7169    fs_handle_t fs_handle, char *mp, char *opts)
    7270{
     
    7876        size_t rsize;
    7977        unsigned rlnkcnt;
    80         sysarg_t rc;
     78        ipcarg_t rc;
    8179        int phone;
    8280        aid_t msg;
     
    9088                        /* Trying to mount root FS over root FS */
    9189                        fibril_rwlock_write_unlock(&namespace_rwlock);
    92                         async_answer_0(rid, EBUSY);
     90                        ipc_answer_0(rid, EBUSY);
    9391                        return;
    9492                }
    9593               
    96                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
     94                rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
    9795                if (rc != EOK) {
    9896                        /* The lookup failed for some reason. */
    9997                        fibril_rwlock_write_unlock(&namespace_rwlock);
    100                         async_answer_0(rid, rc);
     98                        ipc_answer_0(rid, rc);
    10199                        return;
    102100                }
     
    105103                if (!mp_node) {
    106104                        fibril_rwlock_write_unlock(&namespace_rwlock);
    107                         async_answer_0(rid, ENOMEM);
     105                        ipc_answer_0(rid, ENOMEM);
    108106                        return;
    109107                }
     
    125123                        phone = vfs_grab_phone(fs_handle);
    126124                        msg = async_send_1(phone, VFS_OUT_MOUNTED,
    127                             (sysarg_t) devmap_handle, &answer);
     125                            (ipcarg_t) dev_handle, &answer);
    128126                        /* send the mount options */
    129                         rc = async_data_write_start(phone, (void *)opts,
     127                        rc = ipc_data_write_start(phone, (void *)opts,
    130128                            str_size(opts));
    131129                        if (rc != EOK) {
    132130                                async_wait_for(msg, NULL);
    133                                 vfs_release_phone(fs_handle, phone);
     131                                vfs_release_phone(phone);
    134132                                fibril_rwlock_write_unlock(&namespace_rwlock);
    135                                 async_answer_0(rid, rc);
     133                                ipc_answer_0(rid, rc);
    136134                                return;
    137135                        }
    138136                        async_wait_for(msg, &rc);
    139                         vfs_release_phone(fs_handle, phone);
     137                        vfs_release_phone(phone);
    140138                       
    141139                        if (rc != EOK) {
    142140                                fibril_rwlock_write_unlock(&namespace_rwlock);
    143                                 async_answer_0(rid, rc);
     141                                ipc_answer_0(rid, rc);
    144142                                return;
    145143                        }
     
    150148                       
    151149                        mr_res.triplet.fs_handle = fs_handle;
    152                         mr_res.triplet.devmap_handle = devmap_handle;
     150                        mr_res.triplet.dev_handle = dev_handle;
    153151                        mr_res.triplet.index = rindex;
    154152                        mr_res.size = rsize;
     
    157155                       
    158156                        rootfs.fs_handle = fs_handle;
    159                         rootfs.devmap_handle = devmap_handle;
     157                        rootfs.dev_handle = dev_handle;
    160158                       
    161159                        /* Add reference to the mounted root. */
     
    164162                       
    165163                        fibril_rwlock_write_unlock(&namespace_rwlock);
    166                         async_answer_0(rid, rc);
     164                        ipc_answer_0(rid, rc);
    167165                        return;
    168166                } else {
     
    172170                         */
    173171                        fibril_rwlock_write_unlock(&namespace_rwlock);
    174                         async_answer_0(rid, ENOENT);
     172                        ipc_answer_0(rid, ENOENT);
    175173                        return;
    176174                }
     
    187185        phone = vfs_grab_phone(mp_res.triplet.fs_handle);
    188186        msg = async_send_4(phone, VFS_OUT_MOUNT,
    189             (sysarg_t) mp_res.triplet.devmap_handle,
    190             (sysarg_t) mp_res.triplet.index,
    191             (sysarg_t) fs_handle,
    192             (sysarg_t) devmap_handle, &answer);
     187            (ipcarg_t) mp_res.triplet.dev_handle,
     188            (ipcarg_t) mp_res.triplet.index,
     189            (ipcarg_t) fs_handle,
     190            (ipcarg_t) dev_handle, &answer);
    193191       
    194192        /* send connection */
     
    196194        if (rc != EOK) {
    197195                async_wait_for(msg, NULL);
    198                 vfs_release_phone(fs_handle, mountee_phone);
    199                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     196                vfs_release_phone(mountee_phone);
     197                vfs_release_phone(phone);
    200198                /* Mount failed, drop reference to mp_node. */
    201199                if (mp_node)
    202200                        vfs_node_put(mp_node);
    203                 async_answer_0(rid, rc);
     201                ipc_answer_0(rid, rc);
    204202                fibril_rwlock_write_unlock(&namespace_rwlock);
    205203                return;
    206204        }
    207205
    208         vfs_release_phone(fs_handle, mountee_phone);
     206        vfs_release_phone(mountee_phone);
    209207       
    210208        /* send the mount options */
    211         rc = async_data_write_start(phone, (void *)opts, str_size(opts));
     209        rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
    212210        if (rc != EOK) {
    213211                async_wait_for(msg, NULL);
    214                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     212                vfs_release_phone(phone);
    215213                /* Mount failed, drop reference to mp_node. */
    216214                if (mp_node)
    217215                        vfs_node_put(mp_node);
    218216                fibril_rwlock_write_unlock(&namespace_rwlock);
    219                 async_answer_0(rid, rc);
     217                ipc_answer_0(rid, rc);
    220218                return;
    221219        }
    222220        async_wait_for(msg, &rc);
    223         vfs_release_phone(mp_res.triplet.fs_handle, phone);
     221        vfs_release_phone(phone);
    224222       
    225223        if (rc == EOK) {
     
    229227       
    230228                mr_res.triplet.fs_handle = fs_handle;
    231                 mr_res.triplet.devmap_handle = devmap_handle;
     229                mr_res.triplet.dev_handle = dev_handle;
    232230                mr_res.triplet.index = rindex;
    233231                mr_res.size = rsize;
     
    244242        }
    245243
    246         async_answer_0(rid, rc);
     244        ipc_answer_0(rid, rc);
    247245        fibril_rwlock_write_unlock(&namespace_rwlock);
    248246}
     
    250248void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
    251249{
    252         devmap_handle_t devmap_handle;
    253 
    254250        /*
    255251         * We expect the library to do the device-name to device-handle
     
    257253         * in the request.
    258254         */
    259         devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     255        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    260256       
    261257        /*
     
    270266       
    271267        /* We want the client to send us the mount point. */
    272         char *mp;
    273         int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    274             0, NULL);
    275         if (rc != EOK) {
    276                 async_answer_0(rid, rc);
    277                 return;
    278         }
     268        ipc_callid_t callid;
     269        size_t size;
     270        if (!ipc_data_write_receive(&callid, &size)) {
     271                ipc_answer_0(callid, EINVAL);
     272                ipc_answer_0(rid, EINVAL);
     273                return;
     274        }
     275       
     276        /* Check whether size is reasonable wrt. the mount point. */
     277        if ((size < 1) || (size > MAX_PATH_LEN)) {
     278                ipc_answer_0(callid, EINVAL);
     279                ipc_answer_0(rid, EINVAL);
     280                return;
     281        }
     282       
     283        /* Allocate buffer for the mount point data being received. */
     284        char *mp = malloc(size + 1);
     285        if (!mp) {
     286                ipc_answer_0(callid, ENOMEM);
     287                ipc_answer_0(rid, ENOMEM);
     288                return;
     289        }
     290       
     291        /* Deliver the mount point. */
     292        ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);
     293        if (retval != EOK) {
     294                ipc_answer_0(rid, retval);
     295                free(mp);
     296                return;
     297        }
     298        mp[size] = '\0';
    279299       
    280300        /* Now we expect to receive the mount options. */
    281         char *opts;
    282         rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
    283             0, NULL);
    284         if (rc != EOK) {
     301        if (!ipc_data_write_receive(&callid, &size)) {
     302                ipc_answer_0(callid, EINVAL);
     303                ipc_answer_0(rid, EINVAL);
    285304                free(mp);
    286                 async_answer_0(rid, rc);
    287                 return;
    288         }
     305                return;
     306        }
     307
     308        /* Check the offered options size. */
     309        if (size > MAX_MNTOPTS_LEN) {
     310                ipc_answer_0(callid, EINVAL);
     311                ipc_answer_0(rid, EINVAL);
     312                free(mp);
     313                return;
     314        }
     315
     316        /* Allocate buffer for the mount options. */
     317        char *opts = (char *) malloc(size + 1);
     318        if (!opts) {
     319                ipc_answer_0(callid, ENOMEM);
     320                ipc_answer_0(rid, ENOMEM);
     321                free(mp);
     322                return;
     323        }
     324
     325        /* Deliver the mount options. */
     326        retval = ipc_data_write_finalize(callid, opts, size);
     327        if (retval != EOK) {
     328                ipc_answer_0(rid, retval);
     329                free(mp);
     330                free(opts);
     331                return;
     332        }
     333        opts[size] = '\0';
    289334       
    290335        /*
     
    292337         * system.
    293338         */
    294         char *fs_name;
    295         rc = async_data_write_accept((void **) &fs_name, true, 0,
    296             FS_NAME_MAXLEN, 0, NULL);
    297         if (rc != EOK) {
     339        if (!ipc_data_write_receive(&callid, &size)) {
     340                ipc_answer_0(callid, EINVAL);
     341                ipc_answer_0(rid, EINVAL);
    298342                free(mp);
    299343                free(opts);
    300                 async_answer_0(rid, rc);
    301                 return;
    302         }
    303        
     344                return;
     345        }
     346       
     347        /*
     348         * Don't receive more than is necessary for storing a full file system
     349         * name.
     350         */
     351        if ((size < 1) || (size > FS_NAME_MAXLEN)) {
     352                ipc_answer_0(callid, EINVAL);
     353                ipc_answer_0(rid, EINVAL);
     354                free(mp);
     355                free(opts);
     356                return;
     357        }
     358       
     359        /*
     360         * Allocate buffer for file system name.
     361         */
     362        char *fs_name = (char *) malloc(size + 1);
     363        if (fs_name == NULL) {
     364                ipc_answer_0(callid, ENOMEM);
     365                ipc_answer_0(rid, ENOMEM);
     366                free(mp);
     367                free(opts);
     368                return;
     369        }
     370       
     371        /* Deliver the file system name. */
     372        retval = ipc_data_write_finalize(callid, fs_name, size);
     373        if (retval != EOK) {
     374                ipc_answer_0(rid, retval);
     375                free(mp);
     376                free(opts);
     377                free(fs_name);
     378                return;
     379        }
     380        fs_name[size] = '\0';
     381
    304382        /*
    305383         * Wait for IPC_M_PING so that we can return an error if we don't know
     
    307385         */
    308386        ipc_call_t data;
    309         ipc_callid_t callid = async_get_call(&data);
    310         if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
    311                 async_answer_0(callid, ENOTSUP);
    312                 async_answer_0(rid, ENOTSUP);
     387        callid = async_get_call(&data);
     388        if (IPC_GET_METHOD(data) != IPC_M_PING) {
     389                ipc_answer_0(callid, ENOTSUP);
     390                ipc_answer_0(rid, ENOTSUP);
    313391                free(mp);
    314392                free(opts);
     
    332410               
    333411                fibril_mutex_unlock(&fs_head_lock);
    334                 async_answer_0(callid, ENOENT);
    335                 async_answer_0(rid, ENOENT);
     412                ipc_answer_0(callid, ENOENT);
     413                ipc_answer_0(rid, ENOENT);
    336414                free(mp);
    337415                free(fs_name);
     
    342420       
    343421        /* Acknowledge that we know fs_name. */
    344         async_answer_0(callid, EOK);
     422        ipc_answer_0(callid, EOK);
    345423       
    346424        /* Do the mount */
    347         vfs_mount_internal(rid, devmap_handle, fs_handle, mp, opts);
     425        vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts);
    348426        free(mp);
    349427        free(fs_name);
     
    351429}
    352430
    353 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    354 {
    355         int rc;
    356         char *mp;
    357         vfs_lookup_res_t mp_res;
    358         vfs_lookup_res_t mr_res;
    359         vfs_node_t *mr_node;
    360         int phone;
    361 
    362         /*
    363          * Receive the mount point path.
    364          */
    365         rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    366             0, NULL);
    367         if (rc != EOK)
    368                 async_answer_0(rid, rc);
    369 
    370         /*
    371          * Taking the namespace lock will do two things for us. First, it will
    372          * prevent races with other lookup operations. Second, it will stop new
    373          * references to already existing VFS nodes and creation of new VFS
    374          * nodes. This is because new references are added as a result of some
    375          * lookup operation or at least of some operation which is protected by
    376          * the namespace lock.
    377          */
    378         fibril_rwlock_write_lock(&namespace_rwlock);
    379        
    380         /*
    381          * Lookup the mounted root and instantiate it.
    382          */
    383         rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL);
    384         if (rc != EOK) {
    385                 fibril_rwlock_write_unlock(&namespace_rwlock);
    386                 free(mp);
    387                 async_answer_0(rid, rc);
    388                 return;
    389         }
    390         mr_node = vfs_node_get(&mr_res);
    391         if (!mr_node) {
    392                 fibril_rwlock_write_unlock(&namespace_rwlock);
    393                 free(mp);
    394                 async_answer_0(rid, ENOMEM);
    395                 return;
    396         }
    397 
    398         /*
    399          * Count the total number of references for the mounted file system. We
    400          * are expecting at least two. One which we got above and one which we
    401          * got when the file system was mounted. If we find more, it means that
    402          * the file system cannot be gracefully unmounted at the moment because
    403          * someone is working with it.
    404          */
    405         if (vfs_nodes_refcount_sum_get(mr_node->fs_handle,
    406             mr_node->devmap_handle) != 2) {
    407                 fibril_rwlock_write_unlock(&namespace_rwlock);
    408                 vfs_node_put(mr_node);
    409                 free(mp);
    410                 async_answer_0(rid, EBUSY);
    411                 return;
    412         }
    413 
    414         if (str_cmp(mp, "/") == 0) {
    415 
    416                 /*
    417                  * Unmounting the root file system.
    418                  *
    419                  * In this case, there is no mount point node and we send
    420                  * VFS_OUT_UNMOUNTED directly to the mounted file system.
    421                  */
    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);
    428                 if (rc != EOK) {
    429                         fibril_rwlock_write_unlock(&namespace_rwlock);
    430                         vfs_node_put(mr_node);
    431                         async_answer_0(rid, rc);
    432                         return;
    433                 }
    434                 rootfs.fs_handle = 0;
    435                 rootfs.devmap_handle = 0;
    436         } else {
    437 
    438                 /*
    439                  * Unmounting a non-root file system.
    440                  *
    441                  * We have a regular mount point node representing the parent
    442                  * file system, so we delegate the operation to it.
    443                  */
    444 
    445                 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    446                 free(mp);
    447                 if (rc != EOK) {
    448                         fibril_rwlock_write_unlock(&namespace_rwlock);
    449                         vfs_node_put(mr_node);
    450                         async_answer_0(rid, rc);
    451                         return;
    452                 }
    453                 vfs_node_t *mp_node = vfs_node_get(&mp_res);
    454                 if (!mp_node) {
    455                         fibril_rwlock_write_unlock(&namespace_rwlock);
    456                         vfs_node_put(mr_node);
    457                         async_answer_0(rid, ENOMEM);
    458                         return;
    459                 }
    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);
    465                 if (rc != EOK) {
    466                         fibril_rwlock_write_unlock(&namespace_rwlock);
    467                         vfs_node_put(mp_node);
    468                         vfs_node_put(mr_node);
    469                         async_answer_0(rid, rc);
    470                         return;
    471                 }
    472 
    473                 /* Drop the reference we got above. */
    474                 vfs_node_put(mp_node);
    475                 /* Drop the reference from when the file system was mounted. */
    476                 vfs_node_put(mp_node);
    477         }
    478 
    479 
    480         /*
    481          * All went well, the mounted file system was successfully unmounted.
    482          * The only thing left is to forget the unmounted root VFS node.
    483          */
    484         vfs_node_forget(mr_node);
    485 
    486         fibril_rwlock_write_unlock(&namespace_rwlock);
    487         async_answer_0(rid, EOK);
    488 }
    489 
    490431void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    491432{
     433        if (!vfs_files_init()) {
     434                ipc_answer_0(rid, ENOMEM);
     435                return;
     436        }
     437       
    492438        /*
    493439         * The POSIX interface is open(path, oflag, mode).
     
    501447        int oflag = IPC_GET_ARG2(*request);
    502448        int mode = IPC_GET_ARG3(*request);
     449        size_t len;
    503450
    504451        /* Ignore mode for now. */
     
    507454        /*
    508455         * Make sure that we are called with exactly one of L_FILE and
    509          * L_DIRECTORY. Make sure that the user does not pass L_OPEN,
    510          * L_ROOT or L_MP.
     456         * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
    511457         */
    512458        if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
    513459            ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
    514             (lflag & (L_OPEN | L_ROOT | L_MP))) {
    515                 async_answer_0(rid, EINVAL);
     460            ((lflag & L_OPEN) != 0)) {
     461                ipc_answer_0(rid, EINVAL);
    516462                return;
    517463        }
     
    522468                lflag |= L_EXCLUSIVE;
    523469       
    524         char *path;
    525         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    526         if (rc != EOK) {
    527                 async_answer_0(rid, rc);
    528                 return;
    529         }
     470        ipc_callid_t callid;
     471        if (!ipc_data_write_receive(&callid, &len)) {
     472                ipc_answer_0(callid, EINVAL);
     473                ipc_answer_0(rid, EINVAL);
     474                return;
     475        }
     476       
     477        char *path = malloc(len + 1);
     478        if (!path) {
     479                ipc_answer_0(callid, ENOMEM);
     480                ipc_answer_0(rid, ENOMEM);
     481                return;
     482        }
     483       
     484        int rc;
     485        if ((rc = ipc_data_write_finalize(callid, path, len))) {
     486                ipc_answer_0(rid, rc);
     487                free(path);
     488                return;
     489        }
     490        path[len] = '\0';
    530491       
    531492        /*
     
    547508                else
    548509                        fibril_rwlock_read_unlock(&namespace_rwlock);
    549                 async_answer_0(rid, rc);
     510                ipc_answer_0(rid, rc);
    550511                free(path);
    551512                return;
     
    566527                if (node->size) {
    567528                        rc = vfs_truncate_internal(node->fs_handle,
    568                             node->devmap_handle, node->index, 0);
     529                            node->dev_handle, node->index, 0);
    569530                        if (rc) {
    570531                                fibril_rwlock_write_unlock(&node->contents_rwlock);
    571532                                vfs_node_put(node);
    572                                 async_answer_0(rid, rc);
     533                                ipc_answer_0(rid, rc);
    573534                                return;
    574535                        }
     
    582543         * structure.
    583544         */
    584         int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
     545        int fd = vfs_fd_alloc();
    585546        if (fd < 0) {
    586547                vfs_node_put(node);
    587                 async_answer_0(rid, fd);
     548                ipc_answer_0(rid, fd);
    588549                return;
    589550        }
    590551        vfs_file_t *file = vfs_file_get(fd);
    591         assert(file);
    592552        file->node = node;
    593553        if (oflag & O_APPEND)
     
    603563        vfs_node_addref(node);
    604564        vfs_node_put(node);
    605         vfs_file_put(file);
    606565       
    607566        /* Success! Return the new file descriptor to the client. */
    608         async_answer_1(rid, EOK, fd);
     567        ipc_answer_1(rid, EOK, fd);
    609568}
    610569
     
    613572        // FIXME: check for sanity of the supplied fs, dev and index
    614573       
     574        if (!vfs_files_init()) {
     575                ipc_answer_0(rid, ENOMEM);
     576                return;
     577        }
     578       
    615579        /*
    616580         * The interface is open_node(fs, dev, index, oflag).
     
    619583       
    620584        lr.triplet.fs_handle = IPC_GET_ARG1(*request);
    621         lr.triplet.devmap_handle = IPC_GET_ARG2(*request);
     585        lr.triplet.dev_handle = IPC_GET_ARG2(*request);
    622586        lr.triplet.index = IPC_GET_ARG3(*request);
    623587        int oflag = IPC_GET_ARG4(*request);
     
    628592        if (rc != EOK) {
    629593                fibril_rwlock_read_unlock(&namespace_rwlock);
    630                 async_answer_0(rid, rc);
     594                ipc_answer_0(rid, rc);
    631595                return;
    632596        }
     
    640604                if (node->size) {
    641605                        rc = vfs_truncate_internal(node->fs_handle,
    642                             node->devmap_handle, node->index, 0);
     606                            node->dev_handle, node->index, 0);
    643607                        if (rc) {
    644608                                fibril_rwlock_write_unlock(&node->contents_rwlock);
    645609                                vfs_node_put(node);
    646                                 async_answer_0(rid, rc);
     610                                ipc_answer_0(rid, rc);
    647611                                return;
    648612                        }
     
    656620         * structure.
    657621         */
    658         int fd = vfs_fd_alloc((oflag & O_DESC) != 0);
     622        int fd = vfs_fd_alloc();
    659623        if (fd < 0) {
    660624                vfs_node_put(node);
    661                 async_answer_0(rid, fd);
     625                ipc_answer_0(rid, fd);
    662626                return;
    663627        }
     
    676640        vfs_node_addref(node);
    677641        vfs_node_put(node);
    678         vfs_file_put(file);
    679642       
    680643        /* Success! Return the new file descriptor to the client. */
    681         async_answer_1(rid, EOK, fd);
     644        ipc_answer_1(rid, EOK, fd);
    682645}
    683646
     
    689652        vfs_file_t *file = vfs_file_get(fd);
    690653        if (!file) {
    691                 async_answer_0(rid, ENOENT);
     654                ipc_answer_0(rid, ENOENT);
    692655                return;
    693656        }
     
    703666        aid_t msg;
    704667        ipc_call_t answer;
    705         msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle,
     668        msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle,
    706669            file->node->index, &answer);
    707670
    708671        /* Wait for reply from the FS server. */
    709         sysarg_t rc;
     672        ipcarg_t rc;
    710673        async_wait_for(msg, &rc);
    711674       
    712         vfs_release_phone(file->node->fs_handle, fs_phone);
     675        vfs_release_phone(fs_phone);
    713676        fibril_mutex_unlock(&file->lock);
    714 
    715         vfs_file_put(file);
    716         async_answer_0(rid, rc);
    717 }
    718 
    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;
     677       
     678        ipc_answer_0(rid, rc);
    752679}
    753680
     
    759686        vfs_file_t *file = vfs_file_get(fd);
    760687        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);
    771         async_answer_0(rid, ret);
     688                ipc_answer_0(rid, ENOENT);
     689                return;
     690        }
     691       
     692        /*
     693         * Lock the open file structure so that no other thread can manipulate
     694         * the same open file at a time.
     695         */
     696        fibril_mutex_lock(&file->lock);
     697        int fs_phone = vfs_grab_phone(file->node->fs_handle);
     698       
     699        /* Make a VFS_OUT_CLOSE request at the destination FS server. */
     700        aid_t msg;
     701        ipc_call_t answer;
     702        msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
     703            file->node->index, &answer);
     704
     705        /* Wait for reply from the FS server. */
     706        ipcarg_t rc;
     707        async_wait_for(msg, &rc);
     708
     709        vfs_release_phone(fs_phone);
     710        fibril_mutex_unlock(&file->lock);
     711       
     712        int retval = IPC_GET_ARG1(answer);
     713        if (retval != EOK)
     714                ipc_answer_0(rid, retval);
     715       
     716        retval = vfs_fd_free(fd);
     717        ipc_answer_0(rid, retval);
    772718}
    773719
    774720static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    775721{
    776         vfs_info_t *vi;
    777722
    778723        /*
     
    791736        vfs_file_t *file = vfs_file_get(fd);
    792737        if (!file) {
    793                 async_answer_0(rid, ENOENT);
     738                ipc_answer_0(rid, ENOENT);
     739                return;
     740        }
     741       
     742        /*
     743         * Now we need to receive a call with client's
     744         * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.
     745         */
     746        ipc_callid_t callid;
     747        int res;
     748        if (read)
     749                res = ipc_data_read_receive(&callid, NULL);
     750        else
     751                res = ipc_data_write_receive(&callid, NULL);
     752        if (!res) {
     753                ipc_answer_0(callid, EINVAL);
     754                ipc_answer_0(rid, EINVAL);
    794755                return;
    795756        }
     
    801762        fibril_mutex_lock(&file->lock);
    802763
    803         vi = fs_handle_to_info(file->node->fs_handle);
    804         assert(vi);
    805 
    806764        /*
    807765         * Lock the file's node so that no other client can read/write to it at
    808          * the same time unless the FS supports concurrent reads/writes and its
    809          * write implementation does not modify the file size.
    810          */
    811         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     766         * the same time.
     767         */
     768        if (read)
    812769                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    813770        else
     
    823780        }
    824781       
    825         int fs_phone = vfs_grab_phone(file->node->fs_handle);
    826        
    827         /*
    828          * Make a VFS_READ/VFS_WRITE request at the destination FS server
    829          * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
     782        int fs_phone = vfs_grab_phone(file->node->fs_handle);   
     783       
     784        /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
     785        aid_t msg;
     786        ipc_call_t answer;
     787        if (!read && file->append)
     788                file->pos = file->node->size;
     789        msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
     790            file->node->dev_handle, file->node->index, file->pos, &answer);
     791       
     792        /*
     793         * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
    830794         * destination FS server. The call will be routed as if sent by
    831795         * ourselves. Note that call arguments are immutable in this case so we
    832796         * don't have to bother.
    833797         */
    834         sysarg_t rc;
    835         ipc_call_t answer;
    836         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);
    840         } else {
    841                 if (file->append)
    842                         file->pos = file->node->size;
    843                
    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);
     798        ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     799
     800        /* Wait for reply from the FS server. */
     801        ipcarg_t rc;
     802        async_wait_for(msg, &rc);
     803       
     804        vfs_release_phone(fs_phone);
    850805       
    851806        size_t bytes = IPC_GET_ARG1(answer);
    852        
     807
    853808        if (file->node->type == VFS_NODE_DIRECTORY)
    854809                fibril_rwlock_read_unlock(&namespace_rwlock);
    855810       
    856811        /* Unlock the VFS node. */
    857         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     812        if (read)
    858813                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    859814        else {
     
    868823                file->pos += bytes;
    869824        fibril_mutex_unlock(&file->lock);
    870         vfs_file_put(file);     
    871 
     825       
    872826        /*
    873827         * FS server's reply is the final result of the whole operation we
    874828         * return to the client.
    875829         */
    876         async_answer_1(rid, rc, bytes);
     830        ipc_answer_1(rid, rc, bytes);
    877831}
    878832
     
    890844{
    891845        int fd = (int) IPC_GET_ARG1(*request);
    892         off64_t off = (off64_t) MERGE_LOUP32(IPC_GET_ARG2(*request),
    893             IPC_GET_ARG3(*request));
    894         int whence = (int) IPC_GET_ARG4(*request);
    895        
     846        off_t off = (off_t) IPC_GET_ARG2(*request);
     847        int whence = (int) IPC_GET_ARG3(*request);
     848
     849
    896850        /* Lookup the file structure corresponding to the file descriptor. */
    897851        vfs_file_t *file = vfs_file_get(fd);
    898852        if (!file) {
    899                 async_answer_0(rid, ENOENT);
    900                 return;
    901         }
    902        
     853                ipc_answer_0(rid, ENOENT);
     854                return;
     855        }
     856
     857        off_t newpos;
    903858        fibril_mutex_lock(&file->lock);
    904        
    905         off64_t newoff;
    906         switch (whence) {
    907         case SEEK_SET:
    908                 if (off >= 0) {
    909                         file->pos = (aoff64_t) off;
     859        if (whence == SEEK_SET) {
     860                file->pos = off;
     861                fibril_mutex_unlock(&file->lock);
     862                ipc_answer_1(rid, EOK, off);
     863                return;
     864        }
     865        if (whence == SEEK_CUR) {
     866                if (file->pos + off < file->pos) {
    910867                        fibril_mutex_unlock(&file->lock);
    911                         vfs_file_put(file);
    912                         async_answer_1(rid, EOK, off);
     868                        ipc_answer_0(rid, EOVERFLOW);
    913869                        return;
    914870                }
    915                 break;
    916         case SEEK_CUR:
    917                 if ((off >= 0) && (file->pos + off < file->pos)) {
     871                file->pos += off;
     872                newpos = file->pos;
     873                fibril_mutex_unlock(&file->lock);
     874                ipc_answer_1(rid, EOK, newpos);
     875                return;
     876        }
     877        if (whence == SEEK_END) {
     878                fibril_rwlock_read_lock(&file->node->contents_rwlock);
     879                size_t size = file->node->size;
     880                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
     881                if (size + off < size) {
    918882                        fibril_mutex_unlock(&file->lock);
    919                         vfs_file_put(file);
    920                         async_answer_0(rid, EOVERFLOW);
     883                        ipc_answer_0(rid, EOVERFLOW);
    921884                        return;
    922885                }
    923                
    924                 if ((off < 0) && (file->pos < (aoff64_t) -off)) {
    925                         fibril_mutex_unlock(&file->lock);
    926                         vfs_file_put(file);
    927                         async_answer_0(rid, EOVERFLOW);
    928                         return;
    929                 }
    930                
    931                 file->pos += off;
    932                 newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
    933                
     886                newpos = size + off;
    934887                fibril_mutex_unlock(&file->lock);
    935                 vfs_file_put(file);
    936                 async_answer_2(rid, EOK, LOWER32(newoff),
    937                     UPPER32(newoff));
    938                 return;
    939         case SEEK_END:
    940                 fibril_rwlock_read_lock(&file->node->contents_rwlock);
    941                 aoff64_t size = file->node->size;
    942                
    943                 if ((off >= 0) && (size + off < size)) {
    944                         fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    945                         fibril_mutex_unlock(&file->lock);
    946                         vfs_file_put(file);
    947                         async_answer_0(rid, EOVERFLOW);
    948                         return;
    949                 }
    950                
    951                 if ((off < 0) && (size < (aoff64_t) -off)) {
    952                         fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    953                         fibril_mutex_unlock(&file->lock);
    954                         vfs_file_put(file);
    955                         async_answer_0(rid, EOVERFLOW);
    956                         return;
    957                 }
    958                
    959                 file->pos = size + off;
    960                 newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
    961                
    962                 fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    963                 fibril_mutex_unlock(&file->lock);
    964                 vfs_file_put(file);
    965                 async_answer_2(rid, EOK, LOWER32(newoff), UPPER32(newoff));
    966                 return;
    967         }
    968        
     888                ipc_answer_1(rid, EOK, newpos);
     889                return;
     890        }
    969891        fibril_mutex_unlock(&file->lock);
    970         vfs_file_put(file);
    971         async_answer_0(rid, EINVAL);
    972 }
    973 
    974 int vfs_truncate_internal(fs_handle_t fs_handle, devmap_handle_t devmap_handle,
    975     fs_index_t index, aoff64_t size)
    976 {
    977         sysarg_t rc;
     892        ipc_answer_0(rid, EINVAL);
     893}
     894
     895int
     896vfs_truncate_internal(fs_handle_t fs_handle, dev_handle_t dev_handle,
     897    fs_index_t index, size_t size)
     898{
     899        ipcarg_t rc;
    978900        int fs_phone;
    979901       
    980902        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);
     903        rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
     904            (ipcarg_t)index, (ipcarg_t)size);
     905        vfs_release_phone(fs_phone);
    984906        return (int)rc;
    985907}
     
    988910{
    989911        int fd = IPC_GET_ARG1(*request);
    990         aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(*request),
    991             IPC_GET_ARG3(*request));
     912        size_t size = IPC_GET_ARG2(*request);
    992913        int rc;
    993914
    994915        vfs_file_t *file = vfs_file_get(fd);
    995916        if (!file) {
    996                 async_answer_0(rid, ENOENT);
     917                ipc_answer_0(rid, ENOENT);
    997918                return;
    998919        }
     
    1001922        fibril_rwlock_write_lock(&file->node->contents_rwlock);
    1002923        rc = vfs_truncate_internal(file->node->fs_handle,
    1003             file->node->devmap_handle, file->node->index, size);
     924            file->node->dev_handle, file->node->index, size);
    1004925        if (rc == EOK)
    1005926                file->node->size = size;
     
    1007928
    1008929        fibril_mutex_unlock(&file->lock);
    1009         vfs_file_put(file);
    1010         async_answer_0(rid, (sysarg_t)rc);
     930        ipc_answer_0(rid, (ipcarg_t)rc);
    1011931}
    1012932
     
    1014934{
    1015935        int fd = IPC_GET_ARG1(*request);
    1016         sysarg_t rc;
     936        size_t size = IPC_GET_ARG2(*request);
     937        ipcarg_t rc;
    1017938
    1018939        vfs_file_t *file = vfs_file_get(fd);
    1019940        if (!file) {
    1020                 async_answer_0(rid, ENOENT);
     941                ipc_answer_0(rid, ENOENT);
    1021942                return;
    1022943        }
    1023944
    1024945        ipc_callid_t callid;
    1025         if (!async_data_read_receive(&callid, NULL)) {
    1026                 vfs_file_put(file);
    1027                 async_answer_0(callid, EINVAL);
    1028                 async_answer_0(rid, EINVAL);
     946        if (!ipc_data_read_receive(&callid, NULL)) {
     947                ipc_answer_0(callid, EINVAL);
     948                ipc_answer_0(rid, EINVAL);
    1029949                return;
    1030950        }
     
    1035955       
    1036956        aid_t msg;
    1037         msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle,
     957        msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
    1038958            file->node->index, true, NULL);
    1039         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     959        ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1040960        async_wait_for(msg, &rc);
    1041         vfs_release_phone(file->node->fs_handle, fs_phone);
     961        vfs_release_phone(fs_phone);
    1042962
    1043963        fibril_mutex_unlock(&file->lock);
    1044         vfs_file_put(file);
    1045         async_answer_0(rid, rc);
     964        ipc_answer_0(rid, rc);
    1046965}
    1047966
    1048967void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
    1049968{
    1050         char *path;
    1051         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1052         if (rc != EOK) {
    1053                 async_answer_0(rid, rc);
    1054                 return;
    1055         }
    1056        
     969        size_t len;
    1057970        ipc_callid_t callid;
    1058         if (!async_data_read_receive(&callid, NULL)) {
     971
     972        if (!ipc_data_write_receive(&callid, &len)) {
     973                ipc_answer_0(callid, EINVAL);
     974                ipc_answer_0(rid, EINVAL);
     975                return;
     976        }
     977        char *path = malloc(len + 1);
     978        if (!path) {
     979                ipc_answer_0(callid, ENOMEM);
     980                ipc_answer_0(rid, ENOMEM);
     981                return;
     982        }
     983        int rc;
     984        if ((rc = ipc_data_write_finalize(callid, path, len))) {
     985                ipc_answer_0(rid, rc);
    1059986                free(path);
    1060                 async_answer_0(callid, EINVAL);
    1061                 async_answer_0(rid, EINVAL);
     987                return;
     988        }
     989        path[len] = '\0';
     990
     991        if (!ipc_data_read_receive(&callid, NULL)) {
     992                free(path);
     993                ipc_answer_0(callid, EINVAL);
     994                ipc_answer_0(rid, EINVAL);
    1062995                return;
    1063996        }
     
    10691002        if (rc != EOK) {
    10701003                fibril_rwlock_read_unlock(&namespace_rwlock);
    1071                 async_answer_0(callid, rc);
    1072                 async_answer_0(rid, rc);
     1004                ipc_answer_0(callid, rc);
     1005                ipc_answer_0(rid, rc);
    10731006                return;
    10741007        }
     
    10761009        if (!node) {
    10771010                fibril_rwlock_read_unlock(&namespace_rwlock);
    1078                 async_answer_0(callid, ENOMEM);
    1079                 async_answer_0(rid, ENOMEM);
     1011                ipc_answer_0(callid, ENOMEM);
     1012                ipc_answer_0(rid, ENOMEM);
    10801013                return;
    10811014        }
     
    10851018        int fs_phone = vfs_grab_phone(node->fs_handle);
    10861019        aid_t msg;
    1087         msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
     1020        msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle,
    10881021            node->index, false, NULL);
    1089         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    1090        
    1091         sysarg_t rv;
     1022        ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1023       
     1024        ipcarg_t rv;
    10921025        async_wait_for(msg, &rv);
    1093         vfs_release_phone(node->fs_handle, fs_phone);
    1094 
    1095         async_answer_0(rid, rv);
     1026        vfs_release_phone(fs_phone);
     1027
     1028        ipc_answer_0(rid, rv);
    10961029
    10971030        vfs_node_put(node);
     
    11011034{
    11021035        int mode = IPC_GET_ARG1(*request);
    1103        
    1104         char *path;
    1105         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1106         if (rc != EOK) {
    1107                 async_answer_0(rid, rc);
    1108                 return;
    1109         }
    1110        
     1036
     1037        size_t len;
     1038        ipc_callid_t callid;
     1039
     1040        if (!ipc_data_write_receive(&callid, &len)) {
     1041                ipc_answer_0(callid, EINVAL);
     1042                ipc_answer_0(rid, EINVAL);
     1043                return;
     1044        }
     1045        char *path = malloc(len + 1);
     1046        if (!path) {
     1047                ipc_answer_0(callid, ENOMEM);
     1048                ipc_answer_0(rid, ENOMEM);
     1049                return;
     1050        }
     1051        int rc;
     1052        if ((rc = ipc_data_write_finalize(callid, path, len))) {
     1053                ipc_answer_0(rid, rc);
     1054                free(path);
     1055                return;
     1056        }
     1057        path[len] = '\0';
     1058
    11111059        /* Ignore mode for now. */
    11121060        (void) mode;
     
    11171065        fibril_rwlock_write_unlock(&namespace_rwlock);
    11181066        free(path);
    1119         async_answer_0(rid, rc);
     1067        ipc_answer_0(rid, rc);
    11201068}
    11211069
     
    11231071{
    11241072        int lflag = IPC_GET_ARG1(*request);
    1125        
    1126         char *path;
    1127         int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
    1128         if (rc != EOK) {
    1129                 async_answer_0(rid, rc);
    1130                 return;
    1131         }
     1073
     1074        size_t len;
     1075        ipc_callid_t callid;
     1076
     1077        if (!ipc_data_write_receive(&callid, &len)) {
     1078                ipc_answer_0(callid, EINVAL);
     1079                ipc_answer_0(rid, EINVAL);
     1080                return;
     1081        }
     1082        char *path = malloc(len + 1);
     1083        if (!path) {
     1084                ipc_answer_0(callid, ENOMEM);
     1085                ipc_answer_0(rid, ENOMEM);
     1086                return;
     1087        }
     1088        int rc;
     1089        if ((rc = ipc_data_write_finalize(callid, path, len))) {
     1090                ipc_answer_0(rid, rc);
     1091                free(path);
     1092                return;
     1093        }
     1094        path[len] = '\0';
    11321095       
    11331096        fibril_rwlock_write_lock(&namespace_rwlock);
     
    11381101        if (rc != EOK) {
    11391102                fibril_rwlock_write_unlock(&namespace_rwlock);
    1140                 async_answer_0(rid, rc);
     1103                ipc_answer_0(rid, rc);
    11411104                return;
    11421105        }
     
    11531116        fibril_rwlock_write_unlock(&namespace_rwlock);
    11541117        vfs_node_put(node);
    1155         async_answer_0(rid, EOK);
     1118        ipc_answer_0(rid, EOK);
    11561119}
    11571120
    11581121void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
    11591122{
     1123        size_t olen, nlen;
     1124        ipc_callid_t callid;
     1125        int rc;
     1126
    11601127        /* Retrieve the old path. */
    1161         char *old;
    1162         int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL);
    1163         if (rc != EOK) {
    1164                 async_answer_0(rid, rc);
    1165                 return;
    1166         }
     1128        if (!ipc_data_write_receive(&callid, &olen)) {
     1129                ipc_answer_0(callid, EINVAL);
     1130                ipc_answer_0(rid, EINVAL);
     1131                return;
     1132        }
     1133        char *old = malloc(olen + 1);
     1134        if (!old) {
     1135                ipc_answer_0(callid, ENOMEM);
     1136                ipc_answer_0(rid, ENOMEM);
     1137                return;
     1138        }
     1139        if ((rc = ipc_data_write_finalize(callid, old, olen))) {
     1140                ipc_answer_0(rid, rc);
     1141                free(old);
     1142                return;
     1143        }
     1144        old[olen] = '\0';
    11671145       
    11681146        /* Retrieve the new path. */
    1169         char *new;
    1170         rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL);
    1171         if (rc != EOK) {
     1147        if (!ipc_data_write_receive(&callid, &nlen)) {
     1148                ipc_answer_0(callid, EINVAL);
     1149                ipc_answer_0(rid, EINVAL);
    11721150                free(old);
    1173                 async_answer_0(rid, rc);
    1174                 return;
    1175         }
    1176        
    1177         size_t olen;
    1178         size_t nlen;
     1151                return;
     1152        }
     1153        char *new = malloc(nlen + 1);
     1154        if (!new) {
     1155                ipc_answer_0(callid, ENOMEM);
     1156                ipc_answer_0(rid, ENOMEM);
     1157                free(old);
     1158                return;
     1159        }
     1160        if ((rc = ipc_data_write_finalize(callid, new, nlen))) {
     1161                ipc_answer_0(rid, rc);
     1162                free(old);
     1163                free(new);
     1164                return;
     1165        }
     1166        new[nlen] = '\0';
     1167
    11791168        char *oldc = canonify(old, &olen);
    11801169        char *newc = canonify(new, &nlen);
    1181        
    1182         if ((!oldc) || (!newc)) {
    1183                 async_answer_0(rid, EINVAL);
     1170        if (!oldc || !newc) {
     1171                ipc_answer_0(rid, EINVAL);
    11841172                free(old);
    11851173                free(new);
    11861174                return;
    11871175        }
    1188        
    11891176        oldc[olen] = '\0';
    11901177        newc[nlen] = '\0';
    1191        
    11921178        if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
    11931179            ((newc[str_length(oldc)] == '/') ||
     
    12001186                 * - oldc and newc are equal.
    12011187                 */
    1202                 async_answer_0(rid, EINVAL);
     1188                ipc_answer_0(rid, EINVAL);
    12031189                free(old);
    12041190                free(new);
     
    12101196        vfs_lookup_res_t new_par_lr;
    12111197        fibril_rwlock_write_lock(&namespace_rwlock);
    1212        
    12131198        /* Lookup the node belonging to the old file name. */
    12141199        rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
    12151200        if (rc != EOK) {
    12161201                fibril_rwlock_write_unlock(&namespace_rwlock);
    1217                 async_answer_0(rid, rc);
     1202                ipc_answer_0(rid, rc);
    12181203                free(old);
    12191204                free(new);
    12201205                return;
    12211206        }
    1222        
    12231207        vfs_node_t *old_node = vfs_node_get(&old_lr);
    12241208        if (!old_node) {
    12251209                fibril_rwlock_write_unlock(&namespace_rwlock);
    1226                 async_answer_0(rid, ENOMEM);
     1210                ipc_answer_0(rid, ENOMEM);
    12271211                free(old);
    12281212                free(new);
    12291213                return;
    12301214        }
    1231        
    12321215        /* Determine the path to the parent of the node with the new name. */
    12331216        char *parentc = str_dup(newc);
    12341217        if (!parentc) {
    12351218                fibril_rwlock_write_unlock(&namespace_rwlock);
    1236                 async_answer_0(rid, rc);
     1219                ipc_answer_0(rid, rc);
    12371220                free(old);
    12381221                free(new);
    12391222                return;
    12401223        }
    1241        
    12421224        char *lastsl = str_rchr(parentc + 1, '/');
    12431225        if (lastsl)
     
    12451227        else
    12461228                parentc[1] = '\0';
    1247        
    12481229        /* Lookup parent of the new file name. */
    12491230        rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
     
    12511232        if (rc != EOK) {
    12521233                fibril_rwlock_write_unlock(&namespace_rwlock);
    1253                 async_answer_0(rid, rc);
     1234                ipc_answer_0(rid, rc);
    12541235                free(old);
    12551236                free(new);
    12561237                return;
    12571238        }
    1258        
    12591239        /* Check whether linking to the same file system instance. */
    12601240        if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
    1261             (old_node->devmap_handle != new_par_lr.triplet.devmap_handle)) {
     1241            (old_node->dev_handle != new_par_lr.triplet.dev_handle)) {
    12621242                fibril_rwlock_write_unlock(&namespace_rwlock);
    1263                 async_answer_0(rid, EXDEV);     /* different file systems */
     1243                ipc_answer_0(rid, EXDEV);       /* different file systems */
    12641244                free(old);
    12651245                free(new);
    12661246                return;
    12671247        }
    1268        
    12691248        /* Destroy the old link for the new name. */
    12701249        vfs_node_t *new_node = NULL;
    12711250        rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
    1272        
    12731251        switch (rc) {
    12741252        case ENOENT:
     
    12791257                if (!new_node) {
    12801258                        fibril_rwlock_write_unlock(&namespace_rwlock);
    1281                         async_answer_0(rid, ENOMEM);
     1259                        ipc_answer_0(rid, ENOMEM);
    12821260                        free(old);
    12831261                        free(new);
     
    12901268        default:
    12911269                fibril_rwlock_write_unlock(&namespace_rwlock);
    1292                 async_answer_0(rid, ENOTEMPTY);
     1270                ipc_answer_0(rid, ENOTEMPTY);
    12931271                free(old);
    12941272                free(new);
    12951273                return;
    12961274        }
    1297        
    12981275        /* Create the new link for the new name. */
    12991276        rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
     
    13021279                if (new_node)
    13031280                        vfs_node_put(new_node);
    1304                 async_answer_0(rid, rc);
     1281                ipc_answer_0(rid, rc);
    13051282                free(old);
    13061283                free(new);
    13071284                return;
    13081285        }
    1309        
    13101286        fibril_mutex_lock(&nodes_mutex);
    13111287        old_node->lnkcnt++;
    13121288        fibril_mutex_unlock(&nodes_mutex);
    1313        
    13141289        /* Destroy the link for the old name. */
    13151290        rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
     
    13191294                if (new_node)
    13201295                        vfs_node_put(new_node);
    1321                 async_answer_0(rid, rc);
     1296                ipc_answer_0(rid, rc);
    13221297                free(old);
    13231298                free(new);
    13241299                return;
    13251300        }
    1326        
    13271301        fibril_mutex_lock(&nodes_mutex);
    13281302        old_node->lnkcnt--;
     
    13301304        fibril_rwlock_write_unlock(&namespace_rwlock);
    13311305        vfs_node_put(old_node);
    1332        
    13331306        if (new_node)
    13341307                vfs_node_put(new_node);
    1335        
    13361308        free(old);
    13371309        free(new);
    1338         async_answer_0(rid, EOK);
    1339 }
    1340 
    1341 void vfs_dup(ipc_callid_t rid, ipc_call_t *request)
    1342 {
    1343         int oldfd = IPC_GET_ARG1(*request);
    1344         int newfd = IPC_GET_ARG2(*request);
    1345        
    1346         /* If the file descriptors are the same, do nothing. */
    1347         if (oldfd == newfd) {
    1348                 async_answer_1(rid, EOK, newfd);
    1349                 return;
    1350         }
    1351        
    1352         /* Lookup the file structure corresponding to oldfd. */
    1353         vfs_file_t *oldfile = vfs_file_get(oldfd);
    1354         if (!oldfile) {
    1355                 async_answer_0(rid, EBADF);
    1356                 return;
    1357         }
    1358        
    1359         /*
    1360          * Lock the open file structure so that no other thread can manipulate
    1361          * the same open file at a time.
    1362          */
    1363         fibril_mutex_lock(&oldfile->lock);
    1364        
    1365         /* Lookup an open file structure possibly corresponding to newfd. */
    1366         vfs_file_t *newfile = vfs_file_get(newfd);
    1367         if (newfile) {
    1368                 /* Close the originally opened file. */
    1369                 int ret = vfs_close_internal(newfile);
    1370                 if (ret != EOK) {
    1371                         fibril_mutex_unlock(&oldfile->lock);
    1372                         vfs_file_put(oldfile);
    1373                         vfs_file_put(newfile);
    1374                         async_answer_0(rid, ret);
    1375                         return;
    1376                 }
    1377                
    1378                 ret = vfs_fd_free(newfd);
    1379                 if (ret != EOK) {
    1380                         fibril_mutex_unlock(&oldfile->lock);
    1381                         vfs_file_put(oldfile);
    1382                         vfs_file_put(newfile);
    1383                         async_answer_0(rid, ret);
    1384                         return;
    1385                 }
    1386                 vfs_file_put(newfile);
    1387         }
    1388        
    1389         /* Assign the old file to newfd. */
    1390         int ret = vfs_fd_assign(oldfile, newfd);
    1391         fibril_mutex_unlock(&oldfile->lock);
    1392         vfs_file_put(oldfile);
    1393        
    1394         if (ret != EOK)
    1395                 async_answer_0(rid, ret);
    1396         else
    1397                 async_answer_1(rid, EOK, newfd);
     1310        ipc_answer_0(rid, EOK);
    13981311}
    13991312
Note: See TracChangeset for help on using the changeset viewer.