Ignore:
File:
1 edited

Legend:

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

    r8caaea7 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;
     
    6966        char *ncwd_path;
    7067        char *ncwd_path_nc;
    71         size_t total_size;
    72 
    73         fibril_mutex_lock(&cwd_mutex);
     68
     69        futex_down(&cwd_futex);
    7470        size_t size = str_size(path);
    7571        if (*path != '/') {
    7672                if (!cwd_path) {
    77                         fibril_mutex_unlock(&cwd_mutex);
     73                        futex_up(&cwd_futex);
    7874                        return NULL;
    7975                }
    80                 total_size = cwd_size + 1 + size + 1;
    81                 ncwd_path_nc = malloc(total_size);
     76                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    8277                if (!ncwd_path_nc) {
    83                         fibril_mutex_unlock(&cwd_mutex);
     78                        futex_up(&cwd_futex);
    8479                        return NULL;
    8580                }
    86                 str_cpy(ncwd_path_nc, total_size, cwd_path);
     81                str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
    8782                ncwd_path_nc[cwd_size] = '/';
    8883                ncwd_path_nc[cwd_size + 1] = '\0';
    8984        } else {
    90                 total_size = size + 1;
    91                 ncwd_path_nc = malloc(total_size);
     85                ncwd_path_nc = malloc(size + 1);
    9286                if (!ncwd_path_nc) {
    93                         fibril_mutex_unlock(&cwd_mutex);
     87                        futex_up(&cwd_futex);
    9488                        return NULL;
    9589                }
    9690                ncwd_path_nc[0] = '\0';
    9791        }
    98         str_append(ncwd_path_nc, total_size, path);
     92        str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
    9993        ncwd_path = canonify(ncwd_path_nc, retlen);
    10094        if (!ncwd_path) {
    101                 fibril_mutex_unlock(&cwd_mutex);
     95                futex_up(&cwd_futex);
    10296                free(ncwd_path_nc);
    10397                return NULL;
     
    111105        free(ncwd_path_nc);
    112106        if (!ncwd_path) {
    113                 fibril_mutex_unlock(&cwd_mutex);
     107                futex_up(&cwd_futex);
    114108                return NULL;
    115109        }
    116         fibril_mutex_unlock(&cwd_mutex);
     110        futex_up(&cwd_futex);
    117111        return ncwd_path;
    118112}
    119113
    120 /** Connect to VFS service and create session. */
    121114static void vfs_connect(void)
    122115{
    123116        while (vfs_phone < 0)
    124                 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    125        
    126         async_session_create(&vfs_session, vfs_phone, 0);
    127 }
    128 
    129 /** Start an async exchange on the VFS session.
    130  *
    131  * @return              New phone to be used during the exchange.
    132  */
    133 static int vfs_exchange_begin(void)
    134 {
    135         fibril_mutex_lock(&vfs_phone_mutex);
    136         if (vfs_phone < 0)
    137                 vfs_connect();
    138         fibril_mutex_unlock(&vfs_phone_mutex);
    139 
    140         return async_exchange_begin(&vfs_session);
    141 }
    142 
    143 /** End an async exchange on the VFS session.
    144  *
    145  * @param phone         Phone used during the exchange.
    146  */
    147 static void vfs_exchange_end(int phone)
    148 {
    149         async_exchange_end(&vfs_session, phone);
     117                vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
    150118}
    151119
     
    186154        }
    187155       
    188         int vfs_phone = vfs_exchange_begin();
    189 
     156        futex_down(&vfs_phone_futex);
     157        async_serialize_start();
     158        vfs_connect();
     159       
    190160        sysarg_t rc_orig;
    191161        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    192162        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    193163        if (rc != EOK) {
    194                 vfs_exchange_end(vfs_phone);
     164                async_wait_for(req, &rc_orig);
     165                async_serialize_end();
     166                futex_up(&vfs_phone_futex);
    195167                free(mpa);
    196                 async_wait_for(req, &rc_orig);
    197168               
    198169                if (null_id != -1)
     
    207178        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    208179        if (rc != EOK) {
    209                 vfs_exchange_end(vfs_phone);
     180                async_wait_for(req, &rc_orig);
     181                async_serialize_end();
     182                futex_up(&vfs_phone_futex);
    210183                free(mpa);
    211                 async_wait_for(req, &rc_orig);
    212184               
    213185                if (null_id != -1)
     
    222194        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    223195        if (rc != EOK) {
    224                 vfs_exchange_end(vfs_phone);
     196                async_wait_for(req, &rc_orig);
     197                async_serialize_end();
     198                futex_up(&vfs_phone_futex);
    225199                free(mpa);
    226                 async_wait_for(req, &rc_orig);
    227200               
    228201                if (null_id != -1)
     
    238211        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    239212        if (rc != EOK) {
    240                 vfs_exchange_end(vfs_phone);
     213                async_wait_for(req, &rc_orig);
     214                async_serialize_end();
     215                futex_up(&vfs_phone_futex);
    241216                free(mpa);
    242                 async_wait_for(req, &rc_orig);
    243217               
    244218                if (null_id != -1)
     
    251225        }
    252226       
    253         vfs_exchange_end(vfs_phone);
     227        async_wait_for(req, &rc);
     228        async_serialize_end();
     229        futex_up(&vfs_phone_futex);
    254230        free(mpa);
    255         async_wait_for(req, &rc);
    256231       
    257232        if ((rc != EOK) && (null_id != -1))
     
    273248                return ENOMEM;
    274249       
    275         int vfs_phone = vfs_exchange_begin();
     250        futex_down(&vfs_phone_futex);
     251        async_serialize_start();
     252        vfs_connect();
    276253       
    277254        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    278255        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    279256        if (rc != EOK) {
    280                 vfs_exchange_end(vfs_phone);
     257                async_wait_for(req, &rc_orig);
     258                async_serialize_end();
     259                futex_up(&vfs_phone_futex);
    281260                free(mpa);
    282                 async_wait_for(req, &rc_orig);
    283                 if (rc_orig == EOK)
    284                         return (int) rc;
    285                 else
    286                         return (int) rc_orig;
    287         }
    288        
    289 
    290         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);
    291271        free(mpa);
    292         async_wait_for(req, &rc);
    293272       
    294273        return (int) rc;
     
    297276static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    298277{
    299         int vfs_phone = vfs_exchange_begin();
     278        futex_down(&vfs_phone_futex);
     279        async_serialize_start();
     280        vfs_connect();
    300281       
    301282        ipc_call_t answer;
     
    304285       
    305286        if (rc != EOK) {
    306                 vfs_exchange_end(vfs_phone);
    307 
    308287                sysarg_t rc_orig;
    309288                async_wait_for(req, &rc_orig);
    310289               
    311                 if (rc_orig == EOK)
    312                         return (int) rc;
    313                 else
    314                         return (int) rc_orig;
    315         }
    316        
    317         vfs_exchange_end(vfs_phone);
    318         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);
    319302       
    320303        if (rc != EOK)
     
    339322int open_node(fdi_node_t *node, int oflag)
    340323{
    341         int vfs_phone = vfs_exchange_begin();
     324        futex_down(&vfs_phone_futex);
     325        async_serialize_start();
     326        vfs_connect();
    342327       
    343328        ipc_call_t answer;
     
    345330            node->devmap_handle, node->index, oflag, &answer);
    346331       
    347         vfs_exchange_end(vfs_phone);
    348 
    349         sysarg_t rc;
    350         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);
    351336       
    352337        if (rc != EOK)
     
    360345        sysarg_t rc;
    361346       
    362         int vfs_phone = vfs_exchange_begin();
     347        futex_down(&vfs_phone_futex);
     348        async_serialize_start();
     349        vfs_connect();
    363350       
    364351        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    365352       
    366         vfs_exchange_end(vfs_phone);
     353        async_serialize_end();
     354        futex_up(&vfs_phone_futex);
    367355       
    368356        return (int)rc;
     
    375363        aid_t req;
    376364
    377         int vfs_phone = vfs_exchange_begin();
     365        futex_down(&vfs_phone_futex);
     366        async_serialize_start();
     367        vfs_connect();
    378368       
    379369        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    380370        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    381371        if (rc != EOK) {
    382                 vfs_exchange_end(vfs_phone);
    383 
    384372                sysarg_t rc_orig;
    385                 async_wait_for(req, &rc_orig);
    386 
     373       
     374                async_wait_for(req, &rc_orig);
     375                async_serialize_end();
     376                futex_up(&vfs_phone_futex);
    387377                if (rc_orig == EOK)
    388378                        return (ssize_t) rc;
     
    390380                        return (ssize_t) rc_orig;
    391381        }
    392         vfs_exchange_end(vfs_phone);
    393         async_wait_for(req, &rc);
     382        async_wait_for(req, &rc);
     383        async_serialize_end();
     384        futex_up(&vfs_phone_futex);
    394385        if (rc == EOK)
    395386                return (ssize_t) IPC_GET_ARG1(answer);
     
    404395        aid_t req;
    405396
    406         int vfs_phone = vfs_exchange_begin();
     397        futex_down(&vfs_phone_futex);
     398        async_serialize_start();
     399        vfs_connect();
    407400       
    408401        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    409402        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    410403        if (rc != EOK) {
    411                 vfs_exchange_end(vfs_phone);
    412 
    413404                sysarg_t rc_orig;
    414                 async_wait_for(req, &rc_orig);
    415 
     405       
     406                async_wait_for(req, &rc_orig);
     407                async_serialize_end();
     408                futex_up(&vfs_phone_futex);
    416409                if (rc_orig == EOK)
    417410                        return (ssize_t) rc;
     
    419412                        return (ssize_t) rc_orig;
    420413        }
    421         vfs_exchange_end(vfs_phone);
    422         async_wait_for(req, &rc);
     414        async_wait_for(req, &rc);
     415        async_serialize_end();
     416        futex_up(&vfs_phone_futex);
    423417        if (rc == EOK)
    424418                return (ssize_t) IPC_GET_ARG1(answer);
     
    429423int fsync(int fildes)
    430424{
    431         int vfs_phone = vfs_exchange_begin();
     425        futex_down(&vfs_phone_futex);
     426        async_serialize_start();
     427        vfs_connect();
    432428       
    433429        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    434430       
    435         vfs_exchange_end(vfs_phone);
     431        async_serialize_end();
     432        futex_up(&vfs_phone_futex);
    436433       
    437434        return (int) rc;
     
    440437off64_t lseek(int fildes, off64_t offset, int whence)
    441438{
    442         int vfs_phone = vfs_exchange_begin();
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
    443442       
    444443        sysarg_t newoff_lo;
     
    448447            &newoff_lo, &newoff_hi);
    449448       
    450         vfs_exchange_end(vfs_phone);
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
    451451       
    452452        if (rc != EOK)
     
    460460        sysarg_t rc;
    461461       
    462         int vfs_phone = vfs_exchange_begin();
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
    463465       
    464466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    465467            LOWER32(length), UPPER32(length));
    466         vfs_exchange_end(vfs_phone);
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
    467470       
    468471        return (int) rc;
     
    474477        aid_t req;
    475478
    476         int vfs_phone = vfs_exchange_begin();
     479        futex_down(&vfs_phone_futex);
     480        async_serialize_start();
     481        vfs_connect();
    477482       
    478483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    479484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    480485        if (rc != EOK) {
    481                 vfs_exchange_end(vfs_phone);
    482 
    483486                sysarg_t rc_orig;
    484                 async_wait_for(req, &rc_orig);
    485 
     487               
     488                async_wait_for(req, &rc_orig);
     489                async_serialize_end();
     490                futex_up(&vfs_phone_futex);
    486491                if (rc_orig == EOK)
    487492                        return (ssize_t) rc;
     
    489494                        return (ssize_t) rc_orig;
    490495        }
    491         vfs_exchange_end(vfs_phone);
    492         async_wait_for(req, &rc);
     496        async_wait_for(req, &rc);
     497        async_serialize_end();
     498        futex_up(&vfs_phone_futex);
    493499
    494500        return rc;
     
    506512                return ENOMEM;
    507513       
    508         int vfs_phone = vfs_exchange_begin();
     514        futex_down(&vfs_phone_futex);
     515        async_serialize_start();
     516        vfs_connect();
    509517       
    510518        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    511519        rc = async_data_write_start(vfs_phone, pa, pa_size);
    512520        if (rc != EOK) {
    513                 vfs_exchange_end(vfs_phone);
     521                async_wait_for(req, &rc_orig);
     522                async_serialize_end();
     523                futex_up(&vfs_phone_futex);
    514524                free(pa);
    515                 async_wait_for(req, &rc_orig);
    516525                if (rc_orig == EOK)
    517526                        return (int) rc;
     
    521530        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    522531        if (rc != EOK) {
    523                 vfs_exchange_end(vfs_phone);
     532                async_wait_for(req, &rc_orig);
     533                async_serialize_end();
     534                futex_up(&vfs_phone_futex);
    524535                free(pa);
    525                 async_wait_for(req, &rc_orig);
    526                 if (rc_orig == EOK)
    527                         return (int) rc;
    528                 else
    529                         return (int) rc_orig;
    530         }
    531         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);
    532544        free(pa);
    533         async_wait_for(req, &rc);
    534545        return rc;
    535546}
     
    590601                return ENOMEM;
    591602       
    592         int vfs_phone = vfs_exchange_begin();
     603        futex_down(&vfs_phone_futex);
     604        async_serialize_start();
     605        vfs_connect();
    593606       
    594607        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    595608        rc = async_data_write_start(vfs_phone, pa, pa_size);
    596609        if (rc != EOK) {
    597                 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);
    598615                free(pa);
    599 
    600                 sysarg_t rc_orig;
    601                 async_wait_for(req, &rc_orig);
    602 
    603                 if (rc_orig == EOK)
    604                         return (int) rc;
    605                 else
    606                         return (int) rc_orig;
    607         }
    608         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);
    609624        free(pa);
    610         async_wait_for(req, &rc);
    611625        return rc;
    612626}
     
    622636                return ENOMEM;
    623637
    624         int vfs_phone = vfs_exchange_begin();
     638        futex_down(&vfs_phone_futex);
     639        async_serialize_start();
     640        vfs_connect();
    625641       
    626642        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    627643        rc = async_data_write_start(vfs_phone, pa, pa_size);
    628644        if (rc != EOK) {
    629                 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);
    630650                free(pa);
    631 
    632                 sysarg_t rc_orig;
    633                 async_wait_for(req, &rc_orig);
    634 
    635                 if (rc_orig == EOK)
    636                         return (int) rc;
    637                 else
    638                         return (int) rc_orig;
    639         }
    640         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);
    641659        free(pa);
    642         async_wait_for(req, &rc);
    643660        return rc;
    644661}
     
    672689        }
    673690
    674         int vfs_phone = vfs_exchange_begin();
     691        futex_down(&vfs_phone_futex);
     692        async_serialize_start();
     693        vfs_connect();
    675694       
    676695        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    677696        rc = async_data_write_start(vfs_phone, olda, olda_size);
    678697        if (rc != EOK) {
    679                 vfs_exchange_end(vfs_phone);
     698                async_wait_for(req, &rc_orig);
     699                async_serialize_end();
     700                futex_up(&vfs_phone_futex);
    680701                free(olda);
    681702                free(newa);
    682                 async_wait_for(req, &rc_orig);
    683703                if (rc_orig == EOK)
    684704                        return (int) rc;
     
    688708        rc = async_data_write_start(vfs_phone, newa, newa_size);
    689709        if (rc != EOK) {
    690                 vfs_exchange_end(vfs_phone);
     710                async_wait_for(req, &rc_orig);
     711                async_serialize_end();
     712                futex_up(&vfs_phone_futex);
    691713                free(olda);
    692714                free(newa);
    693                 async_wait_for(req, &rc_orig);
    694                 if (rc_orig == EOK)
    695                         return (int) rc;
    696                 else
    697                         return (int) rc_orig;
    698         }
    699         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);
    700723        free(olda);
    701724        free(newa);
    702         async_wait_for(req, &rc);
    703725        return rc;
    704726}
     
    718740        }
    719741       
    720         fibril_mutex_lock(&cwd_mutex);
     742        futex_down(&cwd_futex);
    721743       
    722744        if (cwd_fd >= 0)
     
    731753        cwd_size = abs_size;
    732754       
    733         fibril_mutex_unlock(&cwd_mutex);
     755        futex_up(&cwd_futex);
    734756        return EOK;
    735757}
     
    740762                return NULL;
    741763       
    742         fibril_mutex_lock(&cwd_mutex);
     764        futex_down(&cwd_futex);
    743765       
    744766        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    745                 fibril_mutex_unlock(&cwd_mutex);
     767                futex_up(&cwd_futex);
    746768                return NULL;
    747769        }
    748770       
    749771        str_cpy(buf, size, cwd_path);
    750         fibril_mutex_unlock(&cwd_mutex);
     772        futex_up(&cwd_futex);
    751773       
    752774        return buf;
     
    756778{
    757779        struct stat stat;
    758        
    759         int rc = fstat(fildes, &stat);
    760         if (rc != 0)
    761                 return rc;
    762        
     780        int rc;
     781
     782        rc = fstat(fildes, &stat);
     783
    763784        if (!stat.device)
    764785                return -1;
     
    785806int dup2(int oldfd, int newfd)
    786807{
    787         int vfs_phone = vfs_exchange_begin();
     808        futex_down(&vfs_phone_futex);
     809        async_serialize_start();
     810        vfs_connect();
    788811       
    789812        sysarg_t ret;
    790813        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    791814       
    792         vfs_exchange_end(vfs_phone);
     815        async_serialize_end();
     816        futex_up(&vfs_phone_futex);
    793817       
    794818        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.