Ignore:
File:
1 edited

Legend:

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

    ra28ab12 r96b02eb9  
    4646#include <ipc/services.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{
    120         while (vfs_phone < 0) {
    121                 vfs_phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_VFS,
    122                     0, 0);
    123         }
    124        
    125         async_session_create(&vfs_session, vfs_phone, 0);
    126 }
    127 
    128 /** Start an async exchange on the VFS session.
    129  *
    130  * @return              New phone to be used during the exchange.
    131  */
    132 static int vfs_exchange_begin(void)
    133 {
    134         fibril_mutex_lock(&vfs_phone_mutex);
    135         if (vfs_phone < 0)
    136                 vfs_connect();
    137         fibril_mutex_unlock(&vfs_phone_mutex);
    138 
    139         return async_exchange_begin(&vfs_session);
    140 }
    141 
    142 /** End an async exchange on the VFS session.
    143  *
    144  * @param phone         Phone used during the exchange.
    145  */
    146 static void vfs_exchange_end(int phone)
    147 {
    148         async_exchange_end(&vfs_session, phone);
     116        while (vfs_phone < 0)
     117                vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
    149118}
    150119
     
    185154        }
    186155       
    187         int vfs_phone = vfs_exchange_begin();
    188 
     156        futex_down(&vfs_phone_futex);
     157        async_serialize_start();
     158        vfs_connect();
     159       
    189160        sysarg_t rc_orig;
    190161        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    191162        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    192163        if (rc != EOK) {
    193                 vfs_exchange_end(vfs_phone);
     164                async_wait_for(req, &rc_orig);
     165                async_serialize_end();
     166                futex_up(&vfs_phone_futex);
    194167                free(mpa);
    195                 async_wait_for(req, &rc_orig);
    196168               
    197169                if (null_id != -1)
     
    206178        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    207179        if (rc != EOK) {
    208                 vfs_exchange_end(vfs_phone);
     180                async_wait_for(req, &rc_orig);
     181                async_serialize_end();
     182                futex_up(&vfs_phone_futex);
    209183                free(mpa);
    210                 async_wait_for(req, &rc_orig);
    211184               
    212185                if (null_id != -1)
     
    221194        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    222195        if (rc != EOK) {
    223                 vfs_exchange_end(vfs_phone);
     196                async_wait_for(req, &rc_orig);
     197                async_serialize_end();
     198                futex_up(&vfs_phone_futex);
    224199                free(mpa);
    225                 async_wait_for(req, &rc_orig);
    226200               
    227201                if (null_id != -1)
     
    237211        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    238212        if (rc != EOK) {
    239                 vfs_exchange_end(vfs_phone);
     213                async_wait_for(req, &rc_orig);
     214                async_serialize_end();
     215                futex_up(&vfs_phone_futex);
    240216                free(mpa);
    241                 async_wait_for(req, &rc_orig);
    242217               
    243218                if (null_id != -1)
     
    250225        }
    251226       
    252         vfs_exchange_end(vfs_phone);
     227        async_wait_for(req, &rc);
     228        async_serialize_end();
     229        futex_up(&vfs_phone_futex);
    253230        free(mpa);
    254         async_wait_for(req, &rc);
    255231       
    256232        if ((rc != EOK) && (null_id != -1))
     
    272248                return ENOMEM;
    273249       
    274         int vfs_phone = vfs_exchange_begin();
     250        futex_down(&vfs_phone_futex);
     251        async_serialize_start();
     252        vfs_connect();
    275253       
    276254        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    277255        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    278256        if (rc != EOK) {
    279                 vfs_exchange_end(vfs_phone);
     257                async_wait_for(req, &rc_orig);
     258                async_serialize_end();
     259                futex_up(&vfs_phone_futex);
    280260                free(mpa);
    281                 async_wait_for(req, &rc_orig);
    282                 if (rc_orig == EOK)
    283                         return (int) rc;
    284                 else
    285                         return (int) rc_orig;
    286         }
    287        
    288 
    289         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);
    290271        free(mpa);
    291         async_wait_for(req, &rc);
    292272       
    293273        return (int) rc;
     
    296276static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    297277{
    298         int vfs_phone = vfs_exchange_begin();
     278        futex_down(&vfs_phone_futex);
     279        async_serialize_start();
     280        vfs_connect();
    299281       
    300282        ipc_call_t answer;
     
    303285       
    304286        if (rc != EOK) {
    305                 vfs_exchange_end(vfs_phone);
    306 
    307287                sysarg_t rc_orig;
    308288                async_wait_for(req, &rc_orig);
    309289               
    310                 if (rc_orig == EOK)
    311                         return (int) rc;
    312                 else
    313                         return (int) rc_orig;
    314         }
    315        
    316         vfs_exchange_end(vfs_phone);
    317         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);
    318302       
    319303        if (rc != EOK)
     
    338322int open_node(fdi_node_t *node, int oflag)
    339323{
    340         int vfs_phone = vfs_exchange_begin();
     324        futex_down(&vfs_phone_futex);
     325        async_serialize_start();
     326        vfs_connect();
    341327       
    342328        ipc_call_t answer;
     
    344330            node->devmap_handle, node->index, oflag, &answer);
    345331       
    346         vfs_exchange_end(vfs_phone);
    347 
    348         sysarg_t rc;
    349         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);
    350336       
    351337        if (rc != EOK)
     
    359345        sysarg_t rc;
    360346       
    361         int vfs_phone = vfs_exchange_begin();
     347        futex_down(&vfs_phone_futex);
     348        async_serialize_start();
     349        vfs_connect();
    362350       
    363351        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    364352       
    365         vfs_exchange_end(vfs_phone);
     353        async_serialize_end();
     354        futex_up(&vfs_phone_futex);
    366355       
    367356        return (int)rc;
     
    374363        aid_t req;
    375364
    376         int vfs_phone = vfs_exchange_begin();
     365        futex_down(&vfs_phone_futex);
     366        async_serialize_start();
     367        vfs_connect();
    377368       
    378369        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    379370        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    380371        if (rc != EOK) {
    381                 vfs_exchange_end(vfs_phone);
    382 
    383372                sysarg_t rc_orig;
    384                 async_wait_for(req, &rc_orig);
    385 
     373       
     374                async_wait_for(req, &rc_orig);
     375                async_serialize_end();
     376                futex_up(&vfs_phone_futex);
    386377                if (rc_orig == EOK)
    387378                        return (ssize_t) rc;
     
    389380                        return (ssize_t) rc_orig;
    390381        }
    391         vfs_exchange_end(vfs_phone);
    392         async_wait_for(req, &rc);
     382        async_wait_for(req, &rc);
     383        async_serialize_end();
     384        futex_up(&vfs_phone_futex);
    393385        if (rc == EOK)
    394386                return (ssize_t) IPC_GET_ARG1(answer);
     
    403395        aid_t req;
    404396
    405         int vfs_phone = vfs_exchange_begin();
     397        futex_down(&vfs_phone_futex);
     398        async_serialize_start();
     399        vfs_connect();
    406400       
    407401        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    408402        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    409403        if (rc != EOK) {
    410                 vfs_exchange_end(vfs_phone);
    411 
    412404                sysarg_t rc_orig;
    413                 async_wait_for(req, &rc_orig);
    414 
     405       
     406                async_wait_for(req, &rc_orig);
     407                async_serialize_end();
     408                futex_up(&vfs_phone_futex);
    415409                if (rc_orig == EOK)
    416410                        return (ssize_t) rc;
     
    418412                        return (ssize_t) rc_orig;
    419413        }
    420         vfs_exchange_end(vfs_phone);
    421         async_wait_for(req, &rc);
     414        async_wait_for(req, &rc);
     415        async_serialize_end();
     416        futex_up(&vfs_phone_futex);
    422417        if (rc == EOK)
    423418                return (ssize_t) IPC_GET_ARG1(answer);
     
    428423int fsync(int fildes)
    429424{
    430         int vfs_phone = vfs_exchange_begin();
     425        futex_down(&vfs_phone_futex);
     426        async_serialize_start();
     427        vfs_connect();
    431428       
    432429        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    433430       
    434         vfs_exchange_end(vfs_phone);
     431        async_serialize_end();
     432        futex_up(&vfs_phone_futex);
    435433       
    436434        return (int) rc;
     
    439437off64_t lseek(int fildes, off64_t offset, int whence)
    440438{
    441         int vfs_phone = vfs_exchange_begin();
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
    442442       
    443443        sysarg_t newoff_lo;
     
    447447            &newoff_lo, &newoff_hi);
    448448       
    449         vfs_exchange_end(vfs_phone);
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
    450451       
    451452        if (rc != EOK)
     
    459460        sysarg_t rc;
    460461       
    461         int vfs_phone = vfs_exchange_begin();
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
    462465       
    463466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    464467            LOWER32(length), UPPER32(length));
    465         vfs_exchange_end(vfs_phone);
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
    466470       
    467471        return (int) rc;
     
    473477        aid_t req;
    474478
    475         int vfs_phone = vfs_exchange_begin();
     479        futex_down(&vfs_phone_futex);
     480        async_serialize_start();
     481        vfs_connect();
    476482       
    477483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    478484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    479485        if (rc != EOK) {
    480                 vfs_exchange_end(vfs_phone);
    481 
    482486                sysarg_t rc_orig;
    483                 async_wait_for(req, &rc_orig);
    484 
     487               
     488                async_wait_for(req, &rc_orig);
     489                async_serialize_end();
     490                futex_up(&vfs_phone_futex);
    485491                if (rc_orig == EOK)
    486492                        return (ssize_t) rc;
     
    488494                        return (ssize_t) rc_orig;
    489495        }
    490         vfs_exchange_end(vfs_phone);
    491         async_wait_for(req, &rc);
     496        async_wait_for(req, &rc);
     497        async_serialize_end();
     498        futex_up(&vfs_phone_futex);
    492499
    493500        return rc;
     
    505512                return ENOMEM;
    506513       
    507         int vfs_phone = vfs_exchange_begin();
     514        futex_down(&vfs_phone_futex);
     515        async_serialize_start();
     516        vfs_connect();
    508517       
    509518        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    510519        rc = async_data_write_start(vfs_phone, pa, pa_size);
    511520        if (rc != EOK) {
    512                 vfs_exchange_end(vfs_phone);
     521                async_wait_for(req, &rc_orig);
     522                async_serialize_end();
     523                futex_up(&vfs_phone_futex);
    513524                free(pa);
    514                 async_wait_for(req, &rc_orig);
    515525                if (rc_orig == EOK)
    516526                        return (int) rc;
     
    520530        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    521531        if (rc != EOK) {
    522                 vfs_exchange_end(vfs_phone);
     532                async_wait_for(req, &rc_orig);
     533                async_serialize_end();
     534                futex_up(&vfs_phone_futex);
    523535                free(pa);
    524                 async_wait_for(req, &rc_orig);
    525                 if (rc_orig == EOK)
    526                         return (int) rc;
    527                 else
    528                         return (int) rc_orig;
    529         }
    530         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);
    531544        free(pa);
    532         async_wait_for(req, &rc);
    533545        return rc;
    534546}
     
    589601                return ENOMEM;
    590602       
    591         int vfs_phone = vfs_exchange_begin();
     603        futex_down(&vfs_phone_futex);
     604        async_serialize_start();
     605        vfs_connect();
    592606       
    593607        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    594608        rc = async_data_write_start(vfs_phone, pa, pa_size);
    595609        if (rc != EOK) {
    596                 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);
    597615                free(pa);
    598 
    599                 sysarg_t rc_orig;
    600                 async_wait_for(req, &rc_orig);
    601 
    602                 if (rc_orig == EOK)
    603                         return (int) rc;
    604                 else
    605                         return (int) rc_orig;
    606         }
    607         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);
    608624        free(pa);
    609         async_wait_for(req, &rc);
    610625        return rc;
    611626}
     
    621636                return ENOMEM;
    622637
    623         int vfs_phone = vfs_exchange_begin();
     638        futex_down(&vfs_phone_futex);
     639        async_serialize_start();
     640        vfs_connect();
    624641       
    625642        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    626643        rc = async_data_write_start(vfs_phone, pa, pa_size);
    627644        if (rc != EOK) {
    628                 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);
    629650                free(pa);
    630 
    631                 sysarg_t rc_orig;
    632                 async_wait_for(req, &rc_orig);
    633 
    634                 if (rc_orig == EOK)
    635                         return (int) rc;
    636                 else
    637                         return (int) rc_orig;
    638         }
    639         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);
    640659        free(pa);
    641         async_wait_for(req, &rc);
    642660        return rc;
    643661}
     
    671689        }
    672690
    673         int vfs_phone = vfs_exchange_begin();
     691        futex_down(&vfs_phone_futex);
     692        async_serialize_start();
     693        vfs_connect();
    674694       
    675695        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    676696        rc = async_data_write_start(vfs_phone, olda, olda_size);
    677697        if (rc != EOK) {
    678                 vfs_exchange_end(vfs_phone);
     698                async_wait_for(req, &rc_orig);
     699                async_serialize_end();
     700                futex_up(&vfs_phone_futex);
    679701                free(olda);
    680702                free(newa);
    681                 async_wait_for(req, &rc_orig);
    682703                if (rc_orig == EOK)
    683704                        return (int) rc;
     
    687708        rc = async_data_write_start(vfs_phone, newa, newa_size);
    688709        if (rc != EOK) {
    689                 vfs_exchange_end(vfs_phone);
     710                async_wait_for(req, &rc_orig);
     711                async_serialize_end();
     712                futex_up(&vfs_phone_futex);
    690713                free(olda);
    691714                free(newa);
    692                 async_wait_for(req, &rc_orig);
    693                 if (rc_orig == EOK)
    694                         return (int) rc;
    695                 else
    696                         return (int) rc_orig;
    697         }
    698         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);
    699723        free(olda);
    700724        free(newa);
    701         async_wait_for(req, &rc);
    702725        return rc;
    703726}
     
    717740        }
    718741       
    719         fibril_mutex_lock(&cwd_mutex);
     742        futex_down(&cwd_futex);
    720743       
    721744        if (cwd_fd >= 0)
     
    730753        cwd_size = abs_size;
    731754       
    732         fibril_mutex_unlock(&cwd_mutex);
     755        futex_up(&cwd_futex);
    733756        return EOK;
    734757}
     
    739762                return NULL;
    740763       
    741         fibril_mutex_lock(&cwd_mutex);
     764        futex_down(&cwd_futex);
    742765       
    743766        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    744                 fibril_mutex_unlock(&cwd_mutex);
     767                futex_up(&cwd_futex);
    745768                return NULL;
    746769        }
    747770       
    748771        str_cpy(buf, size, cwd_path);
    749         fibril_mutex_unlock(&cwd_mutex);
     772        futex_up(&cwd_futex);
    750773       
    751774        return buf;
     
    783806int dup2(int oldfd, int newfd)
    784807{
    785         int vfs_phone = vfs_exchange_begin();
     808        futex_down(&vfs_phone_futex);
     809        async_serialize_start();
     810        vfs_connect();
    786811       
    787812        sysarg_t ret;
    788813        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    789814       
    790         vfs_exchange_end(vfs_phone);
     815        async_serialize_end();
     816        futex_up(&vfs_phone_futex);
    791817       
    792818        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.