Changeset 79ae36dd in mainline for uspace/srv/vfs


Ignore:
Timestamp:
2011-06-08T19:01:55Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eff68e
Parents:
764d71e
Message:

new async framework with integrated exchange tracking

  • strict isolation between low-level IPC and high-level async framework with integrated exchange tracking
    • each IPC connection is represented by an async_sess_t structure
    • each IPC exchange is represented by an async_exch_t structure
    • exchange management is either based on atomic messages (EXCHANGE_ATOMIC), locking (EXCHANGE_SERIALIZE) or connection cloning (EXCHANGE_CLONE)
  • async_obsolete: temporary compatibility layer to keep old async clients working (several pieces of code are currently broken, but only non-essential functionality)
  • IPC_M_PHONE_HANGUP is now method no. 0 (for elegant boolean evaluation)
  • IPC_M_DEBUG_ALL has been renamed to IPC_M_DEBUG
  • IPC_M_PING has been removed (VFS protocol now has VFS_IN_PING)
  • console routines in libc have been rewritten for better abstraction
  • additional use for libc-private header files (FILE structure opaque to the client)
  • various cstyle changes (typos, indentation, missing externs in header files, improved comments, etc.)
Location:
uspace/srv/vfs
Files:
7 edited

Legend:

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

    r764d71e r79ae36dd  
    3737
    3838#include <ipc/services.h>
    39 #include <ipc/ns.h>
     39#include <ns.h>
    4040#include <async.h>
    4141#include <errno.h>
     
    5151static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
    5252{
    53         bool keep_on_going = true;
    54 
     53        bool cont = true;
     54       
    5555        /*
    5656         * The connection was opened via the IPC_CONNECT_ME_TO call.
     
    5959        async_answer_0(iid, EOK);
    6060       
    61         while (keep_on_going) {
     61        while (cont) {
    6262                ipc_call_t call;
    6363                ipc_callid_t callid = async_get_call(&call);
    6464               
     65                if (!IPC_GET_IMETHOD(call))
     66                        break;
     67               
    6568                switch (IPC_GET_IMETHOD(call)) {
    66                 case IPC_M_PHONE_HUNGUP:
    67                         keep_on_going = false;
    68                         break;
    6969                case VFS_IN_REGISTER:
    7070                        vfs_register(callid, &call);
    71                         keep_on_going = false;
     71                        cont = false;
    7272                        break;
    7373                case VFS_IN_MOUNT:
     
    123123                }
    124124        }
    125 
     125       
    126126        /*
    127127         * Open files for this client will be cleaned up when its last
  • uspace/srv/vfs/vfs.h

    r764d71e r79ae36dd  
    5353        vfs_info_t vfs_info;
    5454        fs_handle_t fs_handle;
    55         async_sess_t session;
     55        async_sess_t *sess;
    5656} fs_info_t;
    5757
     
    167167extern fibril_rwlock_t namespace_rwlock;
    168168
    169 extern int vfs_grab_phone(fs_handle_t);
    170 extern void vfs_release_phone(fs_handle_t, int);
     169extern async_exch_t *vfs_exchange_grab(fs_handle_t);
     170extern void vfs_exchange_release(async_exch_t *);
    171171
    172172extern fs_handle_t fs_name_to_handle(char *, bool);
  • uspace/srv/vfs/vfs_file.c

    r764d71e r79ae36dd  
    4545#include "vfs.h"
    4646
    47 #define VFS_DATA        ((vfs_client_data_t *) async_client_data_get())
     47#define VFS_DATA        ((vfs_client_data_t *) async_get_client_data())
    4848#define FILES           (VFS_DATA->files)
    4949
     
    110110static int vfs_file_close_remote(vfs_file_t *file)
    111111{
     112        assert(!file->refcnt);
     113       
     114        async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
     115       
    112116        ipc_call_t answer;
    113         aid_t msg;
     117        aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node->devmap_handle,
     118            file->node->index, &answer);
     119       
     120        vfs_exchange_release(exch);
     121       
    114122        sysarg_t rc;
    115         int phone;
    116 
    117         assert(!file->refcnt);
    118 
    119         phone = vfs_grab_phone(file->node->fs_handle);
    120         msg = async_send_2(phone, VFS_OUT_CLOSE, file->node->devmap_handle,
    121             file->node->index, &answer);
    122123        async_wait_for(msg, &rc);
    123         vfs_release_phone(file->node->fs_handle, phone);
    124 
     124       
    125125        return IPC_GET_ARG1(answer);
    126126}
    127 
    128127
    129128/** Increment reference count of VFS file structure.
  • uspace/srv/vfs/vfs_lookup.c

    r764d71e r79ae36dd  
    159159
    160160        ipc_call_t answer;
    161         int phone = vfs_grab_phone(root->fs_handle);
    162         aid_t req = async_send_5(phone, VFS_OUT_LOOKUP, (sysarg_t) first,
     161        async_exch_t *exch = vfs_exchange_grab(root->fs_handle);
     162        aid_t req = async_send_5(exch, VFS_OUT_LOOKUP, (sysarg_t) first,
    163163            (sysarg_t) (first + len - 1) % PLB_SIZE,
    164164            (sysarg_t) root->devmap_handle, (sysarg_t) lflag, (sysarg_t) index,
     
    167167        sysarg_t rc;
    168168        async_wait_for(req, &rc);
    169         vfs_release_phone(root->fs_handle, phone);
     169        vfs_exchange_release(exch);
    170170       
    171171        fibril_mutex_lock(&plb_mutex);
     
    208208int vfs_open_node_internal(vfs_lookup_res_t *result)
    209209{
    210         int phone = vfs_grab_phone(result->triplet.fs_handle);
     210        async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);
    211211       
    212212        ipc_call_t answer;
    213         aid_t req = async_send_2(phone, VFS_OUT_OPEN_NODE,
     213        aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,
    214214            (sysarg_t) result->triplet.devmap_handle,
    215215            (sysarg_t) result->triplet.index, &answer);
     
    217217        sysarg_t rc;
    218218        async_wait_for(req, &rc);
    219         vfs_release_phone(result->triplet.fs_handle, phone);
     219        vfs_exchange_release(exch);
    220220       
    221221        if (rc == EOK) {
  • uspace/srv/vfs/vfs_node.c

    r764d71e r79ae36dd  
    104104        bool free_vfs_node = false;
    105105        bool free_fs_node = false;
    106 
    107         fibril_mutex_lock(&nodes_mutex);
     106       
     107        fibril_mutex_lock(&nodes_mutex);
     108       
    108109        if (node->refcnt-- == 1) {
     110               
    109111                /*
    110112                 * We are dropping the last reference to this node.
    111113                 * Remove it from the VFS node hash table.
    112114                 */
     115               
    113116                unsigned long key[] = {
    114117                        [KEY_FS_HANDLE] = node->fs_handle,
     
    116119                        [KEY_INDEX] = node->index
    117120                };
     121               
    118122                hash_table_remove(&nodes, key, 3);
    119123                free_vfs_node = true;
     124               
    120125                if (!node->lnkcnt)
    121126                        free_fs_node = true;
    122127        }
    123         fibril_mutex_unlock(&nodes_mutex);
    124 
     128       
     129        fibril_mutex_unlock(&nodes_mutex);
     130       
    125131        if (free_fs_node) {
    126                 /*
     132               
     133                /*
    127134                 * The node is not visible in the file system namespace.
    128135                 * Free up its resources.
    129136                 */
    130                 int phone = vfs_grab_phone(node->fs_handle);
    131                 sysarg_t rc;
    132                 rc = async_req_2_0(phone, VFS_OUT_DESTROY,
    133                     (sysarg_t)node->devmap_handle, (sysarg_t)node->index);
     137               
     138                async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     139                sysarg_t rc = async_req_2_0(exch, VFS_OUT_DESTROY,
     140                    (sysarg_t) node->devmap_handle, (sysarg_t)node->index);
     141               
    134142                assert(rc == EOK);
    135                 vfs_release_phone(node->fs_handle, phone);
     143                vfs_exchange_release(exch);
    136144        }
     145       
    137146        if (free_vfs_node)
    138147                free(node);
  • uspace/srv/vfs/vfs_ops.c

    r764d71e r79ae36dd  
    7878        size_t rsize;
    7979        unsigned rlnkcnt;
     80        async_exch_t *exch;
    8081        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                         phone = vfs_grab_phone(fs_handle);
    126                         msg = async_send_1(phone, VFS_OUT_MOUNTED,
     125                        exch = vfs_exchange_grab(fs_handle);
     126                        msg = async_send_1(exch, VFS_OUT_MOUNTED,
    127127                            (sysarg_t) devmap_handle, &answer);
    128                         /* send the mount options */
    129                         rc = async_data_write_start(phone, (void *)opts,
     128                        /* Send the mount options */
     129                        rc = async_data_write_start(exch, (void *)opts,
    130130                            str_size(opts));
     131                        vfs_exchange_release(exch);
     132                       
    131133                        if (rc != EOK) {
    132134                                async_wait_for(msg, NULL);
    133                                 vfs_release_phone(fs_handle, phone);
    134135                                fibril_rwlock_write_unlock(&namespace_rwlock);
    135136                                async_answer_0(rid, rc);
     
    137138                        }
    138139                        async_wait_for(msg, &rc);
    139                         vfs_release_phone(fs_handle, phone);
    140140                       
    141141                        if (rc != EOK) {
     
    182182         */
    183183       
    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,
     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,
    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_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
    196         if (rc != EOK) {
     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);
    197200                async_wait_for(msg, NULL);
    198                 vfs_release_phone(fs_handle, mountee_phone);
    199                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     201               
    200202                /* Mount failed, drop reference to mp_node. */
    201203                if (mp_node)
    202204                        vfs_node_put(mp_node);
    203                 async_answer_0(rid, rc);
    204                 fibril_rwlock_write_unlock(&namespace_rwlock);
    205                 return;
    206         }
    207 
    208         vfs_release_phone(fs_handle, mountee_phone);
     205               
     206                async_answer_0(rid, rc);
     207                fibril_rwlock_write_unlock(&namespace_rwlock);
     208                return;
     209        }
    209210       
    210211        /* send the mount options */
    211         rc = async_data_write_start(phone, (void *)opts, str_size(opts));
    212         if (rc != EOK) {
     212        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     213        if (rc != EOK) {
     214                vfs_exchange_release(exch);
    213215                async_wait_for(msg, NULL);
    214                 vfs_release_phone(mp_res.triplet.fs_handle, phone);
     216               
    215217                /* Mount failed, drop reference to mp_node. */
    216218                if (mp_node)
    217219                        vfs_node_put(mp_node);
    218                 fibril_rwlock_write_unlock(&namespace_rwlock);
    219                 async_answer_0(rid, rc);
    220                 return;
    221         }
     220               
     221                fibril_rwlock_write_unlock(&namespace_rwlock);
     222                async_answer_0(rid, rc);
     223                return;
     224        }
     225       
     226        vfs_exchange_release(exch);
    222227        async_wait_for(msg, &rc);
    223         vfs_release_phone(mp_res.triplet.fs_handle, phone);
    224228       
    225229        if (rc == EOK) {
     
    227231                rsize = (size_t) IPC_GET_ARG2(answer);
    228232                rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
    229        
     233               
    230234                mr_res.triplet.fs_handle = fs_handle;
    231235                mr_res.triplet.devmap_handle = devmap_handle;
     
    234238                mr_res.lnkcnt = rlnkcnt;
    235239                mr_res.type = VFS_NODE_DIRECTORY;
    236        
     240               
    237241                /* Add reference to the mounted root. */
    238242                mr_node = vfs_node_get(&mr_res);
     
    243247                        vfs_node_put(mp_node);
    244248        }
    245 
     249       
    246250        async_answer_0(rid, rc);
    247251        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    303307       
    304308        /*
    305          * Wait for IPC_M_PING so that we can return an error if we don't know
     309         * Wait for VFS_IN_PING so that we can return an error if we don't know
    306310         * fs_name.
    307311         */
    308312        ipc_call_t data;
    309313        ipc_callid_t callid = async_get_call(&data);
    310         if (IPC_GET_IMETHOD(data) != IPC_M_PING) {
     314        if (IPC_GET_IMETHOD(data) != VFS_IN_PING) {
    311315                async_answer_0(callid, ENOTSUP);
    312316                async_answer_0(rid, ENOTSUP);
     
    358362        vfs_lookup_res_t mr_res;
    359363        vfs_node_t *mr_node;
    360         int phone;
    361 
     364        async_exch_t *exch;
     365       
    362366        /*
    363367         * Receive the mount point path.
     
    367371        if (rc != EOK)
    368372                async_answer_0(rid, rc);
    369 
     373       
    370374        /*
    371375         * Taking the namespace lock will do two things for us. First, it will
     
    395399                return;
    396400        }
    397 
     401       
    398402        /*
    399403         * Count the total number of references for the mounted file system. We
     
    411415                return;
    412416        }
    413 
     417       
    414418        if (str_cmp(mp, "/") == 0) {
    415 
     419               
    416420                /*
    417421                 * Unmounting the root file system.
     
    420424                 * VFS_OUT_UNMOUNTED directly to the mounted file system.
    421425                 */
    422 
     426               
    423427                free(mp);
    424                 phone = vfs_grab_phone(mr_node->fs_handle);
    425                 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
     428               
     429                exch = vfs_exchange_grab(mr_node->fs_handle);
     430                rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED,
    426431                    mr_node->devmap_handle);
    427                 vfs_release_phone(mr_node->fs_handle, phone);
     432                vfs_exchange_release(exch);
     433               
    428434                if (rc != EOK) {
    429435                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    432438                        return;
    433439                }
     440               
    434441                rootfs.fs_handle = 0;
    435442                rootfs.devmap_handle = 0;
    436443        } else {
    437 
     444               
    438445                /*
    439446                 * Unmounting a non-root file system.
     
    442449                 * file system, so we delegate the operation to it.
    443450                 */
    444 
     451               
    445452                rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL);
    446453                free(mp);
     
    451458                        return;
    452459                }
     460               
    453461                vfs_node_t *mp_node = vfs_node_get(&mp_res);
    454462                if (!mp_node) {
     
    458466                        return;
    459467                }
    460 
    461                 phone = vfs_grab_phone(mp_node->fs_handle);
    462                 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT,
     468               
     469                exch = vfs_exchange_grab(mp_node->fs_handle);
     470                rc = async_req_2_0(exch, VFS_OUT_UNMOUNT,
    463471                    mp_node->devmap_handle, mp_node->index);
    464                 vfs_release_phone(mp_node->fs_handle, phone);
     472                vfs_exchange_release(exch);
     473               
    465474                if (rc != EOK) {
    466475                        fibril_rwlock_write_unlock(&namespace_rwlock);
     
    470479                        return;
    471480                }
    472 
     481               
    473482                /* Drop the reference we got above. */
    474483                vfs_node_put(mp_node);
     
    476485                vfs_node_put(mp_node);
    477486        }
    478 
    479 
     487       
    480488        /*
    481489         * All went well, the mounted file system was successfully unmounted.
     
    483491         */
    484492        vfs_node_forget(mr_node);
    485 
     493       
    486494        fibril_rwlock_write_unlock(&namespace_rwlock);
    487495        async_answer_0(rid, EOK);
     
    698706         */
    699707        fibril_mutex_lock(&file->lock);
    700         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     708        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    701709       
    702710        /* Make a VFS_OUT_SYMC request at the destination FS server. */
    703711        aid_t msg;
    704712        ipc_call_t answer;
    705         msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->devmap_handle,
     713        msg = async_send_2(fs_exch, VFS_OUT_SYNC, file->node->devmap_handle,
    706714            file->node->index, &answer);
    707 
     715       
     716        vfs_exchange_release(fs_exch);
     717       
    708718        /* Wait for reply from the FS server. */
    709719        sysarg_t rc;
    710720        async_wait_for(msg, &rc);
    711721       
    712         vfs_release_phone(file->node->fs_handle, fs_phone);
    713722        fibril_mutex_unlock(&file->lock);
    714 
     723       
    715724        vfs_file_put(file);
    716725        async_answer_0(rid, rc);
     
    720729{
    721730        int fd = IPC_GET_ARG1(*request);
    722         int ret;
    723        
    724         ret = vfs_fd_free(fd);
     731        int ret = vfs_fd_free(fd);
    725732        async_answer_0(rid, ret);
    726733}
     
    728735static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    729736{
    730         vfs_info_t *vi;
    731 
    732737        /*
    733738         * The following code strongly depends on the fact that the files data
     
    739744         * open files supports parallel access!
    740745         */
    741 
     746       
    742747        int fd = IPC_GET_ARG1(*request);
    743748       
     
    754759         */
    755760        fibril_mutex_lock(&file->lock);
    756 
    757         vi = fs_handle_to_info(file->node->fs_handle);
    758         assert(vi);
    759 
     761       
     762        vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
     763        assert(fs_info);
     764       
    760765        /*
    761766         * Lock the file's node so that no other client can read/write to it at
     
    763768         * write implementation does not modify the file size.
    764769         */
    765         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     770        if ((read) ||
     771            ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
    766772                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    767773        else
    768774                fibril_rwlock_write_lock(&file->node->contents_rwlock);
    769 
     775       
    770776        if (file->node->type == VFS_NODE_DIRECTORY) {
    771777                /*
     
    777783        }
    778784       
    779         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     785        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    780786       
    781787        /*
     
    789795        ipc_call_t answer;
    790796        if (read) {
    791                 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ,
     797                rc = async_data_read_forward_3_1(fs_exch, VFS_OUT_READ,
    792798                    file->node->devmap_handle, file->node->index, file->pos,
    793799                    &answer);
     
    796802                        file->pos = file->node->size;
    797803               
    798                 rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE,
     804                rc = async_data_write_forward_3_1(fs_exch, VFS_OUT_WRITE,
    799805                    file->node->devmap_handle, file->node->index, file->pos,
    800806                    &answer);
    801807        }
    802808       
    803         vfs_release_phone(file->node->fs_handle, fs_phone);
     809        vfs_exchange_release(fs_exch);
    804810       
    805811        size_t bytes = IPC_GET_ARG1(answer);
     
    809815       
    810816        /* Unlock the VFS node. */
    811         if (read || (vi->concurrent_read_write && vi->write_retains_size))
     817        if ((read) ||
     818            ((fs_info->concurrent_read_write) && (fs_info->write_retains_size)))
    812819                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    813820        else {
     
    929936    fs_index_t index, aoff64_t size)
    930937{
    931         sysarg_t rc;
    932         int fs_phone;
    933        
    934         fs_phone = vfs_grab_phone(fs_handle);
    935         rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (sysarg_t) devmap_handle,
    936             (sysarg_t) index, LOWER32(size), UPPER32(size));
    937         vfs_release_phone(fs_handle, fs_phone);
    938         return (int)rc;
     938        async_exch_t *exch = vfs_exchange_grab(fs_handle);
     939        sysarg_t rc = async_req_4_0(exch, VFS_OUT_TRUNCATE,
     940            (sysarg_t) devmap_handle, (sysarg_t) index, LOWER32(size),
     941            UPPER32(size));
     942        vfs_exchange_release(exch);
     943       
     944        return (int) rc;
    939945}
    940946
     
    986992        fibril_mutex_lock(&file->lock);
    987993
    988         int fs_phone = vfs_grab_phone(file->node->fs_handle);
     994        async_exch_t *exch = vfs_exchange_grab(file->node->fs_handle);
    989995       
    990996        aid_t msg;
    991         msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->devmap_handle,
     997        msg = async_send_3(exch, VFS_OUT_STAT, file->node->devmap_handle,
    992998            file->node->index, true, NULL);
    993         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     999        async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1000       
     1001        vfs_exchange_release(exch);
     1002       
    9941003        async_wait_for(msg, &rc);
    995         vfs_release_phone(file->node->fs_handle, fs_phone);
    996 
     1004       
    9971005        fibril_mutex_unlock(&file->lock);
    9981006        vfs_file_put(file);
     
    10371045        fibril_rwlock_read_unlock(&namespace_rwlock);
    10381046
    1039         int fs_phone = vfs_grab_phone(node->fs_handle);
     1047        async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     1048       
    10401049        aid_t msg;
    1041         msg = async_send_3(fs_phone, VFS_OUT_STAT, node->devmap_handle,
     1050        msg = async_send_3(exch, VFS_OUT_STAT, node->devmap_handle,
    10421051            node->index, false, NULL);
    1043         async_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1052        async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1053       
     1054        vfs_exchange_release(exch);
    10441055       
    10451056        sysarg_t rv;
    10461057        async_wait_for(msg, &rv);
    1047         vfs_release_phone(node->fs_handle, fs_phone);
    10481058
    10491059        async_answer_0(rid, rv);
  • uspace/srv/vfs/vfs_register.c

    r764d71e r79ae36dd  
    6262/** Verify the VFS info structure.
    6363 *
    64  * @param info          Info structure to be verified.
    65  *
    66  * @return              Non-zero if the info structure is sane, zero otherwise.
     64 * @param info Info structure to be verified.
     65 *
     66 * @return Non-zero if the info structure is sane, zero otherwise.
     67 *
    6768 */
    6869static bool vfs_info_sane(vfs_info_t *info)
    6970{
    7071        int i;
    71 
     72       
    7273        /*
    7374         * Check if the name is non-empty and is composed solely of ASCII
     
    7879                return false;
    7980        }
     81       
    8082        for (i = 1; i < FS_NAME_MAXLEN; i++) {
    8183                if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
     
    9092                }
    9193        }
     94       
    9295        /*
    9396         * This check is not redundant. It ensures that the name is
     
    104107/** VFS_REGISTER protocol function.
    105108 *
    106  * @param rid           Hash of the call with the request.
    107  * @param request       Call structure with the request.
     109 * @param rid     Hash of the call with the request.
     110 * @param request Call structure with the request.
     111 *
    108112 */
    109113void vfs_register(ipc_callid_t rid, ipc_call_t *request)
    110114{
    111         int phone;
    112        
    113115        dprintf("Processing VFS_REGISTER request received from %p.\n",
    114116            request->in_phone_hash);
     
    174176         * which to forward VFS requests to it.
    175177         */
    176         ipc_call_t call;
    177         ipc_callid_t callid = async_get_call(&call);
    178         if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
    179                 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
     178        fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
     179        if (!fs_info->sess) {
     180                dprintf("Callback connection expected\n");
    180181                list_remove(&fs_info->fs_link);
    181182                fibril_mutex_unlock(&fs_head_lock);
    182183                free(fs_info);
    183                 async_answer_0(callid, EINVAL);
    184184                async_answer_0(rid, EINVAL);
    185185                return;
    186186        }
    187187       
    188         phone = IPC_GET_ARG5(call);
    189         async_session_create(&fs_info->session, phone, 0);
    190         async_answer_0(callid, EOK);
    191        
    192188        dprintf("Callback connection to FS created.\n");
    193189       
     
    197193       
    198194        size_t size;
     195        ipc_callid_t callid;
    199196        if (!async_share_in_receive(&callid, &size)) {
    200197                dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
    201198                list_remove(&fs_info->fs_link);
    202199                fibril_mutex_unlock(&fs_head_lock);
    203                 async_session_destroy(&fs_info->session);
    204                 async_hangup(phone);
     200                async_hangup(fs_info->sess);
    205201                free(fs_info);
    206202                async_answer_0(callid, EINVAL);
     
    216212                list_remove(&fs_info->fs_link);
    217213                fibril_mutex_unlock(&fs_head_lock);
    218                 async_session_destroy(&fs_info->session);
    219                 async_hangup(phone);
     214                async_hangup(fs_info->sess);
    220215                free(fs_info);
    221216                async_answer_0(callid, EINVAL);
     
    247242}
    248243
    249 /** For a given file system handle, implement policy for allocating a phone.
    250  *
    251  * @param handle        File system handle.
    252  *
    253  * @return              Phone over which a multi-call request can be safely
    254  *                      sent. Return 0 if no phone was found.
    255  */
    256 int vfs_grab_phone(fs_handle_t handle)
    257 {
     244/** Begin an exchange for a given file system handle
     245 *
     246 * @param handle File system handle.
     247 *
     248 * @return Exchange for a multi-call request.
     249 * @return NULL if no such file exists.
     250 *
     251 */
     252async_exch_t *vfs_exchange_grab(fs_handle_t handle)
     253{
     254        /*
     255         * For now, we don't try to be very clever and very fast.
     256         * We simply lookup the session in the fs_head list and
     257         * begin an exchange.
     258         */
     259        fibril_mutex_lock(&fs_head_lock);
     260       
    258261        link_t *cur;
    259         fs_info_t *fs;
    260         int phone;
    261 
    262         /*
    263          * For now, we don't try to be very clever and very fast.  We simply
    264          * lookup the phone in the fs_head list and duplicate it.  The duplicate
    265          * phone will be returned to the client and the client will use it for
    266          * communication.  In the future, we should cache the connections so
    267          * that they do not have to be reestablished over and over again.
    268          */
    269         fibril_mutex_lock(&fs_head_lock);
    270262        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    271                 fs = list_get_instance(cur, fs_info_t, fs_link);
     263                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
     264               
    272265                if (fs->fs_handle == handle) {
    273266                        fibril_mutex_unlock(&fs_head_lock);
    274                         phone = async_exchange_begin(&fs->session);
    275 
    276                         assert(phone > 0);
    277                         return phone;
     267                       
     268                        assert(fs->sess);
     269                        async_exch_t *exch = async_exchange_begin(fs->sess);
     270                       
     271                        assert(exch);
     272                        return exch;
    278273                }
    279274        }
     275       
    280276        fibril_mutex_unlock(&fs_head_lock);
    281         return 0;
    282 }
    283 
    284 /** Tell VFS that the phone is not needed anymore.
    285  *
    286  * @param phone         Phone to FS task.
    287  */
    288 void vfs_release_phone(fs_handle_t handle, int phone)
    289 {
    290         link_t *cur;
    291         fs_info_t *fs;
    292 
    293         fibril_mutex_lock(&fs_head_lock);
    294         for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    295                 fs = list_get_instance(cur, fs_info_t, fs_link);
    296                 if (fs->fs_handle == handle) {
    297                         fibril_mutex_unlock(&fs_head_lock);
    298                         async_exchange_end(&fs->session, phone);
    299                         return;
    300                 }
    301         }
    302         /* should not really get here */
    303         abort();
    304         fibril_mutex_unlock(&fs_head_lock);
     277       
     278        return NULL;
     279}
     280
     281/** End VFS server exchange.
     282 *
     283 * @param exch   VFS server exchange.
     284 *
     285 */
     286void vfs_exchange_release(async_exch_t *exch)
     287{
     288        async_exchange_end(exch);
    305289}
    306290
    307291/** Convert file system name to its handle.
    308292 *
    309  * @param name          File system name.
    310  * @param lock          If true, the function will lock and unlock the
    311  *                      fs_head_lock.
    312  *
    313  * @return              File system handle or zero if file system not found.
     293 * @param name File system name.
     294 * @param lock If true, the function will lock and unlock the
     295 *             fs_head_lock.
     296 *
     297 * @return File system handle or zero if file system not found.
     298 *
    314299 */
    315300fs_handle_t fs_name_to_handle(char *name, bool lock)
     
    319304        if (lock)
    320305                fibril_mutex_lock(&fs_head_lock);
     306       
    321307        link_t *cur;
    322308        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     
    327313                }
    328314        }
     315       
    329316        if (lock)
    330317                fibril_mutex_unlock(&fs_head_lock);
     318       
    331319        return handle;
    332320}
     
    334322/** Find the VFS info structure.
    335323 *
    336  * @param handle        FS handle for which the VFS info structure is sought.
    337  * @return              VFS info structure on success or NULL otherwise.
     324 * @param handle FS handle for which the VFS info structure is sought.
     325 *
     326 * @return VFS info structure on success or NULL otherwise.
     327 *
    338328 */
    339329vfs_info_t *fs_handle_to_info(fs_handle_t handle)
     
    341331        vfs_info_t *info = NULL;
    342332        link_t *cur;
    343 
     333       
    344334        fibril_mutex_lock(&fs_head_lock);
    345335        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     
    351341        }
    352342        fibril_mutex_unlock(&fs_head_lock);
    353 
     343       
    354344        return info;
    355345}
     
    357347/**
    358348 * @}
    359  */ 
     349 */
Note: See TracChangeset for help on using the changeset viewer.