Ignore:
File:
1 edited

Legend:

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

    r8e80d3f 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);
    380         rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
    381             IPC_XF_RESTRICT);
    382         if (rc != EOK) {
    383                 vfs_exchange_end(vfs_phone);
    384 
     370        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
     371        if (rc != EOK) {
    385372                sysarg_t rc_orig;
    386                 async_wait_for(req, &rc_orig);
    387 
     373       
     374                async_wait_for(req, &rc_orig);
     375                async_serialize_end();
     376                futex_up(&vfs_phone_futex);
    388377                if (rc_orig == EOK)
    389378                        return (ssize_t) rc;
     
    391380                        return (ssize_t) rc_orig;
    392381        }
    393         vfs_exchange_end(vfs_phone);
    394         async_wait_for(req, &rc);
     382        async_wait_for(req, &rc);
     383        async_serialize_end();
     384        futex_up(&vfs_phone_futex);
    395385        if (rc == EOK)
    396386                return (ssize_t) IPC_GET_ARG1(answer);
     
    405395        aid_t req;
    406396
    407         int vfs_phone = vfs_exchange_begin();
     397        futex_down(&vfs_phone_futex);
     398        async_serialize_start();
     399        vfs_connect();
    408400       
    409401        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    410         rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
    411             IPC_XF_RESTRICT);
    412         if (rc != EOK) {
    413                 vfs_exchange_end(vfs_phone);
    414 
     402        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
     403        if (rc != EOK) {
    415404                sysarg_t rc_orig;
    416                 async_wait_for(req, &rc_orig);
    417 
     405       
     406                async_wait_for(req, &rc_orig);
     407                async_serialize_end();
     408                futex_up(&vfs_phone_futex);
    418409                if (rc_orig == EOK)
    419410                        return (ssize_t) rc;
     
    421412                        return (ssize_t) rc_orig;
    422413        }
    423         vfs_exchange_end(vfs_phone);
    424         async_wait_for(req, &rc);
     414        async_wait_for(req, &rc);
     415        async_serialize_end();
     416        futex_up(&vfs_phone_futex);
    425417        if (rc == EOK)
    426418                return (ssize_t) IPC_GET_ARG1(answer);
     
    431423int fsync(int fildes)
    432424{
    433         int vfs_phone = vfs_exchange_begin();
     425        futex_down(&vfs_phone_futex);
     426        async_serialize_start();
     427        vfs_connect();
    434428       
    435429        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    436430       
    437         vfs_exchange_end(vfs_phone);
     431        async_serialize_end();
     432        futex_up(&vfs_phone_futex);
    438433       
    439434        return (int) rc;
     
    442437off64_t lseek(int fildes, off64_t offset, int whence)
    443438{
    444         int vfs_phone = vfs_exchange_begin();
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
    445442       
    446443        sysarg_t newoff_lo;
     
    450447            &newoff_lo, &newoff_hi);
    451448       
    452         vfs_exchange_end(vfs_phone);
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
    453451       
    454452        if (rc != EOK)
     
    462460        sysarg_t rc;
    463461       
    464         int vfs_phone = vfs_exchange_begin();
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
    465465       
    466466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467467            LOWER32(length), UPPER32(length));
    468         vfs_exchange_end(vfs_phone);
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
    469470       
    470471        return (int) rc;
     
    476477        aid_t req;
    477478
    478         int vfs_phone = vfs_exchange_begin();
     479        futex_down(&vfs_phone_futex);
     480        async_serialize_start();
     481        vfs_connect();
    479482       
    480483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482485        if (rc != EOK) {
    483                 vfs_exchange_end(vfs_phone);
    484 
    485486                sysarg_t rc_orig;
    486                 async_wait_for(req, &rc_orig);
    487 
     487               
     488                async_wait_for(req, &rc_orig);
     489                async_serialize_end();
     490                futex_up(&vfs_phone_futex);
    488491                if (rc_orig == EOK)
    489492                        return (ssize_t) rc;
     
    491494                        return (ssize_t) rc_orig;
    492495        }
    493         vfs_exchange_end(vfs_phone);
    494         async_wait_for(req, &rc);
     496        async_wait_for(req, &rc);
     497        async_serialize_end();
     498        futex_up(&vfs_phone_futex);
    495499
    496500        return rc;
     
    508512                return ENOMEM;
    509513       
    510         int vfs_phone = vfs_exchange_begin();
     514        futex_down(&vfs_phone_futex);
     515        async_serialize_start();
     516        vfs_connect();
    511517       
    512518        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    513519        rc = async_data_write_start(vfs_phone, pa, pa_size);
    514520        if (rc != EOK) {
    515                 vfs_exchange_end(vfs_phone);
     521                async_wait_for(req, &rc_orig);
     522                async_serialize_end();
     523                futex_up(&vfs_phone_futex);
    516524                free(pa);
    517                 async_wait_for(req, &rc_orig);
    518525                if (rc_orig == EOK)
    519526                        return (int) rc;
     
    523530        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    524531        if (rc != EOK) {
    525                 vfs_exchange_end(vfs_phone);
     532                async_wait_for(req, &rc_orig);
     533                async_serialize_end();
     534                futex_up(&vfs_phone_futex);
    526535                free(pa);
    527                 async_wait_for(req, &rc_orig);
    528                 if (rc_orig == EOK)
    529                         return (int) rc;
    530                 else
    531                         return (int) rc_orig;
    532         }
    533         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);
    534544        free(pa);
    535         async_wait_for(req, &rc);
    536545        return rc;
    537546}
     
    592601                return ENOMEM;
    593602       
    594         int vfs_phone = vfs_exchange_begin();
     603        futex_down(&vfs_phone_futex);
     604        async_serialize_start();
     605        vfs_connect();
    595606       
    596607        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    597608        rc = async_data_write_start(vfs_phone, pa, pa_size);
    598609        if (rc != EOK) {
    599                 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);
    600615                free(pa);
    601 
    602                 sysarg_t rc_orig;
    603                 async_wait_for(req, &rc_orig);
    604 
    605                 if (rc_orig == EOK)
    606                         return (int) rc;
    607                 else
    608                         return (int) rc_orig;
    609         }
    610         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);
    611624        free(pa);
    612         async_wait_for(req, &rc);
    613625        return rc;
    614626}
     
    624636                return ENOMEM;
    625637
    626         int vfs_phone = vfs_exchange_begin();
     638        futex_down(&vfs_phone_futex);
     639        async_serialize_start();
     640        vfs_connect();
    627641       
    628642        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    629643        rc = async_data_write_start(vfs_phone, pa, pa_size);
    630644        if (rc != EOK) {
    631                 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);
    632650                free(pa);
    633 
    634                 sysarg_t rc_orig;
    635                 async_wait_for(req, &rc_orig);
    636 
    637                 if (rc_orig == EOK)
    638                         return (int) rc;
    639                 else
    640                         return (int) rc_orig;
    641         }
    642         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);
    643659        free(pa);
    644         async_wait_for(req, &rc);
    645660        return rc;
    646661}
     
    674689        }
    675690
    676         int vfs_phone = vfs_exchange_begin();
     691        futex_down(&vfs_phone_futex);
     692        async_serialize_start();
     693        vfs_connect();
    677694       
    678695        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    679696        rc = async_data_write_start(vfs_phone, olda, olda_size);
    680697        if (rc != EOK) {
    681                 vfs_exchange_end(vfs_phone);
     698                async_wait_for(req, &rc_orig);
     699                async_serialize_end();
     700                futex_up(&vfs_phone_futex);
    682701                free(olda);
    683702                free(newa);
    684                 async_wait_for(req, &rc_orig);
    685703                if (rc_orig == EOK)
    686704                        return (int) rc;
     
    690708        rc = async_data_write_start(vfs_phone, newa, newa_size);
    691709        if (rc != EOK) {
    692                 vfs_exchange_end(vfs_phone);
     710                async_wait_for(req, &rc_orig);
     711                async_serialize_end();
     712                futex_up(&vfs_phone_futex);
    693713                free(olda);
    694714                free(newa);
    695                 async_wait_for(req, &rc_orig);
    696                 if (rc_orig == EOK)
    697                         return (int) rc;
    698                 else
    699                         return (int) rc_orig;
    700         }
    701         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);
    702723        free(olda);
    703724        free(newa);
    704         async_wait_for(req, &rc);
    705725        return rc;
    706726}
     
    720740        }
    721741       
    722         fibril_mutex_lock(&cwd_mutex);
     742        futex_down(&cwd_futex);
    723743       
    724744        if (cwd_fd >= 0)
     
    733753        cwd_size = abs_size;
    734754       
    735         fibril_mutex_unlock(&cwd_mutex);
     755        futex_up(&cwd_futex);
    736756        return EOK;
    737757}
     
    742762                return NULL;
    743763       
    744         fibril_mutex_lock(&cwd_mutex);
     764        futex_down(&cwd_futex);
    745765       
    746766        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    747                 fibril_mutex_unlock(&cwd_mutex);
     767                futex_up(&cwd_futex);
    748768                return NULL;
    749769        }
    750770       
    751771        str_cpy(buf, size, cwd_path);
    752         fibril_mutex_unlock(&cwd_mutex);
     772        futex_up(&cwd_futex);
    753773       
    754774        return buf;
     
    758778{
    759779        struct stat stat;
    760        
    761         int rc = fstat(fildes, &stat);
    762         if (rc != 0)
    763                 return rc;
    764        
     780        int rc;
     781
     782        rc = fstat(fildes, &stat);
     783
    765784        if (!stat.device)
    766785                return -1;
     
    787806int dup2(int oldfd, int newfd)
    788807{
    789         int vfs_phone = vfs_exchange_begin();
     808        futex_down(&vfs_phone_futex);
     809        async_serialize_start();
     810        vfs_connect();
    790811       
    791812        sysarg_t ret;
    792813        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    793814       
    794         vfs_exchange_end(vfs_phone);
     815        async_serialize_end();
     816        futex_up(&vfs_phone_futex);
    795817       
    796818        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.