Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/vfs/vfs.c

    r64d2b10 r96b02eb9  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
     2 * Copyright (c) 2008 Jakub Jermar 
    33 * All rights reserved.
    44 *
     
    4343#include <sys/stat.h>
    4444#include <sys/types.h>
     45#include <ipc/ipc.h>
    4546#include <ipc/services.h>
    46 #include <ipc/ns.h>
    4747#include <async.h>
    48 #include <fibril_synch.h>
     48#include <atomic.h>
     49#include <futex.h>
    4950#include <errno.h>
    50 #include <assert.h>
    5151#include <str.h>
    5252#include <devmap.h>
     
    5454#include <ipc/devmap.h>
    5555
    56 static async_sess_t vfs_session;
    57 
    58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    5956static int vfs_phone = -1;
    60 
    61 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     57static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
     58static futex_t cwd_futex = FUTEX_INITIALIZER;
    6259
    6360static int cwd_fd = -1;
     
    7067        char *ncwd_path_nc;
    7168
    72         fibril_mutex_lock(&cwd_mutex);
     69        futex_down(&cwd_futex);
    7370        size_t size = str_size(path);
    7471        if (*path != '/') {
    7572                if (!cwd_path) {
    76                         fibril_mutex_unlock(&cwd_mutex);
     73                        futex_up(&cwd_futex);
    7774                        return NULL;
    7875                }
    7976                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    8077                if (!ncwd_path_nc) {
    81                         fibril_mutex_unlock(&cwd_mutex);
     78                        futex_up(&cwd_futex);
    8279                        return NULL;
    8380                }
     
    8885                ncwd_path_nc = malloc(size + 1);
    8986                if (!ncwd_path_nc) {
    90                         fibril_mutex_unlock(&cwd_mutex);
     87                        futex_up(&cwd_futex);
    9188                        return NULL;
    9289                }
     
    9693        ncwd_path = canonify(ncwd_path_nc, retlen);
    9794        if (!ncwd_path) {
    98                 fibril_mutex_unlock(&cwd_mutex);
     95                futex_up(&cwd_futex);
    9996                free(ncwd_path_nc);
    10097                return NULL;
     
    108105        free(ncwd_path_nc);
    109106        if (!ncwd_path) {
    110                 fibril_mutex_unlock(&cwd_mutex);
     107                futex_up(&cwd_futex);
    111108                return NULL;
    112109        }
    113         fibril_mutex_unlock(&cwd_mutex);
     110        futex_up(&cwd_futex);
    114111        return ncwd_path;
    115112}
    116113
    117 /** Connect to VFS service and create session. */
    118114static void vfs_connect(void)
    119115{
    120116        while (vfs_phone < 0)
    121                 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    122        
    123         async_session_create(&vfs_session, vfs_phone, 0);
    124 }
    125 
    126 /** Start an async exchange on the VFS session.
    127  *
    128  * @return              New phone to be used during the exchange.
    129  */
    130 static int vfs_exchange_begin(void)
    131 {
    132         fibril_mutex_lock(&vfs_phone_mutex);
    133         if (vfs_phone < 0)
    134                 vfs_connect();
    135         fibril_mutex_unlock(&vfs_phone_mutex);
    136 
    137         return async_exchange_begin(&vfs_session);
    138 }
    139 
    140 /** End an async exchange on the VFS session.
    141  *
    142  * @param phone         Phone used during the exchange.
    143  */
    144 static void vfs_exchange_end(int phone)
    145 {
    146         async_exchange_end(&vfs_session, phone);
     117                vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
    147118}
    148119
     
    183154        }
    184155       
    185         int vfs_phone = vfs_exchange_begin();
    186 
     156        futex_down(&vfs_phone_futex);
     157        async_serialize_start();
     158        vfs_connect();
     159       
    187160        sysarg_t rc_orig;
    188161        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    189162        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    190163        if (rc != EOK) {
    191                 vfs_exchange_end(vfs_phone);
     164                async_wait_for(req, &rc_orig);
     165                async_serialize_end();
     166                futex_up(&vfs_phone_futex);
    192167                free(mpa);
    193                 async_wait_for(req, &rc_orig);
    194168               
    195169                if (null_id != -1)
     
    204178        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    205179        if (rc != EOK) {
    206                 vfs_exchange_end(vfs_phone);
     180                async_wait_for(req, &rc_orig);
     181                async_serialize_end();
     182                futex_up(&vfs_phone_futex);
    207183                free(mpa);
    208                 async_wait_for(req, &rc_orig);
    209184               
    210185                if (null_id != -1)
     
    219194        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    220195        if (rc != EOK) {
    221                 vfs_exchange_end(vfs_phone);
     196                async_wait_for(req, &rc_orig);
     197                async_serialize_end();
     198                futex_up(&vfs_phone_futex);
    222199                free(mpa);
    223                 async_wait_for(req, &rc_orig);
    224200               
    225201                if (null_id != -1)
     
    235211        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    236212        if (rc != EOK) {
    237                 vfs_exchange_end(vfs_phone);
     213                async_wait_for(req, &rc_orig);
     214                async_serialize_end();
     215                futex_up(&vfs_phone_futex);
    238216                free(mpa);
    239                 async_wait_for(req, &rc_orig);
    240217               
    241218                if (null_id != -1)
     
    248225        }
    249226       
    250         vfs_exchange_end(vfs_phone);
     227        async_wait_for(req, &rc);
     228        async_serialize_end();
     229        futex_up(&vfs_phone_futex);
    251230        free(mpa);
    252         async_wait_for(req, &rc);
    253231       
    254232        if ((rc != EOK) && (null_id != -1))
     
    270248                return ENOMEM;
    271249       
    272         int vfs_phone = vfs_exchange_begin();
     250        futex_down(&vfs_phone_futex);
     251        async_serialize_start();
     252        vfs_connect();
    273253       
    274254        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    275255        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    276256        if (rc != EOK) {
    277                 vfs_exchange_end(vfs_phone);
     257                async_wait_for(req, &rc_orig);
     258                async_serialize_end();
     259                futex_up(&vfs_phone_futex);
    278260                free(mpa);
    279                 async_wait_for(req, &rc_orig);
    280                 if (rc_orig == EOK)
    281                         return (int) rc;
    282                 else
    283                         return (int) rc_orig;
    284         }
    285        
    286 
    287         vfs_exchange_end(vfs_phone);
     261                if (rc_orig == EOK)
     262                        return (int) rc;
     263                else
     264                        return (int) rc_orig;
     265        }
     266       
     267
     268        async_wait_for(req, &rc);
     269        async_serialize_end();
     270        futex_up(&vfs_phone_futex);
    288271        free(mpa);
    289         async_wait_for(req, &rc);
    290272       
    291273        return (int) rc;
     
    294276static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    295277{
    296         int vfs_phone = vfs_exchange_begin();
     278        futex_down(&vfs_phone_futex);
     279        async_serialize_start();
     280        vfs_connect();
    297281       
    298282        ipc_call_t answer;
     
    301285       
    302286        if (rc != EOK) {
    303                 vfs_exchange_end(vfs_phone);
    304 
    305287                sysarg_t rc_orig;
    306288                async_wait_for(req, &rc_orig);
    307289               
    308                 if (rc_orig == EOK)
    309                         return (int) rc;
    310                 else
    311                         return (int) rc_orig;
    312         }
    313        
    314         vfs_exchange_end(vfs_phone);
    315         async_wait_for(req, &rc);
     290                async_serialize_end();
     291                futex_up(&vfs_phone_futex);
     292               
     293                if (rc_orig == EOK)
     294                        return (int) rc;
     295                else
     296                        return (int) rc_orig;
     297        }
     298       
     299        async_wait_for(req, &rc);
     300        async_serialize_end();
     301        futex_up(&vfs_phone_futex);
    316302       
    317303        if (rc != EOK)
     
    336322int open_node(fdi_node_t *node, int oflag)
    337323{
    338         int vfs_phone = vfs_exchange_begin();
     324        futex_down(&vfs_phone_futex);
     325        async_serialize_start();
     326        vfs_connect();
    339327       
    340328        ipc_call_t answer;
     
    342330            node->devmap_handle, node->index, oflag, &answer);
    343331       
    344         vfs_exchange_end(vfs_phone);
    345 
    346         sysarg_t rc;
    347         async_wait_for(req, &rc);
     332        sysarg_t rc;
     333        async_wait_for(req, &rc);
     334        async_serialize_end();
     335        futex_up(&vfs_phone_futex);
    348336       
    349337        if (rc != EOK)
     
    357345        sysarg_t rc;
    358346       
    359         int vfs_phone = vfs_exchange_begin();
     347        futex_down(&vfs_phone_futex);
     348        async_serialize_start();
     349        vfs_connect();
    360350       
    361351        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    362352       
    363         vfs_exchange_end(vfs_phone);
     353        async_serialize_end();
     354        futex_up(&vfs_phone_futex);
    364355       
    365356        return (int)rc;
     
    372363        aid_t req;
    373364
    374         int vfs_phone = vfs_exchange_begin();
     365        futex_down(&vfs_phone_futex);
     366        async_serialize_start();
     367        vfs_connect();
    375368       
    376369        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    377370        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    378371        if (rc != EOK) {
    379                 vfs_exchange_end(vfs_phone);
    380 
    381372                sysarg_t rc_orig;
    382                 async_wait_for(req, &rc_orig);
    383 
     373       
     374                async_wait_for(req, &rc_orig);
     375                async_serialize_end();
     376                futex_up(&vfs_phone_futex);
    384377                if (rc_orig == EOK)
    385378                        return (ssize_t) rc;
     
    387380                        return (ssize_t) rc_orig;
    388381        }
    389         vfs_exchange_end(vfs_phone);
    390         async_wait_for(req, &rc);
     382        async_wait_for(req, &rc);
     383        async_serialize_end();
     384        futex_up(&vfs_phone_futex);
    391385        if (rc == EOK)
    392386                return (ssize_t) IPC_GET_ARG1(answer);
     
    401395        aid_t req;
    402396
    403         int vfs_phone = vfs_exchange_begin();
     397        futex_down(&vfs_phone_futex);
     398        async_serialize_start();
     399        vfs_connect();
    404400       
    405401        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    406402        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    407403        if (rc != EOK) {
    408                 vfs_exchange_end(vfs_phone);
    409 
    410404                sysarg_t rc_orig;
    411                 async_wait_for(req, &rc_orig);
    412 
     405       
     406                async_wait_for(req, &rc_orig);
     407                async_serialize_end();
     408                futex_up(&vfs_phone_futex);
    413409                if (rc_orig == EOK)
    414410                        return (ssize_t) rc;
     
    416412                        return (ssize_t) rc_orig;
    417413        }
    418         vfs_exchange_end(vfs_phone);
    419         async_wait_for(req, &rc);
     414        async_wait_for(req, &rc);
     415        async_serialize_end();
     416        futex_up(&vfs_phone_futex);
    420417        if (rc == EOK)
    421418                return (ssize_t) IPC_GET_ARG1(answer);
     
    426423int fsync(int fildes)
    427424{
    428         int vfs_phone = vfs_exchange_begin();
     425        futex_down(&vfs_phone_futex);
     426        async_serialize_start();
     427        vfs_connect();
    429428       
    430429        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    431430       
    432         vfs_exchange_end(vfs_phone);
     431        async_serialize_end();
     432        futex_up(&vfs_phone_futex);
    433433       
    434434        return (int) rc;
     
    437437off64_t lseek(int fildes, off64_t offset, int whence)
    438438{
    439         int vfs_phone = vfs_exchange_begin();
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
    440442       
    441443        sysarg_t newoff_lo;
     
    445447            &newoff_lo, &newoff_hi);
    446448       
    447         vfs_exchange_end(vfs_phone);
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
    448451       
    449452        if (rc != EOK)
     
    457460        sysarg_t rc;
    458461       
    459         int vfs_phone = vfs_exchange_begin();
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
    460465       
    461466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    462467            LOWER32(length), UPPER32(length));
    463         vfs_exchange_end(vfs_phone);
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
    464470       
    465471        return (int) rc;
     
    471477        aid_t req;
    472478
    473         int vfs_phone = vfs_exchange_begin();
     479        futex_down(&vfs_phone_futex);
     480        async_serialize_start();
     481        vfs_connect();
    474482       
    475483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    476484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    477485        if (rc != EOK) {
    478                 vfs_exchange_end(vfs_phone);
    479 
    480486                sysarg_t rc_orig;
    481                 async_wait_for(req, &rc_orig);
    482 
     487               
     488                async_wait_for(req, &rc_orig);
     489                async_serialize_end();
     490                futex_up(&vfs_phone_futex);
    483491                if (rc_orig == EOK)
    484492                        return (ssize_t) rc;
     
    486494                        return (ssize_t) rc_orig;
    487495        }
    488         vfs_exchange_end(vfs_phone);
    489         async_wait_for(req, &rc);
     496        async_wait_for(req, &rc);
     497        async_serialize_end();
     498        futex_up(&vfs_phone_futex);
    490499
    491500        return rc;
     
    503512                return ENOMEM;
    504513       
    505         int vfs_phone = vfs_exchange_begin();
     514        futex_down(&vfs_phone_futex);
     515        async_serialize_start();
     516        vfs_connect();
    506517       
    507518        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    508519        rc = async_data_write_start(vfs_phone, pa, pa_size);
    509520        if (rc != EOK) {
    510                 vfs_exchange_end(vfs_phone);
     521                async_wait_for(req, &rc_orig);
     522                async_serialize_end();
     523                futex_up(&vfs_phone_futex);
    511524                free(pa);
    512                 async_wait_for(req, &rc_orig);
    513525                if (rc_orig == EOK)
    514526                        return (int) rc;
     
    518530        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    519531        if (rc != EOK) {
    520                 vfs_exchange_end(vfs_phone);
     532                async_wait_for(req, &rc_orig);
     533                async_serialize_end();
     534                futex_up(&vfs_phone_futex);
    521535                free(pa);
    522                 async_wait_for(req, &rc_orig);
    523                 if (rc_orig == EOK)
    524                         return (int) rc;
    525                 else
    526                         return (int) rc_orig;
    527         }
    528         vfs_exchange_end(vfs_phone);
     536                if (rc_orig == EOK)
     537                        return (int) rc;
     538                else
     539                        return (int) rc_orig;
     540        }
     541        async_wait_for(req, &rc);
     542        async_serialize_end();
     543        futex_up(&vfs_phone_futex);
    529544        free(pa);
    530         async_wait_for(req, &rc);
    531545        return rc;
    532546}
     
    587601                return ENOMEM;
    588602       
    589         int vfs_phone = vfs_exchange_begin();
     603        futex_down(&vfs_phone_futex);
     604        async_serialize_start();
     605        vfs_connect();
    590606       
    591607        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    592608        rc = async_data_write_start(vfs_phone, pa, pa_size);
    593609        if (rc != EOK) {
    594                 vfs_exchange_end(vfs_phone);
     610                sysarg_t rc_orig;
     611       
     612                async_wait_for(req, &rc_orig);
     613                async_serialize_end();
     614                futex_up(&vfs_phone_futex);
    595615                free(pa);
    596 
    597                 sysarg_t rc_orig;
    598                 async_wait_for(req, &rc_orig);
    599 
    600                 if (rc_orig == EOK)
    601                         return (int) rc;
    602                 else
    603                         return (int) rc_orig;
    604         }
    605         vfs_exchange_end(vfs_phone);
     616                if (rc_orig == EOK)
     617                        return (int) rc;
     618                else
     619                        return (int) rc_orig;
     620        }
     621        async_wait_for(req, &rc);
     622        async_serialize_end();
     623        futex_up(&vfs_phone_futex);
    606624        free(pa);
    607         async_wait_for(req, &rc);
    608625        return rc;
    609626}
     
    619636                return ENOMEM;
    620637
    621         int vfs_phone = vfs_exchange_begin();
     638        futex_down(&vfs_phone_futex);
     639        async_serialize_start();
     640        vfs_connect();
    622641       
    623642        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    624643        rc = async_data_write_start(vfs_phone, pa, pa_size);
    625644        if (rc != EOK) {
    626                 vfs_exchange_end(vfs_phone);
     645                sysarg_t rc_orig;
     646
     647                async_wait_for(req, &rc_orig);
     648                async_serialize_end();
     649                futex_up(&vfs_phone_futex);
    627650                free(pa);
    628 
    629                 sysarg_t rc_orig;
    630                 async_wait_for(req, &rc_orig);
    631 
    632                 if (rc_orig == EOK)
    633                         return (int) rc;
    634                 else
    635                         return (int) rc_orig;
    636         }
    637         vfs_exchange_end(vfs_phone);
     651                if (rc_orig == EOK)
     652                        return (int) rc;
     653                else
     654                        return (int) rc_orig;
     655        }
     656        async_wait_for(req, &rc);
     657        async_serialize_end();
     658        futex_up(&vfs_phone_futex);
    638659        free(pa);
    639         async_wait_for(req, &rc);
    640660        return rc;
    641661}
     
    669689        }
    670690
    671         int vfs_phone = vfs_exchange_begin();
     691        futex_down(&vfs_phone_futex);
     692        async_serialize_start();
     693        vfs_connect();
    672694       
    673695        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    674696        rc = async_data_write_start(vfs_phone, olda, olda_size);
    675697        if (rc != EOK) {
    676                 vfs_exchange_end(vfs_phone);
     698                async_wait_for(req, &rc_orig);
     699                async_serialize_end();
     700                futex_up(&vfs_phone_futex);
    677701                free(olda);
    678702                free(newa);
    679                 async_wait_for(req, &rc_orig);
    680703                if (rc_orig == EOK)
    681704                        return (int) rc;
     
    685708        rc = async_data_write_start(vfs_phone, newa, newa_size);
    686709        if (rc != EOK) {
    687                 vfs_exchange_end(vfs_phone);
     710                async_wait_for(req, &rc_orig);
     711                async_serialize_end();
     712                futex_up(&vfs_phone_futex);
    688713                free(olda);
    689714                free(newa);
    690                 async_wait_for(req, &rc_orig);
    691                 if (rc_orig == EOK)
    692                         return (int) rc;
    693                 else
    694                         return (int) rc_orig;
    695         }
    696         vfs_exchange_end(vfs_phone);
     715                if (rc_orig == EOK)
     716                        return (int) rc;
     717                else
     718                        return (int) rc_orig;
     719        }
     720        async_wait_for(req, &rc);
     721        async_serialize_end();
     722        futex_up(&vfs_phone_futex);
    697723        free(olda);
    698724        free(newa);
    699         async_wait_for(req, &rc);
    700725        return rc;
    701726}
     
    715740        }
    716741       
    717         fibril_mutex_lock(&cwd_mutex);
     742        futex_down(&cwd_futex);
    718743       
    719744        if (cwd_fd >= 0)
     
    728753        cwd_size = abs_size;
    729754       
    730         fibril_mutex_unlock(&cwd_mutex);
     755        futex_up(&cwd_futex);
    731756        return EOK;
    732757}
     
    737762                return NULL;
    738763       
    739         fibril_mutex_lock(&cwd_mutex);
     764        futex_down(&cwd_futex);
    740765       
    741766        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    742                 fibril_mutex_unlock(&cwd_mutex);
     767                futex_up(&cwd_futex);
    743768                return NULL;
    744769        }
    745770       
    746771        str_cpy(buf, size, cwd_path);
    747         fibril_mutex_unlock(&cwd_mutex);
     772        futex_up(&cwd_futex);
    748773       
    749774        return buf;
     
    781806int dup2(int oldfd, int newfd)
    782807{
    783         int vfs_phone = vfs_exchange_begin();
     808        futex_down(&vfs_phone_futex);
     809        async_serialize_start();
     810        vfs_connect();
    784811       
    785812        sysarg_t ret;
    786813        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    787814       
    788         vfs_exchange_end(vfs_phone);
     815        async_serialize_end();
     816        futex_up(&vfs_phone_futex);
    789817       
    790818        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.